MPI接收多个部分
MPI receiving in multiple parts
通常,当我想向下一个处理器发送缓冲区并从上一个处理器接收另一个缓冲区时,我会使用以下方法:
MPI_Irecv(rcv_buff,rcv_size,
MPI_DOUBLE,rcv_p,0,world,
&request);
MPI_Send(snd_buff,snd_size,
MPI_DOUBLE,snd_p,0,world);
MPI_Wait(&request,&status);
假设我想把rcv_buff的第一个rcv_size0元素放在array0中,其余的(rcv_size 1元素)放在array1中,其中:
rcv_size1=rcv_size-rcv_size0;
通常,我所做的是首先在这里创建一个类似rcv_buff的伪数组,然后开始将值复制到array0和array1。我的问题是,MPI中有没有任何方法可以接收两个或多个序列中发送的字节?例如,直接接收array0中的第一个size0元素和array1中的其余元素?
您可以通过创建特定于这对缓冲区的类型来实现这一点-接收到两个缓冲区中:
#include <stdio.h>
#include <mpi.h>
#include <stdlib.h>
int recv_split(const int total, const int src, const int tag,
double *buffA, const int sizeA, double *buffB) {
if (total <= 0) return -1;
if (sizeA > total) return -1;
if (buffA == NULL) return -2;
if (buffB == NULL) return -2;
const int sizeB = total - sizeA;
int blocksizes[2] = {sizeA, sizeB};
MPI_Datatype types[2] = {MPI_DOUBLE, MPI_DOUBLE};
MPI_Aint displacements[2], addrA, addrB;
MPI_Datatype splitbuffer;
MPI_Status status;
displacements[0] = 0;
MPI_Get_address(buffA, &addrA);
MPI_Get_address(buffB, &addrB);
displacements[1] = addrB - addrA;
MPI_Type_create_struct(2, blocksizes, displacements, types, &splitbuffer);
MPI_Type_commit(&splitbuffer);
MPI_Recv(buffA, 1, splitbuffer, src, tag, MPI_COMM_WORLD, &status);
MPI_Type_free(&splitbuffer);
return 0;
}
int main(int argc, char **argv) {
int rank, size;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
const int sendSize = 15;
const int tag = 1;
if (rank == 0 && size >= 2) {
double sendbuff[sendSize];
for (int i=0; i<sendSize; i++)
sendbuff[i] = 1.*i;
MPI_Send(sendbuff, sendSize, MPI_DOUBLE, 1, tag, MPI_COMM_WORLD);
}
if (rank == 1) {
const int buffLen = 12;
const int recvIntoA = 10;
double buffA[buffLen];
double buffB[buffLen];
for (int i=0; i<buffLen; i++) {
buffA[i] = buffB[i] = -1.;
}
recv_split(sendSize, 0, tag, buffA, recvIntoA, buffB);
printf("---Buffer A--n");
for (int i=0; i<buffLen; i++)
printf("%5.1lf ", buffA[i]);
printf("n---Buffer B--n");
for (int i=0; i<buffLen; i++)
printf("%5.1lf ", buffB[i]);
printf("n");
}
MPI_Finalize();
return 0;
}
编译和运行提供
$ mpicc -o recvsplit recvsplit.c -std=c99
$ mpirun -np 2 ./recvsplit
---Buffer A--
0.0 1.0 2.0 3.0 4.0 5.0 6.0 7.0 8.0 9.0 -1.0 -1.0
---Buffer B--
10.0 11.0 12.0 13.0 14.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0 -1.0
请注意,这种类型只适用于这对缓冲区;不同的对通常具有不同的相对位移。当然,您也可以使用自己的代码或MPI_Unpack
,始终接收到一个大型暂存缓冲区中,并手动解压缩到不同的缓冲区中。
我所知道的MPI中没有任何东西可以直接让你做到这一点,尽管你可能可以使用一些讨厌的指针魔法来让它发挥作用。一般来说,如果你想这样做,那么两次发送会更干净。
还有一件事不是你问题的直接答案,但你可能不知道,那就是你上面的三行命令可以使用MPI_SENDRECV组合成一个命令。试试这条线路:
MPI_Sendrecv(snd_buff, snd_size, MPI_DOUBLE, snd_p, 0,
rcv_buff, rcv_size, MPI_DOUBLE, rcv_p, 0,
world, &status);
相关文章:
- MPI突然停止了对多个核心的操作
- 使用 make 编译 MPI,几个命名空间错误,例如"错误:未知类型名称'使用'?
- C MPI,使用多个节点,首先在节点级别上降低,然后减小到头节点
- 时间效率的设计模型,用于从所有MPI流程发送和接收:MPI全部2个通信
- 我有 12 个 CPU,1 个插槽,每个插槽 6 个内核,每个内核 2 个线程 - 这些信息如何对应于 MPI 和 Op
- MPI - 当数组初始化值必须为常量时,如何为工作线程创建部分数组
- boost::mpi在具有相同标记的多个isend/irecv传输上抛出mpi_ERR_TRUNCATE
- 如何使用某些MPI命令(或组合命令)之间在两个处理器之间交换2D数组中存储的数据
- 具有多个参数的部分类模板专用化
- MPI接收多个部分
- 大型项目的MPI编码实践多个MPI_Finalize();或者只是一个
- MPI中向多个进程发送Recv的最佳方式
- 如何使用MPI在多个独立启动的程序之间传输数据
- 使用Code::Blocks运行多个进程的MPI程序
- MPI代码不工作与2个节点,但与1
- 打开MPI:如何在每个主机上运行1个进程
- 在多个主机之间分配进程时,打开MPI程序不工作
- MPI帮助查找n个数字的最大值
- 布拉斯特区+多个精度+ MPI
- MPI多个发送和接收在循环中