缓冲区大小大于 64kb 的 MPI 发送和接收挂起
MPI Send and Recv Hangs with Buffer Size Larger Than 64kb
我正在尝试将数据从进程 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 and this question 很相似,但我认为问题在于创建死锁。我不希望这里出现类似的问题,因为每个进程只执行一次发送或接收。
编辑:添加了状态检查。
EDIT2:看来问题是我安装了 OpenMPI,但在安装 MKL 时还安装了 Intel 的 MPI 实现。我的代码是使用 OpenMPI 头文件和库编译的,但是 运行 使用英特尔的 mpi运行。当我确保我 运行 使用来自 OpenMPI 的 mpi运行 可执行文件时,所有工作都按预期进行。
代码没问题!我刚刚检查了版本 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
因此,问题出在您的安装上。 运行 通过以下故障排除选项:
- 查看malloc的结果*
- 勾选
status
我敢打赌 malloc()
的 return 值是 NULL
,因为你提到如果你请求更多内存它会失败。可能是系统拒绝给那个内存
我部分正确,安装出现问题,但正如 OP 所说:
It seems the issue was that I have OpenMPI installed but also installed an implementation of MPI from Intel when I installed MKL. My code was being compiled with the OpenMPI header and libraries, but run with Intel's mpirun. All works as expected when I ensure I run with the mpirun executable from OpenMPI.
*checking that `malloc` succeeded in C
问题在于同时安装了 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 建议检查我的安装。
我正在尝试将数据从进程 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 and this question 很相似,但我认为问题在于创建死锁。我不希望这里出现类似的问题,因为每个进程只执行一次发送或接收。
编辑:添加了状态检查。
EDIT2:看来问题是我安装了 OpenMPI,但在安装 MKL 时还安装了 Intel 的 MPI 实现。我的代码是使用 OpenMPI 头文件和库编译的,但是 运行 使用英特尔的 mpi运行。当我确保我 运行 使用来自 OpenMPI 的 mpi运行 可执行文件时,所有工作都按预期进行。
代码没问题!我刚刚检查了版本 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
因此,问题出在您的安装上。 运行 通过以下故障排除选项:
- 查看malloc的结果*
- 勾选
status
我敢打赌 malloc()
的 return 值是 NULL
,因为你提到如果你请求更多内存它会失败。可能是系统拒绝给那个内存
我部分正确,安装出现问题,但正如 OP 所说:
It seems the issue was that I have OpenMPI installed but also installed an implementation of MPI from Intel when I installed MKL. My code was being compiled with the OpenMPI header and libraries, but run with Intel's mpirun. All works as expected when I ensure I run with the mpirun executable from OpenMPI.
*checking that `malloc` succeeded in C
问题在于同时安装了 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 建议检查我的安装。