2016-05-24 14 views
0

分散システムの異なるノードに格納されている整数配列に対してビット単位の操作を実行しようとしています。結果を計算した後、結果をすべてのノードに配布したいと思います。これを達成するために、MPI_Allreduce操作を使用しようとしています。しかし、次のコードでランタイムエラーが発生しています。分散OR操作のデバッグ

#include <bits/stdc++.h> 
#include <mpi.h> 
#include <unistd.h> 
using namespace std; 

int main (int argc, char* argv[]) { 
    int numtasks, taskid, n=200, i; 

    MPI_Init(&argc, &argv); 
    MPI_Comm_size(MPI_COMM_WORLD, &numtasks); 
    MPI_Comm_rank(MPI_COMM_WORLD, &taskid); 

    int *arr; 
    arr = new int[n]; 
    for(i=0; i<n; i++) arr[i] = 0; 
    for(i=taskid; i<n; i+=numtasks) arr[i] = 1; 

    MPI_Allreduce(arr, arr, n, MPI_INT, MPI_BOR, MPI_COMM_WORLD); 

    if(taskid == 0){ 
     for(i=0; i<n; i++) printf("%d ", arr[i]); 
     printf("\n"); 
    } 

    MPI_Finalize(); 
    return 0; 
} 

、nが1であるとき、プログラムが正しく動作しているが、それは実行時に以下のエラーを与えているときのn> 1。

[ユーザー:17026]エラーがMPI_Allreduce
で発生した[ユーザー:17026]コミュニケータMPI_COMM_WORLDに
[ユーザー:17026] MPI_ERR_BUFFER:無効なバッファポインタ
[ユーザー:17026] MPI_ERRORS_ARE_FATAL:あなたのMPIジョブ今


mpirunのを中止します不適切出るノードのユーザ にPID 17028とプロセスランク2に起因して終了しました。これが発生する可能性がある2つの理由があります。

  1. このプロセスが終了する前に、「初期化」を呼び出すことはありませんでしたが、ジョブ内の他の人がやりました。これにより、すべてのプロセスが "init"を呼び出すのを待つ間に、ジョブが無期限にハングすることがあります。ルールによって、あるプロセスが "init"を呼び出す場合、 すべてのプロセスは終了前に "init"を呼び出さなければなりません。

  2. このプロセスは「init」と呼ばれますが、「finalize」を呼び出さずに終了します。規則により、これはアプリケーション内の他のプロセスがで を終了させたかもしれない

「初期化」と呼び、すべてのプロセスが終了する前 に「確定」を呼び出す必要がありますまたはそれが「異常終了」とみなされますmpirunによって送信された信号(ここで報告されているように)。


[ユーザー:17025] 3つの以上のプロセスが送られてきたヘルプメッセージヘルプ-MPI-ERRORS.TXT/mpi_errors_are_fatal
[ユーザー:17025]すべてのヘルプ/エラーメッセージを参照するには0に設定MCAパラメータ "orte_base_help_aggregate"私が知りたい

インターネット上で入手可能な例のほとんどは唯一の1ようなnをとっているので、MPI_Allreduceは、n> 1かで動作しません。私のアプローチが完全に間違っている場合は、私の問題の解決策を提案してください。

答えて

4

送信と受信に同じバッファを使用する場合は、MPI_IN_PLACEを送信バッファとして指定できます。

MPI_Allreduce(MPI_IN_PLACE, arr, n, MPI_INT, MPI_BOR, MPI_COMM_WORLD); 

注:これはイントラコミュニケータでのみ機能します。 MPI_COMM_WORLDはイントラコミュニケータです。インターコミュニケーターが何であるかわからない場合は、おそらくコミュニケータはイントラコミュニケータです。

1

私は、MPIライブラリを知らないMPI_Allreduceのドキュメントから:

int型MPI_Allreduce(のconst void *型sendbuf、void *型recvbuf、int型の数、 MPI_Datatypeデータ型、MPI_Opオペアンプ、MPI_CommのCOMM)

私は「のconst void *型sendbuf」と「無効* recvbuf」というの推測私が思う重く、並列コンピューティングではなおさら、異なるアレイであることをを持っています。

二つのポインタが同じアドレスまたは重複である場合には、そのライブラリのチェックを私は驚かないだろう、それゆえメッセージ:

[ユーザー:17026] MPI_ERR_BUFFER:無効なバッファポインタ

オリジナルとの違いの

#include <bits/stdc++.h> 
#include <mpi.h> 
#include <unistd.h> 
using namespace std; 

int main (int argc, char* argv[]) { 
    int numtasks, taskid, n=200, i; 

    MPI_Init(&argc, &argv); 
    MPI_Comm_size(MPI_COMM_WORLD, &numtasks); 
    MPI_Comm_rank(MPI_COMM_WORLD, &taskid); 

    int *arr_send = new int[n]; 
    int *arr_recv = new int[n]; 
    for(i=0; i<n; i++) arr_send[i] = 0; 
    for(i=taskid; i<n; i+=numtasks) arr_send[i] = 1; 

    MPI_Allreduce(arr_send, arr_recv, n, MPI_INT, MPI_BOR, MPI_COMM_WORLD); 

    if(taskid == 0){ 
     for(i=0; i<n; i++) printf("%d ", arr_recv[i]); 
     printf("\n"); 
    } 

    MPI_Finalize(); 
    return 0; 
} 

ない多く:

だからコードは次のようなものになるだろう。それがあなたのために働くかどうか私に教えてください。

+0

はい、完全に機能しました。ありがとう –