簡體   English   中英

調用MPI_Recv掛起

[英]Call to MPI_Recv hangs

為簡單起見,向上發送發送至等級+1,向下發送發送至等級1

代碼將數組從一個節點發送到另一個節點之間。 這是代碼:

MPI_Request req1, req2;
MPI_Status s1, s2;
if (procid+1 != nproc) {
    // send up
    MPI_Isend(prior_hot_plate[my_num_rows-2], TOTAL_COLS, MPI_FLOAT, procid+1, k, MPI_COMM_WORLD, &req1);
    ++k;
    fprintf(stderr, "%d made it through Isend up\n", procid);
}
if (procid-1 != -1) {
    // send down
    MPI_Isend(prior_hot_plate[1], TOTAL_COLS, MPI_FLOAT, procid-1, k, MPI_COMM_WORLD, &req2);
    ++k;
    fprintf(stderr, "%d made it past Isend down\n", procid);
}
if (procid+1 != nproc) {
    // recv up
    //MPI_Wait(&req1, &s1);
    //fprintf(stderr, "%d finished wait\n", procid);
    MPI_Recv(prior_hot_plate[my_num_rows-1], TOTAL_COLS, MPI_FLOAT, procid+1, k, MPI_COMM_WORLD, &s1);
    ++k;
    fprintf(stderr, "%d finished receiving\n", procid);
}
if (procid-1 != -1) {
    // recv down
    //MPI_Wait(&req2, &s2);
    //fprintf(stderr, "%d finished wait\n", procid);
    MPI_Recv(prior_hot_plate[0], TOTAL_COLS, MPI_FLOAT, procid-1, k, MPI_COMM_WORLD, &s2);
    ++k;
    fprintf(stderr, "%d finished receiving\n", procid);
}

每個節點都可以順利通過Isend調用,但是所有這些節點都掛在對Recv的調用上。 有人認為這有問題嗎? 我想念什么?

謝謝

當您對一個呼叫MPI_Isend ,您在通過(並取回)的最后一個參數是一個MPI_Request對象。 您最初對MPI_Isend調用不會(必要)自行執行發送。 它只是通知MPI您想從現在到完成請求之間的某個時間進行發送操作。 為了表示您希望完成請求,您需要對完成函數(例如MPI_WaitMPI_Test )進行匹配的調用。

SO上還有其他問題也涵蓋了這一點(例如, 此處 )。

對於您的特定問題,正確的做法是將所有通信都轉換為非阻塞呼叫,然后在底部進行大的MPI_Waitall

MPI_Request reqs[] = {MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL, MPI_REQUEST_NULL};
if (procid+1 != nproc) {
    // send up
    MPI_Isend(prior_hot_plate[my_num_rows-2], TOTAL_COLS, MPI_FLOAT, procid+1, k, MPI_COMM_WORLD, &reqs[0]);
}
if (procid-1 != -1) {
    // send down
    MPI_Isend(prior_hot_plate[1], TOTAL_COLS, MPI_FLOAT, procid-1, k, MPI_COMM_WORLD, &reqs[1]);
}
if (procid+1 != nproc) {
    // recv up
    MPI_Irecv(prior_hot_plate[my_num_rows-1], TOTAL_COLS, MPI_FLOAT, procid+1, k, MPI_COMM_WORLD, &reqs[2]);
}
if (procid-1 != -1) {
    // recv down
    MPI_Irecv(prior_hot_plate[0], TOTAL_COLS, MPI_FLOAT, procid-1, k, MPI_COMM_WORLD, &reqs[3]);
}
++k;
MPI_Waitall(4, reqs, MPI_STATUSES_IGNORE);

好吧,我找到了答案。 我嘗試了韋斯利的方法,但無法成功。 它只是一直存在段錯誤。 但是他的例子使我最終改變了代碼。 在原始版本中,每次調用send和recv之后,我都將標記k遞增。 結果,recv呼叫正在尋找帶有錯誤標簽的消息。 通過將其切換為Wesley的方式-在最后增加k-解決了問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM