2016-12-09 3 views
1

私はMPI C++プログラムをローカルで2つのプロセス:mpirun -np 2 <programname>で実行しています。私は、MPI_Gatherコマンドの一貫性のない動作を見ています。テストするために、私は非常に短いコードスニペットを書いた。私はコードをメインの先頭にコピーして正常に動作しました。しかし、それをコード内の他のポイントにコピーすると、時には正しい結果が得られ、時には正しくない場合もあります。コードスニペットが下にコピーされます。問題がコードスニペット自体にあるとは思えません。通常、このようなコードの動作が一貫していないと、メモリの破損が疑われます。しかし、私はこの場合Valgrindを実行しましたが、それは何も報告しませんでした(おそらく私はValgrindをMPIに対して正しく実行していないかもしれません - 私はValgrindをMPIプログラムで使用する経験はありません)。 この種の矛盾した動作を引き起こす原因は何ですか?問題を検出するために何ができますか?MPI_Gatherからの一貫性のない動作

ここにはコードスニペットがあります。

double val[2] = {0, 1};  
val[0] += 10.0*double(gmpirank);  
val[1] += 10.0*double(gmpirank);  
double recv[4];  
printdebug("send", val[0],val[1]);  
int err = MPI_Gather(val,2,MPI_DOUBLE,recv,2,MPI_DOUBLE,0,MPI_COMM_WORLD);  
if (gmpirank == 0) { 
    printdebug("recv");  
    printdebug(recv[0],recv[1]);  
    printdebug(recv[2],recv[3]); 
}  
printdebug("finished test", err); 

プロセスごとに分離され、そしてカンマで入力引数を分離ファイルに印刷デバッグ機能プリント。

プロセス1枚の版画:たまに

send, 10, 11 
finished test, 0 

、プロセス0版画:

send, 0, 1 

recv 

0, 1 

10, 11 

finished test, 0 

しかし、私は、コードの他のセクションにコードを配置し、プロセス0時にプリントこのようなもの:

send, 0, 1 

recv 

0, 1 

2.9643938750474793e-322, 0 

finished test, 0 
+1

を未定義の動作は、多くの形態をとることができ、これは他のコードなしで伝えるのは難しいことになるだろう。 – Zulan

+0

「その他のコード」は非常に大きなプログラムです。そのため、すべてのコードを読み取って無効な読み取り/書き込みバグを探すことはできません。私の質問は、主にMPIを使用する際に、この種のバグを見つけるための一般的な戦略に関するものです。私はValgrindを使って解決策を見つけました(下記参照)。これらのタイプのMPI問題(および解決策)に他の潜在的な原因がある場合は、そのことについて聞くことに興味があります。 –

答えて

1

解決策が見つかりました。疑わしいように、問題はメモリ破損でした。

私はValgrindをMPIで実行するときに初心者の間違いをしました。私は走った:

valgrind <options> mpirun -np 2 <programname> 

代わりの

mpirun -np 2 valgrind <options> <programname> 

このように、私は "mpirunの" 自体にではなく、意図したプログラムでvalgrindのを実行していました。 Valgrindを正しく実行すると、コードの無関係な部分のメモリ破損が特定されました。私はこれを理解助けるための別のスタックオーバーフローQ/Aへ

賞賛:Using valgrind to spot error in mpi code

+0

よくできました。あなたは、左側のチェックマークをチェックすることで、あなた自身の答えを受け入れることができます。 –

関連する問題