我试图编写一个简单的多进程程序来在数组中找到一个值。
#include <mpi.h>
#include <stdio.h>
int* create_array(int num_items) {
int* tmp = new int[num_items];
for(int i = 0; i < num_items; i++)
tmp[i] = i;
return tmp;
}
int main() {
int num_items = 1000;
int item = 999;
MPI_Init(NULL, NULL);
int world_rank, world_size, num_items_per_proc;
MPI_Comm_rank(MPI_COMM_WORLD, &world_rank);
MPI_Comm_size(MPI_COMM_WORLD, &world_size);
MPI_Request* inReq;
int* array;
if(world_rank == 0) {
array = create_array(num_items);
num_items_per_proc = (num_items / world_size) + 1;
}
int* sub_array = new int[num_items_per_proc];
MPI_Scatter(array, num_items_per_proc, MPI_INT, sub_array,
num_items_per_proc, MPI_INT, 0, MPI_COMM_WORLD);
bool found = false;
MPI_Irecv(&found, 1, MPI::BOOL, MPI_ANY_SOURCE, MPI_ANY_TAG,
MPI_COMM_WORLD, inReq);
for(int i = 0; i < num_items_per_proc && !found; i++) {
if (sub_array[i] == item) {
found = true;
printf("Elemento %d trovato in posizione: %d\n", item, i);
for(int j = 0; j < world_size; j++)
if(j != world_rank)
MPI_Send(&found, 1, MPI::BOOL, j, j, MPI_COMM_WORLD);
}
}
if(world_rank == 0) delete[] array;
delete[] sub_array;
MPI_Barrier(MPI_COMM_WORLD);
MPI_Finalize();
return 0;
}
当我们中的一个人在数组的一部分中找到了值时,我试图阻止所有这些,但我从Irecv获得了一个分段错误。我怎么解决这个问题?
答案 0 :(得分:1)
您的代码无法正常工作的原因是您必须提供实际的MPI_Request
到MPI_Irecv
- 而不仅仅是未初始化的指针!
MPI_Request inReq;
MPI_Irecv(&found, 1, MPI_CXX_BOOL, MPI_ANY_SOURCE, MPI_ANY_TAG,
MPI_COMM_WORLD, &inReq);
您处理found
的方式是错误的。您不能修改给予异步请求的变量,也不能假设它在后台更新。非阻塞消息是不单侧远程内存操作。所以你必须调用test,如果状态指示收到的消息,你可以中止循环。确保每个请求都已完成,同样也在找到结果的排名中。
此外,num_items_per_proc
必须在所有排名上有效(用于分配内存,以及在recvcount
中指定MPI_Scatter
。
MPI_Finalize
之前的障碍是多余的,最后,删除了MPI的C ++绑定,使用MPI_CXX_BOOL
而不是MPI::BOOL
。
您可以在answers of this question中找到解决问题的更复杂方法。