2

我正在为人口 MCMC 编写代码。我会尽量提供我认为有帮助的信息,所以请多多包涵。

我正在使用缓和分布,我想执行交换动作,即提议交换两条链的价值的动作。

我做了什么(交换发生在主人身上)

我最初是由

  • 让每条链在指定的迭代次数 n 内发生变异。

  • 在每第 n 次迭代中,我会将从站的结果发送给主站,并尝试在链之间交换参数。

  • 然后将更新的值发送回从站并重复该过程。

我要达到的目的(从机之间直接交换)

这工作正常,但我想清理我的代码并删除 master 和 slave 之间不必要的通信。也就是让slave之间直接通信。

所以假设我要生成 10 个奴隶,

  • 在迭代 n 时,我想让 slave1-slave2、slave3-slave4、....、slave9-slave10 在它们之间进行通信
  • 在迭代 2*n 时,我想让 slave2-slave3、slave4-slave5、...slave8-slave9 在它们之间进行通信

等等,这样我就让样品通过温度阶梯。

问题

这就是我面临的问题。
我想我正在设法将一个值从一个奴隶发送到另一个(我的打印语句“成功发送”被打印在正在发送的奴隶的日志文件中)但这似乎没有被接收到(我的“成功接收”语句不会打印在伙伴从属设备的日志中)。

程序只是挂起。我想也许我造成了僵局,但我不确定我做错了什么?

您能否提一些建议?我已将此 Parallel Tempering R 代码用作指南 http://www.lindonslog.com/mathematics/parallel-tempering-r-rmpi/

请看下面我的代码

非常感谢!

苏菲亚

ind <- mpi.comm.rank()
oddFlag<-0   ### object to flag code suitable for odd/even numbered slaves.

for  (i in  1:TotalIter)  {
##### normal MCMC move (single chain mutation) -  logL.current

 if ( i%%exchangeInterval == 0 ){   ### every nth (right now 5th) iteration, attempt an exchange  

message("\n\nAttempt an exchange move")
oddFlag<-oddFlag+1     
exchange<-0
logL.partner<-0

  if (ind%%2 == oddFlag%%2) {  ###when oddFlag even , the following code concerns even-numbered slaves. When odd number, it concerns odd-numbered slaves.                                                  
  ind.partner<-ind+1

  if (0<ind.partner && ind.partner<(noChains+1)){
    message("This is the slave: ", ind, " and its partner is: ", ind.partner)
    message("The tag for receiving logL.partner is: ", ind.partner)          
    logL.partner<-mpi.recv.Robj(source=ind.partner,tag=ind.partner)  #### receive the logL of partner                    
    message("Succesfully received")
    message("This is the logL.partner: ", logL.partner)
    exchanges.attempted<-exchanges.attempted+1

    if (runif(1)< min(1, exp((logL.partner - estimatorSelf)*(temper[ind] - temper[ind.partner] )))) {    ############# exp((chain2 - chain1)*(T1 - T2))                                          
      message("I exchanged the values")
      exchange<-1
      print(exchange)
      exchanges.accepted<-exchanges.accepted+1
    }
    mpi.send.Robj(obj=exchange,dest=ind.partner,tag=15*ind)
  }

  if (exchange==1){
### exchange parameters  with mpi.send.Robj/mpi.recv.Robj functions
  }

} else {  ##### ###when oddFlag even , the following code concerns odd-numbered slaves. For oddFlag odd, it concerns even-numbered slaves.                              
  ind.partner<-ind-1

  if (0<ind.partner && ind.partner<(noChains+1)){
    message("This is the slave: ", ind, " and its partner is: ", ind.partner)
    message("The tag for sending logL.current is: ", ind)
    mpi.send.Robj(obj=logL.current,dest=ind.partner,tag=ind)  ### send logL to partner
    message("Succesfully sent")

    exchange<-mpi.recv.Robj(source=ind.partner, tag=15*ind.partner)
    message("I received the exchange message")
  }

  if (exchange==1){
 ### exchange parameters send/receive functions
   }
  }
 }
}
4

1 回答 1

0

这似乎很奇怪。据我所知,发送和接收命令是锁定的,因此发送工作没有接收工作让我觉得有点奇怪。您是否尝试过指南上的代码?如果您愿意,我可以将整个 R 代码发送给您,以查看它是否适用于您的系统。如果指南上的代码有效,那么您可以放心地说这不是您的 MPI 设置的问题。

您可能会尝试的一件事是接收命令而不是使用 ind.partner 您可以使用 mpi.any.source() (我认为是正确的),它将接受任何标签的消息。如果这解决了您的僵局,则可能是标签有问题(但从我看来,这似乎没有什么问题)。

您可能会尝试的另一件事是删除接收命令上的“source=”和“tag=”。我注意到在我的代码中我没有任何发送命令。也许这也给我带来了麻烦,但我不太记得了。让我知道进展如何,我希望一切顺利。

于 2013-11-07T02:42:01.887 回答