我是MPI的新手,我想做一个问题,我有2个数组A和B有15个元素,我有16个进程,每个进程代表数组中的一个元素(我不使用进程)零)。数组A已将输入数据存储在位置8 ... 15中,其中此位置代表树的叶子,并且在第一步中我在数组中进行压缩,其中叶子将数字发送给父级,父级接收来自所有儿子并添加数字并发送给父亲。并且在进程1处完成数组A si,其中是数组中所有元素的总和。在第二步中,我进行前缀计算,从进程0开始,然后在叶子处完成。 并且要计算数组B,所有其他进程需要等待进程1完成工作,为此我使用MPI_Barrier,但是当我执行代码时出错。
int m = 3;
int n = (int)pow(2, m);
int *A = (int*)malloc(2 * n * sizeof(int));
int *B = (int*)malloc(2 * n * sizeof(int));
int id;
MPI_Status status;
A[8] = 4; A[9] = 8; A[10] = 5; A[11] = 2;
A[12] = 10; A[13] = 6; A[14] = 9; A[15] = 11;
MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &id);
if (id == 1)
{
int nr;
int suma = 0;
MPI_Recv(&nr, 1, MPI_INT, 2 * id, 99, MPI_COMM_WORLD, &status);
suma += nr;
MPI_Recv(&nr, 1, MPI_INT, 2 * id + 1, 99, MPI_COMM_WORLD, &status);
suma += nr;
A[id] = suma;
printf("A[%d]=%d\n", id, A[id]);
B[id] = A[id];
printf("B[%d]=%d\n", id, B[id]);
MPI_Barrier(MPI_COMM_WORLD);
}
else
{
if (id != 0)
{
if(id >= 8)
{
MPI_Send(&A[id], 1, MPI_INT, id / 2, 99, MPI_COMM_WORLD);
printf("%d a trimis %d catre %d\n", id, A[id], id / 2);
MPI_Barrier(MPI_COMM_WORLD);
}
else
{
int nr;
int suma = 0;
MPI_Recv(&nr, 1, MPI_INT, 2 * id, 99, MPI_COMM_WORLD, &status);
suma += nr;
MPI_Recv(&nr, 1, MPI_INT, 2 * id + 1, 99, MPI_COMM_WORLD, &status);
suma += nr;
A[id] = suma;
MPI_Send(&A[id], 1, MPI_INT, id / 2, 99, MPI_COMM_WORLD);
printf("%d a trimis %d catre %d\n", id, A[id], id / 2);
MPI_Barrier(MPI_COMM_WORLD);
}
if (id % 2 == 1)
{
B[id] = B[(id - 1) / 2];
printf("B[%d]=%d\n", id, B[id]);
}
else
{
B[id] = B[id / 2] - A[id + 1];
printf("B[%d]=%d\n", id, B[id]);
}
}
MPI_Finalize();
free(A);
return 0;
我收到下一个错误:
[15]致命错误
MPI_Barrier中的致命错误:其他MPI错误, 错误堆栈:
MPI_Barrier(MPI_COMM_WORLD)失败 附加到引导队列 - 5064:344
如何使程序正常运作?
答案 0 :(得分:1)
MPI_Barrier()
是一个集体操作,一旦被来自通信器的所有 MPI任务调用它就会完成。
如果我正确读取了您的代码,则任务0
不会调用MPI_Barrier(MPI_COMM_WORLD)
,因此除非MPI库中的某些机制中止,否则您的程序将会死锁。