1

2つの行列を変更する並列for-eachループを構築しようとしています。ループを開始する前に、マトリックスを作成して初期化します。これは私のコードがどのように機能するかを示すダミープログラムです。プログラムはエラーなしで実行されますが、foreachループが終了した後も行列は空のままです。注:これは私のコードの簡略版であり、実際のコード自体ではありません。

#Assume that I've loaded parallel and doParallel and that my computer has 2+ cores 
cluster <- makeCluster(detectCores())
registerDoParallel(cluster)
a1 <- array(dim=c(9,9))
a2 <- array(dim=c(9,9))
numbers <- 1:18
foreach (i=1:9, .combine='c') %dopar%{
    a1[i,] = numbers[1:9]
    a2[i,] = numbers[10:18]
}
stopCluster(cluster)

このプログラムがa1とa2の行にデータを入力しないのはなぜですか?

編集:以前のスレッドで私の質問に対する答えを見つけることができませんでした。C#とPerlにも同様のスレッドがありますが、Rに関係するスレッドはありません。

4

2 に答える 2

4

foreachを使用してこの種の副作用を実行することはできません。ループ内の割り当てはワーカープロセスで行われ、意図的にマスターに返送されません。戻り値に対してforeachを実行するため、2つの行列を生成する場合、foreachは2つの行列のリストを返す必要があります。

次に、combine関数を使用して、ワーカーによって生成された行のリストから複数の行列を作成する例を示します。

rcomb <- function(...) {
  args <- list(...)
  lapply(seq_along(args[[1]]), function(i)
         do.call('rbind', lapply(args, function(a) a[[i]])))
}

numbers <- 1:18
m <- foreach (i=1:9, .combine='rcomb', .multicombine=TRUE) %dopar% {
    list(numbers[1:9], numbers[10:18])
}

やや複雑ですがrcomb、任意の数の行列を処理でき、効率上の理由から重要な多くのタスク結果で呼び出すことができます。

于 2013-03-12T19:03:04.923 に答える
0

多分これは役立ちます。テストできませんでした。バグはご容赦ください。

 require(snowfall)

sfInit(cpus=2,parallel=TRUE)

a1 <- matrix(NA,ncol=9,nrow=0)
a2 <- matrix(NA,ncol=9,nrow=0)
numbers <- 1:18

a1 = rbind(a1,sfSapply(1:9,function(x) return(numbers[1:9]), numbers))
a2 = rbind(a2,sfSapply(1:9,function(x) return(numbers[10:18]), numbers))

sfStop()
于 2013-02-15T21:03:35.413 に答える