1

次のような MPI C コードがあります。

for(i=0;i<NTask;i++)
{
  got_initial_bit_of_data[i]=0;
  if(need_to_communicate with i)
     MPI_ISend(&bit_of_pre_data_for_i,1,MPI_INT,partner,0,MPI_COMM_WORLD,&pre_requests[i]);
}
while(1)
{
  MPI_Testsome(NTask,pre_requests,&ndone,idxs,MPI_STATUSES_IGNORE)
  if(ndone)
  {
    for(i=0;i<ndone;i++)
    {
      MPI_ISend(&the_main_block_of_data_for_i,size_of_block,MPI_BYTE,idxs[i],1,MPI_COMM_WORLD,&main_requests[idxs[i]]);
    }
  }
  //Other stuff that doesn't matter
  MPI_IProbe(MPI_ANY_SOURCE,0,MPI_COMM_WORLD,&flag,&status);
  if(!flag)
  {
    MPI_IProbe(MPI_ANY_SOURCE,1,MPI_COMM_WORLD,&flag,&status);
  }
  if(flag)
  {
    //Receiving the initial little bit of data
    if(status.MPI_TAG==0)
    {
      //Location 1
      got_initial_bit_of_data[status.MPI_SOURCE]=1;
      MPI_Recv(&useful_location,1,MPI_INT,status.MPI_SOURCE,MPI_STATUS_IGNORE);
    }
    //Receiving the main bit of data
    else if(status.MPI_TAG==1)
    {
      //Location 2
      if(got_initial_bit_of_data[status.MPI_SOURCE]!=1)
        //Something has gone horribly wrong...
      //Receive the main bit of data here...
    }
  }
}

完全なコードは数百行の長さであるため、明らかに多くの詳細を省略しています。私が行ったことが少し奇妙に見える場合、それはおそらく、省略されたコード ブロック内の何かが原因である可能性があります。

アイデアは、最初に各プロセッサが「アナウンスメント」メッセージを通信したいプロセッサに送信するというものです。これらのプロセッサがこのメッセージを受信したことを検出すると (つまり、MPI_Testsome が「アナウンスメント」MPI_Isend が完了したことを示したとき)、大量のデータを送信する必要があります。

データを受信するプロセッサの観点からは、最初に位置 1 でアナウンス メッセージを受信する必要があります。これにより、MPI_Testsome は Isend が完了したことを示し、データの大きなチャンクを送信します。受信プロセッサは、位置 2 でデータのメイン ブロックを受信する必要があります。このロジックに従うと、got_initial_bit_of_data[status.MPI_SOURCE] が 0 の状態で位置 2 に到達することは不可能ですが、これはまさに非常にまれに発生することであり、私は理由を解明するのが好きです。

コードのロジックが間違っているか、欠落している IProbe と Testsome の微妙な部分があります。

また、このコード ブロック全体を終了して再入力します。さまざまなプロセッサがさまざまな時点で出入りしますが、すべての ISend が処理された場合のみです (Testsome が完了したと判断した場合)。

上記の説明が意味をなさない場合、私が知りたいのは、一致する受信が完了せずに (または開始さえせずに) ISend が完了したと Testsome が主張する状況があるかどうかです。たとえば、プロセッサが IProbe を呼び出すだけで、Testsome は要求が完了したと見なすことができますか?

4

1 に答える 1

3

上記の説明が意味をなさない場合、私が知りたいのは、一致する受信が完了せずに (または開始さえせずに) ISend が完了したと Testsome が主張する状況があるかどうかです。たとえば、プロセッサが IProbe を呼び出すだけで、Testsome は要求が完了したと見なすことができますか?

MPI_Testsome が保証しているのは、ISend から使用していたバッファーが MPI で不要になったことだけです。受信者が受信を開始したことを保証したい場合は、同期形式の ISSend を使用します。

于 2013-09-25T16:40:06.960 に答える