如何为多核处理重写我的R代码?
我有R代码,我需要进入“并行化”阶段。我在这方面是新手,所以如果我使用了错误的术语,请原谅我。我有一个过程,就是一个一个的,一个一个的,然后最后平均每个人。这个过程对于每个个体来说都是完全相同的(这是一个布朗桥),我只需要对>300个个体做这个。所以,我希望这里的人可能知道如何更改我的代码,以便生成代码?还是并行化?或者,不管用什么词来确保我现在可以访问的48个CPU可以帮助减少用我的小笔记本电脑计算这个数据所需的58天。在我的头脑中,我只会将一个人发送给一个处理器。让它在脚本中运行,然后发送另一个…如果有意义的话 下面是我的代码。我已经试着在里面发表评论,并指出了我认为代码需要修改的地方如何为多核处理重写我的R代码?,r,format,multicore,spawn,R,Format,Multicore,Spawn,我有R代码,我需要进入“并行化”阶段。我在这方面是新手,所以如果我使用了错误的术语,请原谅我。我有一个过程,就是一个一个的,一个一个的,然后最后平均每个人。这个过程对于每个个体来说都是完全相同的(这是一个布朗桥),我只需要对>300个个体做这个。所以,我希望这里的人可能知道如何更改我的代码,以便生成代码?还是并行化?或者,不管用什么词来确保我现在可以访问的48个CPU可以帮助减少用我的小笔记本电脑计算这个数据所需的58天。在我的头脑中,我只会将一个人发送给一个处理器。让它在脚本中运行,然后发送另
for (n in 1:(length(IDNames))){ #THIS PROCESSES THROUGH EACH INDIVIDUAL
#THIS FIRST PART IS JUST EXTRACTING THE DATA FROM MY TWO INPUT FILES.
#I HAVE ONE FILE WITH ALL THE LOCATIONS AND THEN ANOTHER FILE WITH A DATE RANGE.
#EACH INDIVIDUAL HAS DIFFERENT DATE RANGES, THUS IT HAS TO PULL OUT EACH INDIVIDUALS
#DATA SET SEPARATELY AND THEN RUN THE FUNCTION ON IT.
IndivData = MovData[MovData$ID==IDNames[n],]
IndivData = IndivData[1:(nrow(IndivData)-1),]
if (UseTimeWindow==T){
IndivDates = dates[dates$ID==IDNames[n],]
IndivData = IndivData[IndivData$DateTime>IndivDates$Start[1]&IndivData$DateTime<IndivDates$End[1],]
}
IndivData$TimeDif[nrow(IndivData)]=NA
########################
#THIS IS THE PROCESS WHERE I THINK I NEED THAT HAS TO HAVE EACH INDIVIDUAL RUN THROUGH IT
BBMM <- brownian.bridge(x=IndivData$x, y=IndivData$y,
time.lag = IndivData$TimeDif[1:(nrow(IndivData)-1)], location.error=20,
area.grid = Grid, time.step = 0.1)
#############################
# BELOW IS JUST CODE TO BIND THE RESULTS INTO A GRID DATA FRAME I ALREADY CREATED.
#I DO NOT UNDERSTAND HOW THE MULTICORE PROCESSED CODE WOULD JOIN THE DATA BACK
#WHICH IS WHY IVE INCLUDED THIS PART OF THE CODE.
if(n==1){ #creating a data fram with the x, y, and probabilities for the first individual
BBMMProbGrid = as.data.frame(1:length(BBMM[[2]]))
BBMMProbGrid = cbind(BBMMProbGrid,BBMM[[2]],BBMM[[3]],BBMM[[4]])
colnames(BBMMProbGrid)=c("GrdId","X","Y",paste(IDNames[n],"_Prob", sep=""))
} else { #For every other individual just add the new information to the dataframe
BBMMProbGrid = cbind(BBMMProbGrid,BBMM[[4]])
colnames(BBMMProbGrid)[n*2+2]=paste(IDNames[n],"_Prob", sep ="")
}# end if
} #end loop through individuals
for(nin1:(length(IDNames)){#这个过程通过每个个体进行
#第一部分只是从我的两个输入文件中提取数据。
#我有一个包含所有位置的文件,然后是另一个包含日期范围的文件。
#每个人都有不同的日期范围,因此它必须把每个人都抽出来
#单独设置数据集,然后在其上运行函数。
IndivData=MovData[MovData$ID==IDNames[n],]
IndivData=IndivData[1:(nrow(IndivData)-1),]
如果(UseTimeWindow==T){
IndivDates=dates[dates$ID==IDNames[n],]
IndivData=IndivData[IndivData$DateTime>IndivDates$Start[1]&IndivData$DateTime也不知道为什么会被否决。我认为该软件包就是您想要的。前几个PDF中有非常清楚的有用信息。基本上,将您希望为每个人做的事情作为一个函数写入。然后使用foreach将一个人的数据发送到一个节点以运行该函数(在将另一个人发送到另一个节点等时)然后使用rbind之类的工具编译所有结果。我已经使用过几次了,结果非常好
编辑:我不想重做你的代码,因为我认为如果你已经做到了这一点,你将很容易掌握将代码包装成函数,然后使用一行代码的技巧
编辑2:评论太长,无法回复您
我认为,既然您已经对代码有了很大的了解,那么您就可以将其放入函数中:)如果您仍在研究这个问题,可以考虑在主题上编写一个for循环来循环,并进行该主题所需的计算。然后,这个for循环就是您想要在函数中实现的。我认为在您的代码中,这就是“area.grid”的全部内容。然后您可以去掉大部分[n]因为数据在每次迭代中仅是一个子集
也许:
pernode <- function(MovData) {
IndivData = MovData[MovData$ID==IDNames[i],]
IndivData = IndivData[1:(nrow(IndivData)-1),]
if (UseTimeWindow==T){
IndivDates = dates[dates$ID==IDNames,]
IndivData = IndivData[IndivData$DateTime>IndivDates$Start[1]
&IndivData$DateTime<IndivDates$End[1],]
}
IndivData$TimeDif[nrow(IndivData)]=NA
BBMM <- brownian.bridge(x=IndivData$x, y=IndivData$y,
time.lag = IndivData$TimeDif[1:(nrow(IndivData)-1)], location.error=20,
area.grid = Grid, time.step = 0.1)
return(BBMM)
}
pernode指示$Start[1]
&IndivData$DateTime这是一个普通的例子,因为我没有耐心阅读您的所有代码。在多个处理器之间传播此信息的最快方法之一是使用multicore
库和McLappy
(并行版本的Lappy
)推送列表(列表中的单个项目将是您案例中300多个个体中的每个个体的数据帧)通过一个函数
例如:
library(multicore)
result=mclapply(data_list, your_function,mc.preschedule=FALSE, mc.set.seed=FALSE)
据我所知,您可以访问分布式计算机群集。因此包multicore将不起作用。您必须使用Rmpi、snow或foreach。根据您现有的循环结构,我建议您使用foreach和doSnow包。但是您的代码看起来像是有很多数据。您可能必须检查到reduce数据(仅限所需数据)这将被发送到节点。我不知道有人投了-1票,但我怀疑是因为你的代码太复杂了——人们要花很长时间来筛选它。你能给我们一个只有10-20行的简化版本,仍然有完整的R语法,但给出了你想要做什么的想法吗?另外,你能告诉我们一个简单的例子吗ttle关于您的计算设置的更多信息——多核、紧密耦合的机器……?您想到了什么方法(请参阅上的高性能任务视图)附议Brian。不要让我们做你所有的工作。只要告诉我们你需要并行化的步骤,我们就可以帮你。哦,我是想输入Ben。对不起!另请参阅关于@Joris Meys的指南-谢谢你,这是一个很好的链接,对于像我这样一直在努力写问题以获得最佳帮助的人来说。我将标记该讨论以供将来参考,并希望我能改进,以便充分利用这一点community@nezcoops-啊,兄弟,你对我很有信心,认为我掌握了正确的技能!谢谢。使用其他人的剧本和例子来制作我目前掌握的东西是一场斗争。但是,我会坚持下去。我从来没有这样做过r使用了lappy命令,这是我第一次听说foreach。在注释字段中我用光了空间,扩展了答案。谢谢你的建议,我已经将代码缩减到我认为可以解析到各个处理器的部分。代码中只有一个主要功能(brownian.bridge命令)。这是需要为我的数据集中的每个人计算的。我从IF语句开始,将结果绑定到一个网格中。我假设这不需要发送到集群,但我不明白流程如何知道从所有不同的处理器返回并连接在一起。例如循环在R中效率低下。使用plyr将每个个体的数据放入一个列表中。例如:个体=dlply(原始_数据,.(IDNames))。接下来,创建一个包装函数(一次将一个列表项传递给该函数)这包括bbbm函数和格式化结果。因此,当多核运行时,它将同时执行这两项操作并返回单个项目所在的列表
library(multicore)
result=mclapply(data_list, your_function,mc.preschedule=FALSE, mc.set.seed=FALSE)