当 MPI_FLOAT 的计数 > 64 时,MPI_send 和 MPI_recv 挂起
MPI_send and MPI_recv is hanging when count > 64 for MPI_FLOAT
我在使用 MPI_Send
和 MPI_Recv
时遇到问题。当count <= 64
的时候,整体运行没有问题,而count > 64
的时候程序挂了。
有什么解决办法吗?该地址在两个 GPU 上的全局内存地址上。
这是我使用的代码。当我设置 n<=64
时它起作用,否则它会挂起。
#include <stdio.h>
#include <string.h>
#include <mpi.h>
int main(int argc, char *argv[])
{
char *d_msg;
int myrank, tag=99;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
const int n = 65; // <-- number of FLOATs
const int num_GPUs = 2;
cudaMalloc((void**)&d_msg, n*sizeof(float));
MPI_Send(d_msg, n, MPI_FLOAT, (myrank + 1)%num_GPUs, tag, MPI_COMM_WORLD);
MPI_Recv(d_msg, n, MPI_FLOAT, (myrank - 1 + num_GPUs)%num_GPUs, tag, MPI_COMM_WORLD, &status);
MPI_Finalize();
return 0;
}
MPI_Send
是阻塞调用。您的进程都处于 MPI_Send
等待对方调用 MPI_Recv
。 MPI_Send
可以 对小消息是非阻塞的,这就是它适用于 <= 64 个元素的原因。
可能的解决方案是:
- 在通信队列中以交替顺序调用
MPI_Send
和 MPI_Recv
- 使用
MPI_Sendrecv
- 使用非阻塞通信(
MPI_Isend
/MPI_Irecv
)
这里最简单的方法可能是只使用 MPI_Sendrecv
并将 MPI_Send
和 MPI_Recv
调用替换为
MPI_Sendrecv(d_msg, n, MPI_FLOAT, (myrank + 1)%num_GPUs, tag,
d_msg, n, MPI_FLOAT, (myrank - 1 + num_GPUs)%num_GPUs, tag, MPI_COMM_WORLD, &status);
我在使用 MPI_Send
和 MPI_Recv
时遇到问题。当count <= 64
的时候,整体运行没有问题,而count > 64
的时候程序挂了。
有什么解决办法吗?该地址在两个 GPU 上的全局内存地址上。
这是我使用的代码。当我设置 n<=64
时它起作用,否则它会挂起。
#include <stdio.h>
#include <string.h>
#include <mpi.h>
int main(int argc, char *argv[])
{
char *d_msg;
int myrank, tag=99;
MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &myrank);
const int n = 65; // <-- number of FLOATs
const int num_GPUs = 2;
cudaMalloc((void**)&d_msg, n*sizeof(float));
MPI_Send(d_msg, n, MPI_FLOAT, (myrank + 1)%num_GPUs, tag, MPI_COMM_WORLD);
MPI_Recv(d_msg, n, MPI_FLOAT, (myrank - 1 + num_GPUs)%num_GPUs, tag, MPI_COMM_WORLD, &status);
MPI_Finalize();
return 0;
}
MPI_Send
是阻塞调用。您的进程都处于 MPI_Send
等待对方调用 MPI_Recv
。 MPI_Send
可以 对小消息是非阻塞的,这就是它适用于 <= 64 个元素的原因。
可能的解决方案是:
- 在通信队列中以交替顺序调用
MPI_Send
和MPI_Recv
- 使用
MPI_Sendrecv
- 使用非阻塞通信(
MPI_Isend
/MPI_Irecv
)
这里最简单的方法可能是只使用 MPI_Sendrecv
并将 MPI_Send
和 MPI_Recv
调用替换为
MPI_Sendrecv(d_msg, n, MPI_FLOAT, (myrank + 1)%num_GPUs, tag,
d_msg, n, MPI_FLOAT, (myrank - 1 + num_GPUs)%num_GPUs, tag, MPI_COMM_WORLD, &status);