私は現在、MPJ-Express (Java MPI バリアント) を使用して、マルチプロセスの並列アルゴリズム用の Scala フレームワークを開発しています。
MPJ-Express、および基本的にすべての MPI バリアントは、同じプログラムで多くのプロセスを開始することによって機能します。実行時にプロセスを制御できないため (私のプログラムはプロセスを生成しません)、次の理由により、標準の単体テスト フレームワークを使用できません。
すべてのプロセスが実行後に結果のローカル コピーを所有するわけではありません (理想的には、結果は任意のルート プロセスで収集する必要があります)。
標準出力に対する制御の欠如。単一のプロセスからのみ出力を取得することは容易ではありません。
- フロー制御の欠如。単一プログラムの複数データ アルゴリズムを許可するには、すべてのプロセスが同時に同じテストに入る必要があります。
番号 2 が主な問題です。番号 3 は期待どおりに機能する可能性があり、番号 1 は追加の通信操作で修正できます。誰かが実際の経験を持っているか、マルチプロセスアルゴリズムのより良い単体テスト戦略を知っていますか?
編集
現在、 scalacheckを使用して次のコードを実行できているようです。
package it.vigtig.thesis.collection.scalacheck
import java.io.OutputStream
import java.io.PrintStream
import org.scalacheck.Prop.forAll
import org.scalacheck.Properties
import it.vigtig.thesis.env.DistEnv.globalRank
import it.vigtig.thesis.env.DistEnv.parallelize
object CollectionCheck {
def main(args: Array[String]) {
parallelize(args) {
if (globalRank > 0) {
Console.setOut(new PrintStream(new OutputStream() {
def write(b: Int) { //nop
}
}))
}
ST.main(Array())
}
}
}
object ST extends Properties("String") {
// def println(a: String*) = gprintln(a)
property("startsWith") = forAll((a: String, b: String) => (a + b).startsWith(a))
property("concatenate") = forAll((a: String, b: String) =>
(a + b).length > a.length && (a + b).length > b.length)
property("substring") = forAll((a: String, b: String, c: String) =>
(a + b + c).substring(a.length, a.length + b.length) == b)
}
上記のコードは、scala-println メソッドを p=0 以外のすべてのプロセスの nop 操作に再ルーティングします。ルート プロセスのみが結果を検証できるように、並列メソッドを使用してテスト スイートを実行できるはずです。上記により、次の出力が得られます。
MPJ Express (0.38) is started in the multicore configuration
rank-0: 0.212437745 time taken for initialize
+ String.startsWith: OK, passed 100 tests.
! String.concatenate: Falsified after 0 passed tests.
> ARG_0:
> ARG_1:
+ String.substring: OK, passed 100 tests.