我正在使用MPI库在C中编写一个简单的程序。 该计划的目的如下:
我有一组执行迭代循环的进程,在此循环结束时,通信器中的所有进程都必须调用两个集合函数(MPI_Allreduce
和MPI_Bcast
)。第一个发送已生成num.val
变量最小值的进程的id,第二个发送从源num_min.idx_v
广播到通信器MPI_COMM_WORLD
中的所有进程。 / p>
问题是我不知道在调用集合函数之前是否会完成第i个进程。所有进程都有1/10的概率终止。这模拟了我正在实现的真实程序的行为。当第一个进程终止时,其他进程会导致死锁。
这是代码:
#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
typedef struct double_int{
double val;
int idx_v;
}double_int;
int main(int argc, char **argv)
{
int n = 10;
int max_it = 4000;
int proc_id, n_proc;double *x = (double *)malloc(n*sizeof(double));
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &n_proc);
MPI_Comm_rank(MPI_COMM_WORLD, &proc_id);
srand(proc_id);
double_int num_min;
double_int num;
int k;
for(k = 0; k < max_it; k++){
num.idx_v = proc_id;
num.val = rand()/(double)RAND_MAX;
if((rand() % 10) == 0){
printf("iter %d: proc %d terminato\n", k, proc_id);
MPI_Finalize();
exit(EXIT_SUCCESS);
}
MPI_Allreduce(&num, &num_min, 1, MPI_DOUBLE_INT, MPI_MINLOC, MPI_COMM_WORLD);
MPI_Bcast(x, n, MPI_DOUBLE, num_min.idx_v, MPI_COMM_WORLD);
}
MPI_Finalize();
exit(EXIT_SUCCESS);
}
也许我应该在if语句中调用MPI_Finalize函数之前创建一个新组和新的通信器?我该怎么解决这个问题?
答案 0 :(得分:0)
如果您在进程终止之前控制进程,则应该向无法提前终止的等级发送非阻塞标记(将其称为根等级)。然后,您可以将所有等级的发送与其值一起发送到根等级,而不是阻止all_reduce。
根级别可以为可能的标志和值发布非阻塞接收。所有级别都必须发送一个或另一个。一旦考虑了所有等级,你就可以减少根等级,从通信中删除退出的等级并进行广播。
如果您的排名在没有通知的情况下退出,我不确定您有哪些选择。