C 进程使用MPI\U分散将一个数组索引发送到所有其他进程时输出错误
我只是想了解一下MPI,似乎不明白为什么下面的程序输出与我期望的不同C 进程使用MPI\U分散将一个数组索引发送到所有其他进程时输出错误,c,performance,parallel-processing,mpi,hpc,C,Performance,Parallel Processing,Mpi,Hpc,我只是想了解一下MPI,似乎不明白为什么下面的程序输出与我期望的不同 int rank, size; MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); int *sendbuf, *recvbuf; sendbuf = (int *) malloc(sizeof(int) * size); recvbuf = (int *) malloc(sizeof(int) * si
int rank, size;
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &size);
int *sendbuf, *recvbuf;
sendbuf = (int *) malloc(sizeof(int) * size);
recvbuf = (int *) malloc(sizeof(int) * size);
for(int i = 0; i < size; i++) {
sendbuf[i] = rank;
}
for(int i = 0; i < size; i++) {
printf("sendbuf[%d] = %d, rank: %d\n", i, sendbuf[i], rank);
}
MPI_Scatter(sendbuf, 1, MPI_INT,
recvbuf, 1, MPI_INT, rank, MPI_COMM_WORLD);
for(int i = 0; i < size; i++) {
printf("recvbuf[%d] = %d, rank: %d\n", i, recvbuf[i], rank);
}
第二个进程(秩1)有一个大小为MPI\u Comm\u size
的数组,数组中填充了1。
预期产出应为:
recvbuf[0] = 0, rank: 0
recvbuf[1] = 1, rank: 0
recvbuf[0] = 0, rank: 1
revcbuf[1] = 1, rank: 1
但是我得到了以下输出(对于两个进程):
任何指出我的错误的帮助都将不胜感激
我只是想了解一下MPI,但似乎不能
理解,为什么以下程序输出与我的不同
期待
问题在于如何使用来实现您的目标:
将数据从一个进程发送到通信器中的所有其他进程
简介
int MPI_分散(const void*sendbuf、int sendcount、MPI_数据类型
sendtype,void*recvbuf,int recvcount,MPI_数据类型recvtype,int root,
MPI_通信)输入参数
sendbuf发送缓冲区的地址(选项,仅在根上有效)sendcount发送到每个进程的元素数(整数,仅在根上有效) sendtype发送缓冲区元素的数据类型(仅在根位置有效)(句柄)
recvcount接收缓冲区中的元素数(整数)
recvtype接收缓冲区元素(句柄)的数据类型
根发送进程的排名(整数)
通讯器通讯器(手柄) 每个进程都应该使用相同的根调用
MPI\u Scatter
,而不是使用不同的根(即进程的秩),正如您所做的那样:
MPI_Scatter(sendbuf, 1, MPI_INT, recvbuf, 1, MPI_INT, rank, MPI_COMM_WORLD);
^^^^
因此,您误用了MPI\u Scatter
,该例程的目的是“将数据从一个进程发送到通信器中的所有其他进程”。下图(取自)最能说明这一点:
只有一个根进程,它将数据分散到不同的进程。例如,当一个进程有一个数据块(例如,一个数组)并且代码对该数据执行某些操作时,就使用这个例程。您可以通过在进程之间拆分数据来并行化代码,其中每个进程在其分配的数据块上并行执行上述操作。之后,您可以调用将所有进程中的数据收集回数据来自的原始进程
然后每个进程将其数组中的一个索引发送给所有其他进程
过程
为此,您可以改为使用,它“从所有任务收集数据,并将组合数据分发到所有任务”。下图(取自)最能说明这一点:
如您所见,每个进程都将收集所有进程(包括自身)发送的数据
一个运行示例:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
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);
int *sendbuf = malloc(sizeof(int) * size);
int *recvbuf = malloc(sizeof(int) * size);
for(int i = 0; i < size; i++)
sendbuf[i] = rank;
MPI_Allgather(sendbuf, 1, MPI_INT, recvbuf, 1, MPI_INT, MPI_COMM_WORLD);
for(int i = 0; i < size; i++)
printf("recvbuf[%d] = %d, rank: %d\n", i, recvbuf[i], rank);
MPI_Finalize();
return 0;
}
对于您的特定情况(具有相同的输入大小),也将起作用,为了了解MPI\u Allgather
与MPI\u Alltoall
之间的差异,我建议您检查此项
MPI_Scatter(sendbuf, 1, MPI_INT, recvbuf, 1, MPI_INT, rank, MPI_COMM_WORLD);
^^^^
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
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);
int *sendbuf = malloc(sizeof(int) * size);
int *recvbuf = malloc(sizeof(int) * size);
for(int i = 0; i < size; i++)
sendbuf[i] = rank;
MPI_Allgather(sendbuf, 1, MPI_INT, recvbuf, 1, MPI_INT, MPI_COMM_WORLD);
for(int i = 0; i < size; i++)
printf("recvbuf[%d] = %d, rank: %d\n", i, recvbuf[i], rank);
MPI_Finalize();
return 0;
}
recvbuf[0] = 0, rank: 0
recvbuf[1] = 1, rank: 0
recvbuf[0] = 0, rank: 1
recvbuf[1] = 1, rank: 1