2016-11-24 8 views
5

私は並行して処理したいのですが、私はstrange errorのために失敗します。今、私は結合し、マスターCPU上で失敗したタスクを計算することを検討しています。しかし、私はそのような関数を.combineのために書く方法を知らない。foreachの.combineのための関数を構築する

どのように書きますか?

私はそれらを書く方法を知っています。たとえば、this答えが例ですが、失敗したタスクを処理する方法や、マスター上のタスクを繰り返す方法は提供していません。

私のようなものだろう:(それを行うことができる場合)しかし、どのように私は.combine機能で、そのタスクの入力を使用しない

foreach(i=1:100, .combine = function(x, y){tryCatch(?)} %dopar% { 
    long_process_which_fails_randomly(i) 
} 

を?または、%dopar%の中にフラグやリストを返すように指定する必要がありますか?

答えて

2

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のマニュアルページを参照してください。

+0

ありがとうございました!なぜあなたは、タスク全体が計算されるまで並列ループを繰り返すように誘惑されているのか説明してください。エラーが毎回異なる反復で発生するため、この方法がより簡単で高速になると思いますか? – Llopis

+0

@Llopisそれはすべてあなたの特定の問題に依存します。マスターでエラーが発生しない場合は、おそらくあなたのアプローチは良いでしょう。それがマスターで起こる可能性が高いのであれば、それはより速くなるので、ワーカーを使うこともできます。フォールトトレラントなプログラムを作成するのは難しいかもしれないので、いくつかの異なるアプローチについて考えてみると便利です。 –

+0

私はエラーの原因を理解していないので、推測するのは難しいですが、代替案を提供してくれてありがとう – Llopis

関連する問題