MPIを使用するコード/ライブラリと互換性のある単体テストフレームワークに関する推奨事項はありますか?


13

通常、シリアルコードを記述し、その際に、xUnitスタイルのテストフレームワーク(MATLAB xUnit、PyUnit / nose、またはGoogleのC ++テストフレームワーク)を使用してユニットテストを記述します。

Googleの大まかな検索に基づいて、実務家がMPIを使用するコードを単体テストする方法についてはあまり見ていません。そのためのベストプラクティスはありますか?

ユニットテストとテスト駆動開発の戦略と比較して、テストフレームワークに使用するソフトウェアに関する答えを探しています(存在する場合-答えは「独自のコードをロール」することができます)カスタムテストコードの事例が参考になります)。

私がテストしようとしているもののほとんどは、右側の関数評価と半離散化PDEを統合するタイムステッパーのヤコビ行列アセンブリルーチンです。私はPETScを使用するので、PETSc固有のものがあれば、より一般的なテストフレームワークに加えて役立ちます。

明確化の編集:

例はにあり${PETSC_DIR}/src/ts/examples/tutorials/ex2.c、ここでRHSFunction(右側の関数評価)などのテストを行います。RHSJacobian(ヤコビ行列の評価)。私は、組み立てられた右側と組み立てられたヤコビ行列の既知の値に対してテストします。いくつかの単純な問題の場合、これらの値を分析的に取得できます。これらの関数は、他のアプリケーションレベルの関数を実行しないアプリケーション固有の関数ですが、関数内でベクトルまたは行列のアセンブリが実行されると、MPIを呼び出すことができます(上記のリンクされたPETScの例のように)。プロセッサにローカルなベクトルまたは行列の一部のみを計算する関数を作成する場合、可能な場合はグローバルなアセンブルバージョンに対してテストする必要があります。これは、パラレルプログラミングが初めてなので、グローバルなベクトルとグローバルについて考える方が直感的だからです。マトリックス。これらのテストは、小さな問題サイズと少数のプロセッサーで実行されます。

