18.2.31. shmem_complexf_sum_to_all
shmem_comp4_sum_to_all(3), shmem_comp8_sum_to_all(3), shmem_complexd_sum_to_all(3), shmem_complexf_sum_to_all(3), shmem_double_sum_to_all(3), shmem_float_sum_to_all(3), shmem_int_sum_to_all(3), shmem_int4_sum_to_all(3), shmem_int8_sum_to_all(3), shmem_long_sum_to_all(3), shmem_longdouble_sum_to_all(3), shmem_longlong_sum_to_all(3), shmem_real4_sum_to_all(3), shmem_real8_sum_to_all(3), shmem_real16_sum_to_all(3), shmem_short_sum_to_all(3) - 在 一组处理单元(PEs)上执行求和归约操作
18.2.31.1. 概述
C或C++:
#include <mpp/shmem.h>
void shmem_complexd_sum_to_all(double complex *target,
const double complex *source, int nreduce, int PE_start,
int logPE_stride, int PE_size, double complex *pWrk,
long *pSync)
void shmem_complexf_sum_to_all(float complex *target,
const float complex *source, int nreduce, int PE_start,
int logPE_stride, int PE_size, float complex *pWrk,
long *pSync)
void shmem_double_sum_to_all(double *target,
const double *source, int nreduce, int PE_start, int logPE_stride,
int PE_size, double *pWrk, long *pSync)
void shmem_float_sum_to_all(float *target, const float *source,
int nreduce, int PE_start, int logPE_stride, int PE_size,
float *pWrk, long *pSync)
void shmem_int_sum_to_all(int *target, const int *source,
int nreduce, int PE_start, int logPE_stride, int PE_size,
int *pWrk, long *pSync)
void shmem_long_sum_to_all(long *target, const long *source,
int nreduce, int PE_start, int logPE_stride, int PE_size,
long *pWrk, long *pSync)
void shmem_longdouble_sum_to_all(long double *target,
const long double *source, int nreduce, int PE_start, int
logPE_stride, int PE_size, long double *pWrk, long *pSync)
void shmem_longlong_sum_to_all(long long *target,
const long long *source, int nreduce, int PE_start,
int logPE_stride, int PE_size, long long *pWrk,
long *pSync)
void shmem_short_sum_to_all(short *target, const short *source,
int nreduce, int PE_start, int logPE_stride, int PE_size,
short *pWrk, long *pSync)
Fortran语言:
INCLUDE "mpp/shmem.fh"
INTEGER pSync(SHMEM_REDUCE_SYNC_SIZE)
INTEGER nreduce, PE_start, logPE_stride, PE_size
CALL SHMEM_COMP4_SUM_TO_ALL(target, source, nreduce,
& PE_start, logPE_stride, PE_size, pWrk, pSync)
CALL SHMEM_COMP8_SUM_TO_ALL(target, source, nreduce,
& PE_start, logPE_stride, PE_size, pWrk, pSync)
CALL SHMEM_INT4_SUM_TO_ALL(target, source, nreduce,
& PE_start, logPE_stride, PE_size, pWrk, pSync)
CALL SHMEM_INT8_SUM_TO_ALL(target, source, nreduce,
& PE_start, logPE_stride, PE_size, pWrk, pSync)
CALL SHMEM_REAL4_SUM_TO_ALL(target, source, nreduce,
& PE_start, logPE_stride, PE_size, pWrk, pSync)
CALL SHMEM_REAL8_SUM_TO_ALL(target, source, nreduce,
& PE_start, logPE_stride, PE_size, pWrk, pSync)
CALL SHMEM_REAL16_SUM_TO_ALL(target, source, nreduce,
& PE_start, logPE_stride, PE_size, pWrk, pSync)
18.2.31.2. 描述
共享内存(SHMEM)归约例程在多个虚拟PE上对对称数组执行一个或多个归约操作。归约操作会对一组值执行关联二元运算。如需查看其他SHMEM归约例程列表,请参阅intro_shmem(3)。
与所有SHMEM集合例程一样,这些例程都假定只有活动集中的PE会调用该例程。如果不在活动集中的PE调用了SHMEM集合例程,将导致未定义行为。
参数nreduce决定要执行的不同归约操作的数量。活跃集中所有PE上的源数组为每个归约提供一个元素。归约的结果会被放入活跃集中所有PE上的目标数组。活跃集由PE_start、logPE_stride和PE_size这三个参数定义。
源数组和目标数组可以是同一个数组,但它们不能是重叠的数组。
参数如下:
- target
远程可访问的整型数据对象,将在远程PE上进行更新。如果使用C/C++,目标类型应与SYNOPSIS部分隐含的类型匹配。如果使用Fortran编译器,则必须是整型,元素大小为4字节(对应SHMEM_INT4_ADD)或8字节(对应SHMEM_INT8_ADD)。
- value
需要原子性添加到目标的值。如果使用C/C++语言,该值的类型应与概述部分隐含的类型匹配。如果使用Fortran语言,则必须是整数类型且元素大小与目标一致。
- pe
一个整数,表示目标将被更新的PE编号。如果使用Fortran,它必须是一个默认的整数值。
- target
- 一个长度为nreduce的对称数组,用于接收归约操作的结果。目标变量的数据类型会根据所调用的归约例程版本和使用的编程语言而变化。从C/C++调用时,请参考SYNOPSIS部分获取数据类型信息。从Fortran调用时,目标数据类型如下:
shmem_comp4_sum_to_all: **复数类型(KIND=4)。
- shmem_comp8_sum_to_all:** Complex. If you are using Fortran, it must be
默认的复数值。
shmem_int4_sum_to_all: **整数类型(KIND=4)。
- shmem_int8_sum_to_all:** Integer. If you are using Fortran, it must be a
默认整数值。
shmem_real4_sum_to_all: ** 实数(KIND=4).
- shmem_real8_sum_to_all:** Real. If you are using Fortran, it must be a
默认实数值。
- shmem_real16_sum_to_all:** Real. If you are using Fortran, it must be a
默认实数值。
- source
一个长度为nreduce元素的对称数组,其中包含每个独立归约操作的一个元素。源参数必须与目标参数具有相同的数据类型。
- nreduce
目标数组和源数组中的元素数量。nreduce必须是整数类型。如果使用Fortran,它必须是一个默认的整数值。
- PE_start
活动PE集合中的最低虚拟PE编号。PE_start必须为整数类型。如果使用Fortran,则必须为默认整数值。
- logPE_stride
活动集中连续虚拟PE编号之间跨度的对数(以2为底)。logPE_stride必须是整数类型。如果使用Fortran,则必须为默认整数值。
- PE_size
活动集中的PE数量。PE_size必须为整数类型。如果使用Fortran,它必须是一个默认的整数值。
- pWrk
一个对称工作数组。参数pWrk必须与目标具有相同的数据类型。在C/C++中,该数组包含max(nreduce/2 + 1, _SHMEM_REDUCE_MIN_WRKDATA_SIZE)个元素。在Fortran中,该数组包含max(nreduce/2 + 1, SHMEM_REDUCE_MIN_WRKDATA_SIZE)个元素。
- pSync
一个对称工作数组。在C/C++中,pSync是long类型,大小为_SHMEM_REDUCE_SYNC_SIZE。在Fortran中,pSync是integer类型,大小为SHMEM_REDUCE_SYNC_SIZE。它必须是一个默认整数值。在活动集中的任何PE进入归约例程之前,必须用值_SHMEM_SYNC_VALUE(在C/C++中)或SHMEM_SYNC_VALUE(在Fortran中)初始化该数组的每个元素。
参数nreduce、PE_start、logPE_stride和PE_size的值必须在活动集中的所有PE上保持一致。相同的目标数组和源数组,以及相同的工作数组pWrk和pSync,必须传递给活动集中的所有PE。
在任何PE调用归约例程之前,您必须确保满足以下条件(通常需要通过屏障或其他同步方法来确保这一点):活动集中所有PE上的pWrk和pSync数组没有仍在被之前的SHMEM集体例程调用所占用。活动集中所有PE上的目标数组已准备好接收归约结果。
在从归约例程返回后,本地PE(处理单元)将满足以下条件:目标数组已更新。pSync数组中的值已恢复为原始值。
18.2.31.3. 注意事项
术语"collective"、"symmetric"和"cache aligned"的定义请参阅intro_shmem(3)。
所有SHMEM归约例程在返回前都会重置pSync中的值,因此特定的pSync缓冲区只需在首次使用时初始化即可。
必须确保在活动集中的任何PE参与处理SHMEM归约例程时,pSync数组不会被任何PE更新。需特别注意以下情况:如果pSync数组在运行时初始化,需要某种同步机制来确保工作集中的所有PE在进入使用pSync同步数组调用的SHMEM例程之前,都已初始化pSync。只有当活动集中没有任何PE仍在处理使用相同pSync或pWrk数组的先前归约例程调用时,才能在后续归约例程调用中重用pSync或pWrk数组。通常,这只能通过某种同步机制来保证。但在使用相同活动集调用归约例程的特殊情况下,可以分配两个pSync和pWrk数组,并在连续调用中交替使用它们。
18.2.31.4. 示例
示例1: 这个Fortran示例静态初始化了pSync数组,并计算所有偶数PE上实数变量FOO的总和。
INCLUDE "mpp/shmem.fh"
INTEGER PSYNC(SHMEM_REDUCE_SYNC_SIZE)
DATA PSYNC /SHMEM_REDUCE_SYNC_SIZE*SHMEM_SYNC_VALUE/
PARAMETER (NR=1)
REAL FOO, FOOSUM, PWRK(MAX(NR/2+1,SHMEM_REDUCE_MIN_WRKDATA_SIZE))
COMMON /COM/ FOO, FOOSUM, PWRK
INTRINSIC MY_PE
IF ( MOD(MY_PE(),2) .EQ. 0) THEN
CALL SHMEM_INT4_SUM_TO_ALL(FOOSUM, FOO, NR, 0, 1, N$PES/2,
& PWRK, PSYNC)
PRINT *, 'Result on PE ', MY_PE(), ' is ', FOOSUM
ENDIF
示例2: 考虑以下C/C++调用:
shmem_int_sum_to_all( target, source, 3, 0, 0, 8, pwrk, psync );
前面的调用方式效率更高,但在语义上等同于以下组合调用:
shmem_int_sum_to_all(&(target[0]), &(source[0]), 1, 0, 0, 8,
pwrk1, psync1);
shmem_int_sum_to_all(&(target[1]), &(source[1]), 1, 0, 0, 8,
pwrk2, psync2);
shmem_int_sum_to_all(&(target[2]), &(source[2]), 1, 0, 0, 8,
pwrk1, psync1);
Note that two sets of pWrk and pSync arrays are used alternately because no
synchronization is done between calls.
另请参阅
intro_shmem(3)