0

PETSc ライブラリを使用して複雑な関数を作成することに成功しました (これは、巨大な線形システムを並列に解くための MPI ベースの科学ライブラリです)。このライブラリは、独自の「malloc」バージョンと基本的なデータ型 (つまり、標準の「int」としての「PetscInt」) を提供します。この関数には、「malloc」や「int」などの標準的なものではなく、常に PETSc のものを使用してきました。この機能は広範囲にテストされ、常に正常に動作しました。MPI を使用しているにもかかわらず、関数は完全にシリアルであり、すべてのプロセッサが同じデータに対して実行します (各プロセッサにはコピーがあります)。通信はまったく関係ありません。

次に、PETSc を使用せず、標準の MPI バージョンを作成することにしました。基本的に、残忍な力ではなく、置換に注意を払って、PETSc のものを古典的な C のものに置き換えるすべてのコードを書き直しました (エディタの「置換」ツールはありません! すべて手作業で行われます)。置換中、a[2] を宣言する代わりに、2 つの異なる変数 a と b を宣言するなど、小さな変更はほとんど行われていません。これらは置換です:

PetscMalloc -> malloc

PetscScalar -> double

PetscInt -> int

PetscBool -> C には boolean データ型がないため、それを複製する列挙型構造を作成しました。

基本的に、アルゴリズムは置換プロセス中に変更されていません。メイン関数は「for」ループです (実際には 4 つのネストされたループ)。各反復で、別の関数を呼び出します。それをディスファンクションと呼びましょう。Disfunction は 4 サイクルの外側では (私が個別にテストしたように) 完全に機能しますが、4 サイクルの内側では機能する場合と機能しない場合があります。また、各反復で Disfunction に渡されるデータをチェックしました。ECXACTELY が同じ入力である場合、Disfunction は反復ごとに異なる計算を実行します。また、 Disfunction はプログラムの異なる実行で常に同じ結果を返すため、計算されたデータは未定義の動作ではないようです。「mpiexec」のプロセッサ数を変更すると、異なる計算結果が得られることに気付きました。

それが私の問題です。その他の考慮事項: プログラムは「malloc」を広範囲に使用します。計算されたデータは、正しいかどうかにかかわらず、すべてのプロセスで同じです。Valgrind はエラーを検出しません (別の問題であり、OT である printf の通常の使用によるエラーの検出は別として)。Disfunction は、他の 2 つの関数を再帰的に呼び出します (PETSc バージョンでも広範囲にテストされています)。関連するアルゴリズムは数学的に正しいです。機能不全は整数パラメータ p>0 に依存します: p=1,2,3,4,5 の場合は完全に機能しますが、p>=6 の場合は機能しません。

質問があれば、コードを投稿できますが、長くて複雑 (科学的に、情報的にではありません) であり、説明するには時間がかかると思います。

私の考えでは、メモリ割り当てを台無しにしているのですが、どこにあるのかわかりません。私の英語と悪い形式で申し訳ありません。

4

2 に答える 2