combine関数でタスクを実行するには、foreachループの本体から返される結果オブジェクトに余分な情報を含める必要があります。この場合、エラーフラグとなり、値はi
になります。そこにこれを行うには多くの方法がありますが、ここでの例です:
すべてのタスクが計算されるまで、私は何度並列ループを実行することでこの問題に対処するために誘惑されると思います
comb <- function(results, x) {
i <- x$i
result <- x$result
if (x$error) {
cat(sprintf('master computing failed task %d\n', i))
# Could call function repeatedly until it succeeds,
# but that could hang the master
result <- try(fails_randomly(i))
}
results[i] <- list(result) # guard against a NULL result
results
}
r <- foreach(i=1:100, .combine='comb',
.init=vector('list', 100)) %dopar% {
tryCatch({
list(error=FALSE, i=i, result=fails_randomly(i))
},
error=function(e) {
list(error=TRUE, i=i, result=e)
})
}
:
x <- rnorm(100)
results <- lapply(x, function(i) simpleError(''))
# Might want to put a limit on the number of retries
repeat {
ix <- which(sapply(results, function(x) inherits(x, 'error')))
if (length(ix) == 0)
break
cat(sprintf('computing tasks %s\n', paste(ix, collapse=',')))
r <- foreach(i=x[ix], .errorhandling='pass') %dopar% {
fails_randomly(i)
}
results[ix] <- r
}
このソリューションでは、エラーが発生した場合に非常に便利な.errorhandling
オプションを使用しています。このオプションの詳細については、foreachのマニュアルページを参照してください。
ありがとうございました!なぜあなたは、タスク全体が計算されるまで並列ループを繰り返すように誘惑されているのか説明してください。エラーが毎回異なる反復で発生するため、この方法がより簡単で高速になると思いますか? – Llopis
@Llopisそれはすべてあなたの特定の問題に依存します。マスターでエラーが発生しない場合は、おそらくあなたのアプローチは良いでしょう。それがマスターで起こる可能性が高いのであれば、それはより速くなるので、ワーカーを使うこともできます。フォールトトレラントなプログラムを作成するのは難しいかもしれないので、いくつかの異なるアプローチについて考えてみると便利です。 –
私はエラーの原因を理解していないので、推測するのは難しいですが、代替案を提供してくれてありがとう – Llopis