具有集体功能的MPI死锁

时间:2015-05-27 10:28:17

标签: c mpi deadlock

我正在使用MPI库在C中编写一个简单的程序。 该计划的目的如下:

我有一组执行迭代循环的进程,在此循环结束时,通信器中的所有进程都必须调用两个集合函数(MPI_AllreduceMPI_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函数之前创建一个新组和新的通信器?我该怎么解决这个问题?

1 个答案:

答案 0 :(得分:0)

如果您在进程终止之前控制进程,则应该向无法提前终止的等级发送非阻塞标记(将其称为根等级)。然后,您可以将所有等级的发送与其值一起发送到根等级,而不是阻止all_reduce。

根级别可以为可能的标志和值发布非阻塞接收。所有级别都必须发送一个或另一个。一旦考虑了所有等级,你就可以减少根等级,从通信中删除退出的等级并进行广播。

如果您的排名在没有通知的情况下退出,我不确定您有哪些选择。