2

母集団 MCMC のコードを書いています。参考になればと思いますので、少しでもお役に立てればと思いますので、よろしくお願いいたします。

私は緩和されたディストリビューションを使用しており、交換の移動、つまり 2 つのチェーンの値を交換することを提案する移動を実行したいと考えています。

私がやったこと(マスターで起こっている交換)

私は最初にこれを書いた

  • 指定された反復回数 n の間、各チェーンを変化させます。

  • n回目の反復ごとに、スレーブの結果をマスターに送信し、チェーン間でパラメーターの交換を試みます。

  • 次に、更新された値をスレーブに送り返し、プロセスを繰り返します。

私が達成したいこと(スレーブ間の直接交換)

これは正常に動作していますが、コードをクリーンアップして master と 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 の設定に問題はないと言えます。

あなたが試みるかもしれないことの1つは、ind.partnerを使用する代わりに受信コマンドに対して、任意のタグのメッセージを受け入れる mpi.any.source() (正しいものだと思います) を使用することです。これでデッドロックが解決する場合は、タグに問題がある可能性があります (しかし、私には何も問題がないように見えます)。

別の方法として、受信コマンドの「source=」と「tag=」を削除することもできます。送信コマンドを実行している間、コードに何もないことに気付きました。おそらくそれが私にも問題を引き起こしていたのでしょうが、よく覚えていません。それがどうなるか教えてください、すべてがうまくいくことを願っています。

于 2013-11-07T02:42:01.887 に答える