2016-12-06 17 views
0

MPI_Waitsome関数を使用しようとしていますが、プロセッサのランクに応じて異なるインデックス配列(およびアウトカウント)が使用されています。すべての16個のプロセッサは、同じエラーを返す:MPI_Waitsomeが失敗しています

[0] fatal error 
Fatal error in MPI_Waitsome: Invalid MPI_Request, errror stack: 
MPI_Waitsome(count=13, req_array="some address", out_count="some address", indices="some address", status_array="some address") failed 
Invalid MPI_Request 

コード片質問に次のようになります。私の目的は、デカルトグリッド内のプロセッサ間でデータを転送することです

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

int row(int inrank); 
int column(int inrank); 

int main() 
{ 
    int numtasks, rank, len, rc, i, n, tag = 1, outbufp, inbuf1[3], inbuf2[4]; 

    MPI_Status stats[13]; 
    MPI_Request reqs[13]; 

    for (i = 0; i<3; i++) { 
     inbuf1[i] = MPI_PROC_NULL; 
    } 

    for (i = 0; i<4; i++) { 
     inbuf2[i] = MPI_PROC_NULL; 
    } 

    char hostname[MPI_MAX_PROCESSOR_NAME]; 

    MPI_Init(NULL,NULL); 

    MPI_Comm_size(MPI_COMM_WORLD, &numtasks); 

    MPI_Comm_rank(MPI_COMM_WORLD, &rank); 

    MPI_Get_processor_name(hostname, &len); 

    printf("Number of tasks= %d My rank= %d Running on %s\n",numtasks,rank,hostname); 

    outbufp = rank; 

    n = 0; 

    for(i = (row(rank) * 4); i < ((row(rank) + 1) * 4); i++){  
     if(i != rank){   
      MPI_Isend(&outbufp, 1, MPI_INT, i, tag, MPI_COMM_WORLD, &reqs[n]); 
      n++; 
     }  
    } 

    for(i = row(rank); i < 16; i += 4){ 
     if(row(i) != row(rank)){   
      MPI_Isend(&outbufp, 1, MPI_INT, i, tag, MPI_COMM_WORLD, &reqs[n]); 
      n++; 
     }  
    } 

    for(i = (row(rank) * 4); i < ((row(rank) + 1) * 4); i++){ 
     if(i != rank){   
      MPI_Irecv(&inbuf1, 1, MPI_INT, i, tag, MPI_COMM_WORLD, &reqs[n]); 
      n++; 
     }  
    } 
    if(row(rank != column(rank))){ 
     for(i = (column(rank)*4); i < ((column(rank) + 1)*4); i++){   
       MPI_Irecv(&inbuf2, 1, MPI_INT, i, tag, MPI_COMM_WORLD, &reqs[n]); 
       n++;   
     } 
    } 

    int *indic; 
    indic = (int*) malloc(100*sizeof(int)); 

    for(i = 0; i < n; i++){ 
     indic[i] = i; 
    } 
    MPI_Waitsome(13, reqs, n, indic, stats); 

    printf("inbuf(y) =\t"); 

    for(i=0;i<3;i++){ 
     printf("%d\t",inbuf1[i]); 
    } 
    if(row(rank) != column(rank)){ 
     for(i=0;i<4;i++){ 
      printf("%d\t",inbuf2[i]); 
     } 
    } 
    MPI_Finalize(); 

    return 0; 
} 

int row(int inrank){ 
    return (inrank - inrank%4)/4; 
} 
int column(int inrank){ 
    return (inrank%4); 
} 

、私は承知していますしかし、新しいデカルト仮想トポロジでは、最初にバージョンをハードコードしたいと考えています。私は2つのMPI_Waitall関数をif文で使用することを検討していますが、MPI_Waitsome関数が現在動作していない理由はわかりません。私はそれがインデックスの配列が動的であるという事実と関係があるかもしれないと推測するだろうが、これは、プロセッサが斜めにオンかオフかに依存して異なるサイズであるので、そうでなければならない。

EDIT:最初

if(row(rank) != column(rank)){ 
    for(i = (column(rank)*4); i < ((column(rank) + 1)*4); i++){   
      MPI_Irecv(&inbuf2[m], 1, MPI_INT, i, rank, MPI_COMM_WORLD, &reqs2[m]); 
      m++;   
    } 
} 

//printf("Proc %d\n", rank); 

MPI_Waitall(9, reqs, stats); 

if(row(rank)!=column(rank)){ 
    MPI_Waitall(4, reqs2, stats2); 
} 

答えて

0

まず最初に、以下のように2つのMPI_Waitall機能を使用して解決しました。 コンパイラ警告を聞きます。

mpiwaitsome.c: In function ‘main’: 
mpiwaitsome.c:83:28: warning: passing argument 3 of ‘MPI_Waitsome’ makes pointer from integer without a cast [-Wint-conversion] 
    MPI_Waitsome(13, reqs, n, indic, stats); 
          ^
In file included from mpiwaitsome.c:1:0: 
/usr/include/mpi.h:1817:20: note: expected ‘int *’ but argument is of type ‘int’ 
OMPI_DECLSPEC int MPI_Waitsome(int incount, MPI_Request array_of_requests[], 
        ^~~~~~~~~~~~ 

これは、常にあなたの警告を修正することの重要性を示しています。コンパイラはAPIを間違って使用していることを非常に明確に伝えます。その後、ドキュメントをチェックアウトすることができます:

outcount 
    number of completed requests (integer) 
array_of_indices 
    array of indices of operations that completed (array of integers) 
array_of_statuses 
    array of status objects for operations that completed (array of Status). 

はすべて出力パラメータです。あなたはこれをこのように使用します。

int *indic = malloc(n*sizeof(int)); 
int outcount; 
MPI_Waitsome(n, reqs, &outcount, indic, stats); 

このようなインデックスを設定してMPIに伝えたいと思っていたことはよく分かりません。どの操作が実際に完了したかをインデックスで判断する必要があります。 一部はで、すべてが完了するわけではありません。それぞれの操作が完了していることを知らない限り、受信バッファーを読み取らないでください。すべての受信バッファを読み込み、送信バッファを再利用する場合は、MPI_Waitallを使用してください。

アポロスのバッファでは、これらのループの各反復に対して同じポインタ&inbuf1/&inbuf2を提供しています。間違った複数の同時受信操作を介して同じ場所に書き込む。 - また、非常に注意してくださいinbufint[]が、int*なかった場合、その後、&inbufはポインタのアドレスになります...あなたはおそらく何かをしたい:このため

MPI_Irecv(&inbuf1[magical-formula-for-index], 1, ... 
+0

おかげで、私の問題は、この時ということです私はVisual Studio開発者のコ​​マンドラインでコンパイルしているので、エラーや警告ではなくコンパイル時にエラーメッセージが表示されますが、これにはフラグがありますか?私は現在Cygwinで何かを試してみようとしています。 waitパラメータを修正してもエラーメッセージは表示されませんが、waitall関数に設定されている別のバージョンのプログラムと同じですが、if文の中ではプログラムが何も出力しないので、ただ待ちます:( –

+0

質問や新しい質問の編集として機能するはずだと思われるバージョンを提供してください。私はあなたの特定のIDEについてお手伝いすることはできませんが、警告を得るには合理的な方法が必要です。 – Zulan

関連する問題