我有以下代码可以使用:
#include <mpi.h>
#include <stdio.h>
int main(int argc, char** argv) {
int world_rank, world_size;
MPI_Init(NULL, NULL);
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
int n = 10000;
int ni, i;
double t[n];
int x[n];
int buf[n];
int buf_size = n*sizeof(int);
MPI_Buffer_attach(buf, buf_size);
if (world_rank == 0) {
for (ni = 0; ni < n; ++ni) {
int msg_size = ni;
int msg[msg_size];
for (i = 0; i < msg_size; ++i) {
msg[i] = rand();
}
double time0 = MPI_Wtime();
MPI_Bsend(&msg, msg_size, MPI_INT, 1, 0, MPI_COMM_WORLD);
t[ni] = MPI_Wtime() - time0;
x[ni] = msg_size;
MPI_Barrier(MPI_COMM_WORLD);
printf("P0 sent msg with size %d\n", msg_size);
}
}
else if (world_rank == 1) {
for (ni = 0; ni < n; ++ni) {
int msg_size = ni;
int msg[msg_size];
MPI_Request request;
MPI_Barrier(MPI_COMM_WORLD);
MPI_Irecv(&msg, msg_size, MPI_INT, 0, 0, MPI_COMM_WORLD, &request);
MPI_Wait(&request, MPI_STATUS_IGNORE);
printf("P1 received msg with size %d\n", msg_size);
}
}
MPI_Buffer_detach(&buf, &buf_size);
MPI_Finalize();
}
一旦我删除了打印语句,程序就会崩溃,告诉我有一个MPI_ERR_BUFFER: invalid buffer pointer
。如果我只删除其中一个打印语句,则其他打印语句仍然执行,所以我认为它在程序结束时崩溃了。我不明白它崩溃的原因以及当我使用print语句时它没有崩溃的事实超出了我的逻辑......
有人知道这里发生了什么吗?
答案 0 :(得分:0)
您根本没有为MPI提供足够的缓冲区空间。在缓冲模式下,所有正在进行的消息都存储在缓冲区空间中,缓冲区空间用作环形缓冲区。在您的代码中,无论printf
如何,都可能有多条消息需要缓冲。请注意,即使2*n*sizeof(int)
也没有足够的缓冲区空间 - 即使相应的接收完成,这些障碍也不能保证缓冲区在本地被释放。你必须提供(n*(n-1)/2)*sizeof(int)
记忆以确保,或介于两者之间并希望。
底线:不要使用缓冲模式。
通常,使用标准阻止发送调用并编写应用程序,使其不会死锁。调整MPI实现,使得无论接收器如何都是小消息 - 以避免在后期接收器上等待。
如果您想重叠通信和计算,请使用非阻塞消息 - 为每次通信提供适当的内存。