MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
この関数はランクパラメータを必要としません。各プロセスのランクをどのように知るのですか?
MPI_COMM_RANK()
ブロードキャストの前に呼び出す必要がありますが、データ構造(コミュニケーターなど)はプロセスのランクを格納しますか?
MPI_Bcast(void *buffer, int count, MPI_Datatype datatype, int root, MPI_Comm comm)
この関数はランクパラメータを必要としません。各プロセスのランクをどのように知るのですか?
MPI_COMM_RANK()
ブロードキャストの前に呼び出す必要がありますが、データ構造(コミュニケーターなど)はプロセスのランクを格納しますか?
可能だとは思わなかったかもしれませんが、MPI ライブラリ内の関数は、プロセスのランクやコミュニケーターのサイズを取得するために使用するのと同じ MPI 呼び出しを内部的に行うことができます。MPI_Bcast()
呼び出しプロセスのランクを取得するためにの内部実装を呼び出すだけなので、呼び出しプロセスのランクは必要ありませんMPI_Comm_rank()
。Open MPIの実装の 1 つからの小さなサンプルを次に示しますMPI_Bcast()
(より具体的には、これは集合操作を実装するアルゴリズムを提供するフレームワークのtuned
モジュールの分割バイナリ ツリー実装からのものです)。coll
int
ompi_coll_tuned_bcast_intra_split_bintree ( void* buffer,
int count,
struct ompi_datatype_t* datatype,
int root,
struct ompi_communicator_t* comm,
mca_coll_base_module_t *module,
uint32_t segsize )
{
...
int rank, size;
...
size = ompi_comm_size(comm);
rank = ompi_comm_rank(comm);
...
}
ご覧のとおり、 と の内部実装を呼び出しMPI_Comm_size()
ますMPI_Comm_rank()
。これらは、Open MPI では非常に安価な呼び出しです。プロセスのランクは、コミュニケーターに関連付けられているプロセス グループに格納され、コミュニケーターの作成中にコミュニケーター構造体のフィールドにコピーされます (グループへのポインターを逆参照するいくつかの CPU サイクルを節約するため)。openmpi-source/ompi/communicator/communicator.h
およびを参照してくださいopenmpi-source/ompi/group/group.h
)。
実際のところ、MPI 通信プリミティブが呼び出しプロセスのランクを明示的に取得することはありません。常に内部で解決されます。MPI_SEND
データの送信先 (例: in )、データの受信元 (例: in MPI_RECV
)、またはデータ ルートを持つ集合操作のデータ ルートのみを指定します。
の 3 つの可能な実装を検討してくださいMPI_Bcast()
。
root+1
に送信しroot+2
、次に に送信しますroot+3
。これは線形の順序です。N
転送しますrank xor 2^N
。これは対数のオーダーです。これらのシナリオのそれぞれで、MPI_Bcast()
関数は次のメッセージを受け取るプロセスを認識しています。1 番目と 3 番目のケースでは、非ルートプロセスはデータを受信するだけです。2 番目のプロセスでは、データを受信すると、各プロセスが転送プロセスを続行します。ただし、すべての実装において、送信と受信の順序は、どのプロセスがルートであるかに基づいて決定論的です。(そのため、ルートMPI_Bcast()
であるかどうかに関係なく、すべてのプロセスで を呼び出す必要があります。)
そうです、ランクはコミュニケーターに保存され、MPI_Bcast
内部での実装に使用できます。コミュニケータを作成すると、ランクが割り当てられます。たとえば、MPI_COMM_WORLD
によって作成されMPI_Init
ます。
MPI_Comm_rank
コミュニケータからランク値を取得するだけです。ブロードキャストの前に呼び出す必要はありません。ただし、意味のあるプログラミングを行うには、通常、ランクを知る必要があります。
MPI_Bcast
は集合呼び出しであるため、コミュニケーター内のすべてのプロセスで実行する必要があることに注意してください。
int root
、ブロードキャストルートのランクです。基本的にMPIブロードキャストは、ランクルートから他のすべてのランクにメッセージを送信します
また、MPI_Init の後に以下を呼び出すことが「ベスト プラクティス」であると考えられます。
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
これにより、各プロセッサまたはコアに 0 から n-1 までの int ランク値が割り当てられます。
と
MPI_Comm_size( MPI_COMM_WORLD, &Numprocs);
これにより、Numproces がプロセッサの総数である int が作成されます。