Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/performance/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 进程使用MPI\U分散将一个数组索引发送到所有其他进程时输出错误_C_Performance_Parallel Processing_Mpi_Hpc - Fatal编程技术网

C 进程使用MPI\U分散将一个数组索引发送到所有其他进程时输出错误

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

我只是想了解一下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) * 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