【问题标题】:MPI_send and MPI_receive function getting stuckMPI_send 和 MPI_receive 函数卡住
【发布时间】:2015-08-26 17:25:31
【问题描述】:

我有一个 page_rank 代码,我必须在其中并行计算页面排名。我的代码挂在我编写以下 MPI_send 和 MPI_receive 函数的地方。可能是什么问题呢?

int **sendto_list = (int **)malloc(comm_size*sizeof(int*));
for(i=0; i < comm_size; i++) {
    sendto_list[i] = (int *)malloc(18*sizeof(int));
    sendto_list[i][0] = 16;
    sendto_list[i][1] = 0;
}

int temp_data = 1;
for(i=0; i < comm_size; i++) {
    if(request_list[i][1] > 0) {
        for(k=0; k < request_list[i][1]; ) {
            for(j=0; j < 200; j++) {
                if( k >= request_list[i][1] )
                        break;

                sendrecv_buffer_int[j] = request_list[i][k+2];
                k++;
            }
            // Request appropriate process for pagerank.
            if(i!= my_rank)
                MPI_Send(&temp_data, 1, MPI_INT, i, TAG_PR_REQ, MPI_COMM_WORLD);
        }
    }

    if( i != my_rank )
        MPI_Send(&temp_data, 1, MPI_INT, i, TAG_PR_DONE, MPI_COMM_WORLD);
}

int expected_requests = 0, done = 0,temp,s;
s=0;
while( (done == 0) && (comm_size > 1) ) {
    if(expected_requests == (comm_size - 1))
        break;

    int count;
    // Receive pagerank requests or messages with TAG_PR_DONE(can be from any process).
    MPI_Recv(&temp, 1, MPI_INT, MPI_ANY_SOURCE ,MPI_ANY_TAG, MPI_COMM_WORLD, &status);

    MPI_Get_count(&status, MPI_INT, &count);

    switch(status.MPI_TAG) {
        case TAG_PR_REQ:{
            for(i = 0 ; i < count; i++)
                insert_into_adj_list(&sendto_list[status.MPI_SOURCE], sendrecv_buffer_int[i], num_nodes);
            break;
            }
            case TAG_PR_DONE:{
                expected_requests++;
                break;
            }
            default:
                break;
    }
}

【问题讨论】:

标签: c mpi openmpi


【解决方案1】:

粗略浏览一下您的代码,您的问题似乎是因为您的 MPI_Send() 调用被阻塞,因此没有任何东西可以接收和释放它们。

如果(request_list[i][1] &gt; 0)(i!= my_rank) 评估为true,您尝试执行2 个MPI_Send() 操作来处理排名i,但您在每个进程中只有1 个匹配的MPI_Recv() 操作,即进程排名@987654330 @。

你可能想尝试改变

if(request_list[i][1] > 0) {
    ...
}

if( i != my_rank )
    MPI_Send(&temp_data, 1, MPI_INT, i, TAG_PR_DONE, MPI_COMM_WORLD);

if(request_list[i][1] > 0) {
    ...
} else if( i != my_rank ) {
    MPI_Send(&temp_data, 1, MPI_INT, i, TAG_PR_DONE, MPI_COMM_WORLD);
}

注意添加elseif 变成else if。这确保每个进程只有 1 个MPI_Send() 操作。如果上述条件为真,看起来这两个MPI_Send() 操作不应该执行。


或者,如果您需要,您可以查看MPI_Isend()MPI_Irecv()。尽管我认为在这种情况下他们不会完全解决您的问题。我仍然认为你需要else if 子句。


我还想指出,在 C 中没有必要强制返回 malloc()。这个话题已经在 StackOverflow 上进行了广泛的讨论,所以我不会过多地讨论它。

您还应该检查malloc() 的结果是一个有效的指针。如果发生错误,它会返回NULL

【讨论】:

    猜你喜欢
    • 2017-04-11
    • 1970-01-01
    • 2015-04-05
    • 2018-02-15
    • 2021-11-19
    • 2018-05-13
    • 1970-01-01
    • 2018-09-11
    • 1970-01-01
    相关资源
    最近更新 更多