2

我似乎无法弄清楚如何在节点之间发送数据,而不是将其发送到根节点,然后将其发送到所有其他节点。

如果我的N每个节点都有一个这样创建的数组,那么SIZE节点的总数在哪里,目前假设它是一个预处理器常量(如果可能,避免malloc像瘟疫一样)。另外,不言而喻的rank是当前节点的排名。

int dummy [SIZE][5];
int i, n;

for (n = 0; n < SIZE; n++){
  for (i = 0; i <5; i++){
    if ( n == rank ){
      dummy [ n ][ i ] = 123;

这为每个节点提供了一个几乎为空的维度数组SIZE * 5,其中只有一行数字123。现在我想获取所有这些单独的数组并“合并”它们。我唯一能想到的是以下内容,但我确信这会导致死锁,即使我确实费心检查我的源节点是否不等于目标节点:

for ( i = 0; i < SIZE; i++ ){
  for ( j = 0; j < SIZE; j++ ){
     MPI_Send ( &dummy [ i ], 5, MPI_INT, j, 123, MPI_COMM_WORLD );
  }
}

for ( i = 0; i < SIZE; i++ ){
  for ( j = 0; j < SIZE; j++ ){
     MPI_Recv ( &dummy [ j ], 5, MPI_INT, i, 123, MPI_COMM_WORLD );
  }
}

有人可以为我提供一些关于如何解决这个问题的伪代码。干杯

4

1 回答 1

4

这是一个“收集”操作,并且有一个 MPI 集合,MPI_Gather()如果您想将所有数据收集到一个处理器上,它会实现它,并将数据MPI_Allgather()收集到所有处理器。

在这种情况下,我们想做一个“就地”聚集——聚集到我们发送的同一个数组中。所以这将起作用:

#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>

#define SIZE 5

int main(int argc, char **argv) {

    int size, rank;
    MPI_Init(&argc, &argv);
    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    if (size != SIZE) {
        if (rank == 0) {
            fprintf(stderr,"Must run with %d ranks\n", SIZE);
        }
        MPI_Finalize();
        exit(1);
    }

    int dummy [SIZE][5];

    for (int i = 0; i <5; i++){
          dummy [ rank ][ i ] = 100 * rank;
    }

    MPI_Allgather(MPI_IN_PLACE, 5, MPI_INT,
                  dummy, 5, MPI_INT,
                  MPI_COMM_WORLD);

    if (rank == SIZE-1) {
        printf("Rank %d has dummy:\n", rank);
        for (int i=0; i<size; i++) {
            for (int j=0; j<5; j++) {
                printf("%3d ", dummy[i][j]);
            }
            printf("\n");
        }
    }

    MPI_Finalize();
    return 0;
}

运行给出:

$ mpicc -o allgather allgather.c -std=c99
$ mpirun -np 5 ./allgather
Rank 4 has dummy:
  0   0   0   0   0 
100 100 100 100 100 
200 200 200 200 200 
300 300 300 300 300 
400 400 400 400 400 
于 2012-12-19T03:01:03.170 回答