c-缓冲区大小大于64kb的MPI发送和接收挂起



我正在尝试将数据从进程0发送到进程1。当缓冲区大小小于64kb时,此程序会成功,但如果缓冲区变得更大,则会挂起。下面的代码应该会重现这个问题(应该挂起),但如果n被修改为小于8000,则应该会成功。

int main(int argc, char *argv[]){
  int world_size, world_rank,
      count;
  MPI_Status status;

  MPI_Init(NULL, NULL);
  MPI_Comm_size(MPI_COMM_WORLD, &world_size);
  MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
  if(world_size < 2){
    printf("Please add another processn");
    exit(1);
  }
  int n = 8200;
  double *d = malloc(sizeof(double)*n);
  double *c = malloc(sizeof(double)*n);
  printf("malloc results %p %pn", d, c);
  if(world_rank == 0){
    printf("sendingn");
    MPI_Send(c, n, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD);
    printf("sentn");
  }
  if(world_rank == 1){
    printf("recvn");
    MPI_Recv(d, n, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &status);
    MPI_Get_count(&status, MPI_DOUBLE, &count);
    printf("recved, count:%d source:%d tag:%d error:%dn", count, status.MPI_SOURCE, status.MPI_TAG, status.MPI_ERROR);
  }
  MPI_Finalize();
}
Output n = 8200;
malloc results 0x1cb05f0 0x1cc0640
recv
malloc results 0x117d5f0 0x118d640
sending
Output n = 8000;
malloc results 0x183c5f0 0x184c000
recv
malloc results 0x1ea75f0 0x1eb7000
sending
sent
recved, count:8000 source:0 tag:0 error:0

我发现这个问题和这个问题是相似的,但我认为问题在于制造僵局。我不希望出现类似的问题,因为每个进程只执行一次发送或接收。

编辑:添加了状态检查。

第2版:问题似乎是我安装了OpenMPI,但在安装MKL时也安装了来自英特尔的MPI实现。我的代码是用OpenMPI头和库编译的,但使用英特尔的mpirun运行。当我确保使用来自OpenMPI的mpirun可执行文件运行时,一切都如预期的那样工作。

问题在于同时安装了英特尔的MPI和OpenMPI。我看到/usr/include/mpi.h由OpenMPI所有,但mpicc和mpirun来自英特尔的实现:

$ which mpicc
/opt/intel/composerxe/linux/mpi/intel64/bin/mpicc
$ which mpirun
/opt/intel/composerxe/linux/mpi/intel64/bin/mpirun

我通过运行解决了这个问题

/usr/bin/mpicc

/usr/bin/mpirun

以确保我使用了OpenMPI。

感谢@Zulan和@gsamaras建议检查我的安装。

代码很好!我刚刚检查了3.1.3版本(mpiexec --version):

linux16:/home/users/grad1459>mpicc -std=c99 -O1 -o px px.c -lm
linux16:/home/users/grad1459>mpiexec -n 2 ./px
malloc results 0x92572e8 0x9267330
sending
sent
malloc results 0x9dc92e8 0x9dd9330
recv
recved, count:8200 source:0 tag:0 error:1839744

因此,安装时会出现问题。运行以下故障排除选项:

  1. 检查malloc的结果*
  2. 检查status

我敢打赌malloc()的返回值是NULL,因为您提到如果您请求更多内存,它会失败。可能是系统拒绝提供内存。


我在一定程度上是正确的,问题来自安装,但正如OP所说:

问题似乎是我安装了OpenMPI,但在安装MKL时也安装了来自英特尔的MPI实现。我的代码是用OpenMPI头和库编译的,但使用英特尔的mpirun运行。当我确保使用来自OpenMPI的mpirun可执行文件运行时,一切都如预期的那样工作。

*检查"malloc"在C中是否成功

最新更新