在消息传递接口中使用共享数组

时间:2016-05-12 20:46:51

标签: mpi

我想在MPI程序中使用共享数组,这样在一个进程完成其工作后,它会将其排名放入该数组并通过将其发送给其他人而无需等待来“更新”它。我尝试将MPI_Bcast作为“root”参数运行进程的等级(而不是0),但是当我从每个进程显示数组时,它只显示本地发生的更改(发送的其他等级不在数组中)

int array[10];
array[rank] = rank;
MPI_Bcast(array,10,MPI_INT,rank,MPI_COMM_WORLD);
printf("%d, %d - ",array[0],array[1]); //displays: 0, 26872 - 32678, 1

感谢您的帮助。

1 个答案:

答案 0 :(得分:2)

在MPI程序的主体中键入int array[10];不会生成共享阵列。每个进程都处理自己的数组版本。 MPI_Bcast()被设计为给定进程root将其数组版本广播到所有其他进程的方式。因此,所有其他进程上的数组的初始版本将被删除。

MPI_Bcast()是一个集体操作:传播者的每个进程都必须使用相同的MPI_Bcast()来调用root。计数和类型可以不同,但​​根发送的数据量必须等于所有进程接收的数量。

解决问题的两个选项:

  • 您正在寻找的功能可能是MPI_Allgather()。请参阅these schemesMPI_Allgather()可用于在本地进程修改后同步全局数组。全局数组不是“共享”的,因为每个进程在内存中使用不同的空间,但在调用MPI_Allgather()后,不同进程的值将相似。
  • 您正在寻找一个真正的共享数组。可以通过调用MPI_Win_allocate_shared()来分配这样的数组。请参阅第407页的version 3.1 of the MPI standard,第11.2.3节“分配共享内存的窗口”。特别是,如果使用群集的多个节点运行程序,则必须注意以下警告:

      

    用户有责任确保通信器comm代表一组进程,这些进程可以创建可由组中所有进程访问的共享内存段。

    您可以找到MPI_Win_allocate_shared() there

  • 的示例

在下面的示例中,我将假设您对第一个选项感兴趣。它由mpicc main.c -o main编译并由mpirun -np 42 main运行。

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

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

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


    int* array=malloc(size*sizeof(int));
    if(array==NULL){fprintf(stderr,"malloc failed\n");exit(1);}

    //modifying the local portion of the array
    array[rank]=rank;

    //gather content from each process and broadcast it to all processes
    MPI_Allgather(&array[rank],1,MPI_INT,array,1,MPI_INT,MPI_COMM_WORLD);

    //each process has its own copy of the array, but the values are the same.
    int i,j;
    for(i=0;i<size;i++){
        if(i==rank){
            printf("rank %d got ",rank);
            for(j=0;j<size;j++){
                printf("%d ",array[j]);
            }
            printf("\n");
        }
        MPI_Barrier(MPI_COMM_WORLD);
    }

    free(array);
    MPI_Finalize();
    return 0;
}