如何为多核处理重写我的R代码?

如何为多核处理重写我的R代码?,r,format,multicore,spawn,R,Format,Multicore,Spawn,我有R代码,我需要进入“并行化”阶段。我在这方面是新手,所以如果我使用了错误的术语,请原谅我。我有一个过程,就是一个一个的,一个一个的,然后最后平均每个人。这个过程对于每个个体来说都是完全相同的(这是一个布朗桥),我只需要对>300个个体做这个。所以,我希望这里的人可能知道如何更改我的代码,以便生成代码?还是并行化?或者,不管用什么词来确保我现在可以访问的48个CPU可以帮助减少用我的小笔记本电脑计算这个数据所需的58天。在我的头脑中,我只会将一个人发送给一个处理器。让它在脚本中运行,然后发送另

我有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)