并行算法讲义 联系客服

发布时间 : 星期三 文章并行算法讲义更新完毕开始阅读d6ac36768e9951e79b8927da

构成,但它们每个数据块的长度/类型分别为 sendcount/sendtype 和 recvcount/recvtype。 该操作相当于将数据/进程进行一次转置。例如,假设一个二维数组按行分块存储在各进程中,则调用该函数可很容易地将它变成按列分块存储在各进程中 假设 MYRANK 为进程号,则 MPI_Alltoall 相当于:

DO I=0, NPROCS-1

CALL MPI_SEND( SENDBUF + I*SENDCOUNT*extent(SENDTYPE), + SENDCOUNT, SENDTYPE, I, ...)

ENDDO

DO I=0, NPROCS-1

CALL MPI_RECV( RECVBUF + I*RECVCOUNT*extent(RECVTYPE), + RECVCOUNT, RECVTYPE, I, ...)

ENDDO

§5.5.2 不同数据长度的全收集散发 MPI_Alltoallv C

int MPI_Alltoallv(void *sendbuf, int *sendcounts, int *sdispls, MPI_Datatype sendtype,

void *recvbuf, int *recvcounts, int *rdispls, MPI_Datatype recvtype, MPI_Comm comm)

Fortran 77

MPI_ALLTOALLV(SENDBUF, SENDCOUNTS, SDISPLS, SENDTYPE, + RECVBUF, RECVCOUNTS, RDISPLS, RECVTYPE, COMM, + IERR)

SENDBUF(*), RECVBUF(*)

INTEGER SENDCOUNTS(*), SDISPLS(*), SENDTYPE, + RECVCOUNTS(*), RDISPLS(*), RECVTYPE, COMM, IERR .

与MPI_Alltoall类似,但每个数据块的长度可以不等,并且不要求连续存放。各个参数的含义很容易从 MPI_Alltoall, MPI_Scatterv 和 MPI_Gatherv 中参数的含义得出。 假设 MYRANK 为进程号, NPROCS 为进程数,则 MPI_Alltoallv相当于:

DO I=0, NPROCS-1

CALL MPI_SEND( SENDBUF + SDISPLS(I)*extent(SENDTYPE), + SENDCOUNTS(I), SENDTYPE, I, ...)

ENDDO

DO I=0, NPROCS-1

CALL MPI_RECV( RECVBUF + RDISPLS(I)*extent(RECVTYPE), + RECVCOUNTS(I), RECVTYPE, I, ...)

ENDDO

§5.6 归约

假设一个通信器中有p个进程,每个进程均有一个n个元素的数组。设{ak,i,k?1,2,...,n}为笫i个进程中的数组,i?0,1,...,p?1。又设?为关于这些数组元素的二目运算,则相应的归约操作(redution) 结果定义为: 数组{resk,k?1,...,n},其中:

resk?ak,0?ak,1?...?ak,p?1

MPI 的归约函数要求运算?满足结合律,但可以不满足交换律。运算可以是 MPI预定义的,也可以是用户自行定义的。 §5.6.1 归约函数 MPI_Reduce C

int MPI_Reduce(void *sendbuf, void *recvbuf, int count, MPI_Datatype datatype, MPI_Op op, int root, MPI_Comm comm)

Fortran 77

MPI_REDUCE(SENDBUF, RECVBUF, COUNT, DATATYPE, OP, ROOT, + COMM, IERR)

SENDBUF(*), RECVBUF(*)

INTEGER COUNT, DATATYPE, OP, ROOT, COMM, IERR

设进程数为NPROCS ,则MPI_Reduce相当于在根进程(root)中计算:

DO K=1, COUNT

RECVBUF(K) = SENDBUF(K) of process 0 DO I=1, NPROCS-1

RECVBUF(K) = RECVBUF(K) op ( SENDBUF(K) of process I ) ENDDO ENDDO

函数中除op参数外,其它参数的含义是显而易见的。op指定归约使用的运算, op在 C 中的类型为 MPI_Op,而在 Fortran 77 中则是一个句柄。 op可以是 MPI预定义的,也可以是用户定义的。我们将在 §5.6.5 中介绍如何自定义归约中的运算。