【问题标题】:MPI Send and Recv Hangs with Buffer Size Larger Than 64kbMPI 发送和接收挂起,缓冲区大小大于 64kb
【发布时间】:2016-07-23 03:57:38
【问题描述】:

我正在尝试将数据从进程 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 process\n");
    exit(1);
  }

  int n = 8200;
  double *d = malloc(sizeof(double)*n);
  double *c = malloc(sizeof(double)*n);
  printf("malloc results %p %p\n", d, c);

  if(world_rank == 0){
    printf("sending\n");
    MPI_Send(c, n, MPI_DOUBLE, 1, 0, MPI_COMM_WORLD);
    printf("sent\n");
  }
  if(world_rank == 1){
    printf("recv\n");
    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:%d\n", 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

我发现这个question 和这个question 是相似的,但我相信问题在于创建死锁。我不希望在这里出现类似的问题,因为每个进程只执行一次发送或接收。

编辑:添加状态检查。

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

【问题讨论】:

  • 代码看起来不错,实际上在我的 OpenMPI 安装中运行良好。请提供有关您的安装的更多信息。您是否能够通过该安装运行任何足够复杂的 MPI 代码?还请提供相关信息。输出以及调试挂起进程的尝试会有所帮助。
  • 我同意@Zulan,但我会要求 Ruvu 检查status
  • 另外:检查结果malloc的值!
  • @Zulan 我在编辑中添加了状态检查和程序输出。我目前的项目是用于矩阵乘法的 SUMMA 算法的实现,在我需要发送大型子矩阵之前它可以正常工作。然后我无法完成接听电话。我将尝试收集有关我的安装的更多信息。
  • 我使用的是 OpenMPI 1.10.2-1 x86_64,特别是 archlinux.org/packages/extra/x86_64/openmpi

标签: c mpi openmpi


【解决方案1】:

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

$ 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 建议检查我的安装。

【讨论】:

  • 不客气,Ruvu!幸好你也努力解决了这个问题,+2。
  • 我强烈建议您查看Environment modules。它允许您保留同一软件的多个版本和安装。稍后,您可以决定要使用哪个版本,而不必担心您是否正确设置了 PATH。
【解决方案2】:

代码很好!我刚刚检查了版本 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 头文件和库编译的,但使用 Intel 的 mpirun 运行。当我确保使用 OpenMPI 中的 mpirun 可执行文件运行时,一切都按预期工作。

*checking that `malloc` succeeded in C

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-04-21
    • 2015-06-28
    • 2015-12-22
    • 1970-01-01
    • 2011-01-02
    相关资源
    最近更新 更多