2015-12-09 62 views
1

我不知道如何解決這個程序到目前爲止的問題。此程序的目的是將數組中的所有數字相加,但在錯誤開始出現之前,我幾乎無法設法發送數組。它與if statementmy_rank!=0部分的for循環有關。我沒有看到我的MPI程序中存在什麼問題

#include <stdio.h> 
#include <mpi.h> 

int main(int argc, char* argv[]){ 
int my_rank, p, source, dest, tag, total, n = 0; 
MPI_Status status; 

MPI_Init(&argc, &argv); 
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank); 
MPI_Comm_size(MPI_COMM_WORLD, &p); 

//15 processors(1-15) not including processor 0 
if(my_rank != 0){ 
    MPI_Recv(&n, 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status); 
    int arr[n]; 
    MPI_Recv(arr, n, MPI_INT, source, tag, MPI_COMM_WORLD, &status); 

    //printf("%i ", my_rank); 
    int i; 
    for(i = ((my_rank-1)*(n/15)); i < ((my_rank-1)+(n/15)); i++){ 
    //printf("%i ", arr[0]); 
    } 

} 
else{ 
    printf("Please enter an integer:\n"); 
    scanf("%i", &n); 

    int i; 
    int arr[n]; 

    for(i = 0; i < n; i++){ 
    arr[i] = i + 1; 
    } 

    for(dest = 0; dest < p; dest++){ 
    MPI_Send(&n, 1, MPI_INT, dest, tag, MPI_COMM_WORLD); 
    MPI_Send(arr, n, MPI_INT, dest, tag, MPI_COMM_WORLD); 
    } 
} 
MPI_Finalize(); 
} 

當我把它作爲循環出來它編譯和運行,但當我把它放回它只是停止工作。下面是它給我的錯誤:

[compute-0-24.local:1072] *** An error occurred in MPI_Recv 
[compute-0-24.local:1072] *** on communicator MPI_COMM_WORLD 
[compute-0-24.local:1072] *** MPI_ERR_RANK: invalid rank 
[compute-0-24.local:1072] *** MPI_ERRORS_ARE_FATAL: your MPI job will now abort 
Please enter an integer: 
-------------------------------------------------------------------------- 
mpirun has exited due to process rank 8 with PID 1072 on 
node compute-0-24 exiting improperly. There are two reasons this could occur: 

1. this process did not call "init" before exiting, but others in 
the job did. This can cause a job to hang indefinitely while it waits 
for all processes to call "init". By rule, if one process calls "init", 
then ALL processes must call "init" prior to termination. 

2. this process called "init", but exited without calling "finalize". 
By rule, all processes that call "init" MUST call "finalize" prior to 
exiting or it will be considered an "abnormal termination" 

This may have caused other processes in the application to be 
terminated by signals sent by mpirun (as reported here). 
-------------------------------------------------------------------------- 
[compute-0-16.local][[31957,1],0][btl_tcp_endpoint.c:638:mca_btl_tcp_endpoint_complete_connect] connect() to 192.168.4.237 failed: Connection refused (111) 
[cs-cluster:11677] 14 more processes have sent help message help-mpi-errors.txt/mpi_errors_are_fatal 
[cs-cluster:11677] Set MCA parameter "orte_base_help_aggregate" to 0 to see all help/error messages 

回答

1

有你發佈的代碼兩個問題:

  1. 的發送環路從p=0開始,這意味着秩零的過程中會發送給自己。但是,由於過程零沒有接收部分,所以這不起作用。只需讓循環從p=1開始,那應該可以解決它。
  2. 您使用的tag未初始化。所以它的價值可以是任何東西(這是可以的),但是每個進程可以是不同的,這將導致各種通信永不匹配。例如,只需初始化tag=0即可解決該問題。

有了這個,你的代碼片段應該工作。

1

學習閱讀Open MPI爲您提供的信息錯誤消息並應用一些常規調試策略。

[compute-0-24.local:1072] *** An error occurred in MPI_Recv 
[compute-0-24.local:1072] *** on communicator MPI_COMM_WORLD 
[compute-0-24.local:1072] *** MPI_ERR_RANK: invalid rank 

庫正在告訴你接收操作被調用的無效等級值。有了這些知識,你可以看看你的代碼:

int my_rank, p, source, dest, tag, total, n = 0; 
... 
//15 processors(1-15) not including processor 0 
if(my_rank != 0){ 
    MPI_Recv(&n, 1, MPI_INT, source, tag, MPI_COMM_WORLD, &status); 
    ... 

排名是sourcesource是一個自動變量,在之前聲明瞭一些行但從未初始化過,因此它的初始值是完全隨機的。您通過指定source初始值0或簡單地將其替換爲0來解決此問題,因爲您已通過在if運算符的else塊中挑出其代碼,對發送者的等級進行了硬編碼。

上述錯誤的存在最終會提示您檢查其他變量。因此您注意到tag也被用於未初始化,您可以將其初始化爲例如0或完全替換它。

現在你的程序幾乎是正確的。你注意到它似乎工作罰款n高達約33000(自運輸的默認渴望限制除以sizeof(int)),但然後它掛起爲較大的值。您要麼在每次發送和接收操作之前和之後觸發一個簡單地添加printf語句的調試器,並且發現已經第一次調用MPI_Senddest等於0永不返回。然後你把你的代碼定睛一看,發現這個:

for(dest = 0; dest < p; dest++){ 

dest開始從0,但這是錯誤的,因爲排名0只發送數據和接收不到。您通過將初始值設置爲1來修復它。

你的程序現在應該按預期工作(或者至少對於n的值不會導致int arr[n];中的堆棧溢出)。恭喜!現在去了解MPI_ProbeMPI_Get_count,這將幫助您在不明確發送數組長度的情況下做同樣的事情。然後瞭解MPI_ScatterMPI_Reduce,這將使您可以更優雅地實現算法。

相關問題