我目前正在使用 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.