これを行うためのいくつかの戦略を考えることができます。

  • このトピックで行ったGoogleの検索に基づいて、おそらくうまく機能しない戦略は、既知の出力を構築し、相対/絶対エラーを並行して見つけ、単純な比較を行うことです。MPIを使用して「Hello、world」プログラムを作成した人なら誰でも、出力が文字化けする可能性があります。これは、単体テストの実行の有用性を制限します。(これが質問をするきっかけになりました単体テストフレームワークの呼び出しには、潜在的なトリッキーさもあるようです。
  • 出力をファイルに書き込み(たとえば、PETScでVecViewand を使用してMatView)、ndiffまたはのような既知の出力と比較しnumdiffます。ファイル比較を使用して単体テストを行った以前の経験から得たこのメソッドの直感は、細心の注意が必要であり、フィルタリングが必要になるということです。ただし、上記のユーティリティをプレーンdiffに置き換えることができ、テキスト形式の一致を心配する必要がないため、この方法は回帰テストに優れているようです。この戦略は、WolfgangBangerthとandybauerが提案しているものと多かれ少なかれだと思いました。また、PETScは、一部のテストで同様のアプローチを使用しているようです。
  • 単体テストフレームワークを使用して、MPIランク0のプロセッサにすべてを収集し、プロセッサランクが0の場合にのみ単体テストを実行するように依頼します。標準で同様のことができます(おそらく、その方が簡単です)返されたエラーは、計算に問題があることを示しますが、どの要素にエラーがあるかはわかりません。そうすれば、ユニットテストの出力が文字化けすることを心配する必要はありません。単体テストフレームワークを正しく呼び出すことだけを心配する必要があります。PETScは、正確なソリューションが利用可能な場合、サンプルプログラム内で標準的な比較を使用するように見えますが、それらの比較を行うときにユニットテストフレームワークを使用しません(必ずしもそうする必要はありません)。

私は社内のテストスイートにしか精通していないため、何もお勧めできません。そうは言っても、これらのテストスイートでは、作成した実行可能ファイルの実行方法を指定することはできませんか?そうした場合、MPIプログラムで機能するテストを作成するのは簡単なはずです。
ビル・バルト

彼らはすべき。コンパイルされた言語では、それは単なる実行可能ファイルであるため、実行に使用mpiexecしても問題ありません。また、PETScInitialize/のような呼び出しをPETScFinalizesetup / teardownコードに含めます。(おそらく、PETScを使用していなかった場合、使用しているライブラリに応じて、これらの呼び出しをMPI_Init/の類似物に置き換えますMPI_Finalize。)Googleのテストフレームワークはソースベースのリリースであるため、コードと共にコンパイルします書き込みも問題になりません。
ジェフオックスベリー

問題の説明は、統合/回帰テストを実行するために単体テストフレームワークを使用することに興味があることを示唆しています。それ自体に問題はありませんが、質問をもう少し明確にしたいかもしれません。ユニットテストの専門家に科学コードのユニットテストの書き方を尋ねたら、モジュール方式でテストを書くように言われると思います。つまり、ほとんどのテストには適切なMPI呼び出しが含まれていません。
アロンアフマディア

もっと具体的にさせてください。少数のプロセッサ(たとえば、1〜4)を使用した小さな問題でテストしたいことは、組み立てられたヤコビ行列が実際に適切なグローバルヤコビ行列になるかどうかです。また、既知のグローバルな右側に対して右側の機能をテストしたいと思います。各そのようなテストはまだのみ(試験、例えば、PETScアプリケーションに単一の機能を発揮すべきであるRHSFunctionRHSJacobian${PETSC_DIR}/src/ts/examples/tutorials/ex.2分離して)。
ジェフオックスベリー

私は、あなたが望むことをするのを助けるフレームワークが現在存在するとは思わない。PyClawで鼻を絞っていくつかのことをすることができました(そしてLisandroはmpi4pyとpetsc4pyでそれを使用しました)。mpichのテストフレームワークを見ましたか?
アロンアーマディア

回答:


8

私は、CMake / CTestビルド環境でC ++ MPIコードを使用するGoogleTestの幸せなユーザーです。

  • CMakeはsvnからgoogletestを自動的にインストール/リンクします!
  • テストの追加はワンライナーです!
  • テストの作成は簡単です!(そして、Googleモックは非常に強力です!)
  • CTestはコマンドラインパラメータをテストに渡し、データをCDashにエクスポートできます!

これがその仕組みです。mpiを必要とする単体テストのバッチは、my_mpi_test.cpp次のようなファイルに書き込まれます。

#include <gtest/gtest.h>
#include <boost/mpi.h>

/// Most testing libraries allow to define main yourself to override initialization.
int main(int argc, char* argv[]) {
    ::testing::InitGoogleTest(&argc, argv);  /// Set gtest environment
    mpi::environment env(argc, argv);  /// Set mpi environment
    return RUN_ALL_TESTS();  /// Execute all gtest tests
}

TEST(test_batch_name, test_name) {  /// Then you can create tests as usual,
  using namespace mpi;
  communicator world;  /// and use MPI inside your tests.
  /* ... test stuff here ... */
}

このテストを追加するCMakeLists.txtは次のとおりです。

add_mpi_test(my_mpi 2)  # Uses 2 MPI processes

どこ add_mpi_test CMakeの者を包み込みadd_test、私のルートCMakeLists.txt内側:

function(add_mpi_test name no_mpi_proc)
  include_directories(${MY_TESTING_INCLUDES})
      # My test are all called name_test.cpp
      add_executable(${name} ${name}_test.cpp)
      add_dependencies(${name} googletest)
  # Make sure to link MPI here too:
  target_link_libraries(${name} ${MY_TESTING_LIBS})
  set(test_parameters ${MPIEXEC_NUMPROC_FLAG} ${no_mpi_proc} "./${name}")
      add_test(NAME ${name} COMMAND ${MPIEXEC} ${test_parameters})
endfunction(add_mpi_test)

この最後の部分は必須ではありませんが、mpiテストを1行で簡単に追加できます。次に、各テストのMPIプロセスの数をハードコーディングするか、コマンドラインパラメーターを介してctestに読み込むかを決定できます。


4

を使用するいくつかのMPI対応ソフトウェアパッケージがあります。 テストにCMakeのツールセットます。頭の中で思い浮かぶのは、Trilinos、VTK、ParaViewです。実行可能ファイルをmpirunやmpiexecで起動する必要があると思いたくないと思います。CMakeは、使用するプロセスの最大数、必要に応じて事前フラグと事後フラグなどのさまざまなオプションとともに、実行可能ファイルを適切に起動する方法を指定するサポートを備えています。

ParaViewダッシュボードの HPCサイトセクションをご覧ください。さまざまなNERSCおよびArgonneスーパーコンピューターでテストが実行されるをご覧ください。また、これらのマシンで機能させるために指定する必要がある設定のほとんどが埋まっています。

参考のため、Trilinosダッシュボードには多種多様なパッケージが一覧表示されており、私にとってはその組織でかなり印象的です。

完全な開示:私はキットウェアの従業員であり、CMakeはキットウェアが関与するオープンソースプロジェクトの1つです。


答えてくれてありがとう!私はCTestを見てきましたが、KitWareのWebサイトにあるマンページのような説明以外のドキュメントはありません。自由に利用できるチュートリアルをお勧めできますか?
ジェフオックスベリー

CMake wikiにはたくさんの情報があります。CMake、CTest、CPackのチュートリアルがたくさんあります。Stack Overflowでこれらのアプリケーションに対する私の答えのほとんどを見つけました。
アンディバウアー

andybauer-答えてくれてありがとう。回答を編集して、KitWareとの関係を開示してもよろしいですか?
アロン

3

独自のコードを取り引きするだけです。II-基本的に、フレームワークにを使用してテストを実行するように指示しmpirun -np ...ます。以前、Makefileベースのテストスキーム(コンパイル、リンク、テストの実行、出力を以前に保存したものと比較する)を使用したばかりで、次の場所にあります。

コンテキストについては、非MPIターゲットは次のとおりです。

CMake / CTestを使用して物事を書き直しており、現在の開発状況は次のとおりです。


ウルフギャング、答えてくれてありがとう!PETScも同様のことをしているようです。
ジェフオックスベリー

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.