这在我的电脑上正常运行:
registerDoSNOW(makeCluster(2, type = "SOCK"))
foreach(i = 1:M,.combine = "c") %dopar% {
sum(rnorm(M))
}
所以我可以说我可以在这台计算机上运行并行化代码,对吗?
确定。我有一段代码,我希望与 foreach 并行运行。它用%do%写的时候运行得很好,但是当我把它改成%dopar%时它不能正常工作。 (PS:我已经使用registerDoSNOW(makeCluster(2, type = "SOCK"))
以与以前相同的方式初始化了群集。)
我对代码的主要兴趣是获取向量 u.varpred 。我很好地使用%do%,但是当我用%dopar%运行它时,向量变为NULL。
这是一个循环,其中包含正确运行所需的代码。它使用 geoR 包中的函数。
#you can pretty much ignore all this, it's just preparation for the loop
N=20
NN=10
set.seed(111);
datap <- grf(N, cov.pars=c(20, 5),nug=1)
grid.o <- expand.grid(seq(0, 1, l=100), seq(0, 1, l=100))
grid.c <- expand.grid(seq(0, 1, l=NN), seq(0,1, l=NN))
beta1=mean(datap$data)
emv<- likfit(datap, ini=c(10,0.4), nug=1)
krieging <- krige.conv(datap, loc=grid.o,
krige=krige.control(type.krige="SK", trend.d="cte",
beta =beta1, cov.pars=emv$cov.pars))
names(grid.c) = names(as.data.frame(datap$coords))
list.geodatas<-list()
valores<-c(datap$data,0)
list.dataframes<-list()
list.krigings<-list(); i=0; u.varpred=NULL;
#here is the foreach code
t<-proc.time()
foreach(i=1:length(grid.c[,1]), .packages='geoR') %do% {
list.dataframes[[i]] <- rbind(datap$coords,grid.c[i,]);
list.geodatas[[i]] <- as.geodata(data.frame(cbind(list.dataframes[[i]],valores)))
list.krigings[[i]] <- krige.conv(list.geodatas[[i]], loc=grid.o,
krige=krige.control(type.krige="SK", trend.d="cte",
beta =beta1, cov.pars=emv$cov.pars));
u.varpred[i] <- mean(krieging$krige.var - list.krigings[[i]]$krige.var)
list.dataframes[[i]]<-0 #i dont need those objects anymore but since they
# are lists i dont want to put <-NULL as it'll ruin their ordering
list.krigings[[i]]<- 0
list.geodatas[[i]] <-0
}
t<-proc.time()-t
t
您可以检查这是否运行良好(前提是您有以下软件包: geoR , foreach 和 doSNOW )。但是,一旦我使用registerDoSNOW(......)
和%dopar%
, u.varpred 就会显示为NULL。
你们可以试着看看我是否在foreach声明/过程中犯了错误,或者它是否只是不能并行的代码? (我认为可以,因为任何给定的迭代都不会在它之前的任何迭代上降低..)
我很抱歉代码和这个问题都很长。提前感谢您花时间阅读它。
答案 0 :(得分:2)
我的朋友直接帮助了我。这是一种有效的方式:
u.varpred <- foreach(i = 1:length(grid.c[,1]), .packages = 'geoR', .combine = "c") %dopar% {
list.dataframes[[i]] <- rbind(datap$coords,grid.c[i,]);
list.geodatas[[i]] <- as.geodata(data.frame(cbind(list.dataframes[[i]],valores)));
list.krigings[[i]] <- krige.conv(list.geodatas[[i]], loc = grid.o,
krige = krige.control(type.krige = "SK", trend.d = "cte",
beta = beta1, cov.pars = emv$cov.pars));
u.varpred <- mean(krieging$krige.var - list.krigings[[i]]$krige.var);
list.dataframes[[i]] <- 0;
list.krigings[[i]] <- 0;
list.geodatas[[i]] <- 0;
u.varpred #this makes the results go into u.varpred
}
他举了一个例子说明了为什么会这样:
a <- NULL
foreach(i = 1:10) %dopar% {
a <- 5
}
print(a)
# a is still NULL
a <- NULL
a <- foreach(i = 1:10) %dopar% {
a <- 5
a
}
print(a)
#now it works
希望这有助于任何人。