我目前正在开发一个使用MPJ-Express(即Java MPI变体)的多进程并行算法的Scala框架。Scalacheck,单元测试多进程算法
MPJ-Express,基本上所有的MPI变体都通过使用相同程序启动许多进程来工作。由于我有过在运行时(我的程序不会产生进程)的过程没有控制,我不能因下列原因使用标准的单元测试框架:
并非所有的进程将自己的本地副本执行后的结果(理想情况下,结果应该在任意根进程中收集)
缺乏对标准输出的控制。仅从单个进程获得输出是不容易的。
- 缺乏流量控制。所有进程必须同时进入相同的测试以允许单程序多数据算法。
2号主要是这个问题,因为3可能按预期工作,1可以通过额外的通信操作来修复。有没有人有实际经验,或知道更好的多进程算法单元测试策略?
EDIT
现在,我似乎使用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)
}
上面的代码重新路由阶-的println方法的NOP操作对于除p = 0之外的所有其他进程。我应该能够使用并行方法运行测试套件,只允许根进程验证结果。上述产生以下输出:
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.
每当我调用属性内的MPI方法时,我会死锁。使用一个简单的mpi-barrier可以在属性之外完美工作,并且我可以验证所有进程都在调用该方法,但是只要在属性主体内部使用MPI调用,就会陷入死锁。任何帮助将会非常受欢迎:) – Felix
仅在基于其等级的条件语句内执行标准I/O是在MPI编程中执行I/O的标准事实标准方法。 –
https://github.com/rickynils/scalacheck/issues/37 显然,这是由于scalacheck中的一种错误。我可能会关闭这个话题:/ – Felix