3. 集団通信

MPI_Bcast / MPI_Scatter / MPI_Gather / MPI_Allgather / MPI_Alltoall / MPI_Reduce / MPI_Allreduce

MPI_Bcast - ブロードキャスト

      call MPI_Bcast(buffer, count, datatype, root, comm, ierror)

引数        データ型          入力or出力  内容
------------------------------------------------------------
buffer      任意              入力/出力   送受信するデータ(の先頭アドレス)
count       整数              入力        データの個数
datatype    MPIデータ型       入力        データ型
root        整数              入力        送信元プロセスのランク
comm        MPIコミュニケータ 入力        コミュニケータ
ierror      整数              出力        エラーコード
ブロードキャスト

rootプロセスが指定したbufferの位置からcount個のデータを、comm内の他の全てのプロセスのbufferに送信する。したがって、bufferはrootプロセスにとっては入力、その他のプロセスにとっては出力となる。送受信に参加する全てのプロセスがMPI_Bcastをコールする必要があり、rootとcommはその全てのプロセスが同じ値を指定しなければならない。また、countとdatatypeも通常は全プロセスで同じ値となるはずである。

例1:
プロセス0が変数xに持っている値を、他の全プロセスの変数xに渡したい場合は、全プロセスが次のようにコールすればよい。

      call MPI_Bcast(x, 1, MPI_REAL8, 0, MPI_COMM_WORLD, ierr)

例2:
複数の値を持つ配列の場合は、送受信する先頭の位置をbufferに、データの個数をcountに指定する。例えば、プロセス0が配列x(1)〜x(10)に持っている値を、他の全プロセスの配列x(1)〜x(10)に渡したい場合は、全プロセスが次のようにコールすればよい。

      call MPI_Bcast(x(1), 10, MPI_REAL8, 0, MPI_COMM_WORLD, ierr)

戻る

MPI_Scatter - スキャタ

      call MPI_Scatter(sendbuf, sendcount, sendtype,
     &                 recvbuf, recvcount, recvtype,
     &                 root, comm, ierror)

引数        データ型          入力or出力  内容
------------------------------------------------------------
sendbuf     任意              入力        送信するデータ(の先頭アドレス)
sendcount   整数              入力        送信するデータの個数
sendtype    MPIデータ型       入力        送信するデータの型
recvbuf     任意              出力        受信するデータ(の先頭アドレス)
recvcount   整数              入力        受信するデータの個数
recvtype    MPIデータ型       入力        受信するデータの型
root        整数              入力        送信元プロセスのランク
comm        MPIコミュニケータ 入力        コミュニケータ
ierror      整数              出力        エラーコード
スキャタ

rootプロセスが指定したsendbufの位置からsendcount個ずつ、comm内のプロセス0から順に全プロセスのrecvbufの位置へ送信する。送受信に参加する全てのプロセスがMPI_Scatterをコールする必要があり、rootとcommはその全てのプロセスが同じ値を指定しなければならない。また、sendcountとrecvcount、sendtypeとrecvtypeはそれぞれ通常は同じであり、全プロセスにおいても同じはずである。

例1:
4つのプロセスがあり、プロセス0がx(1)〜x(100)にデータを持っているとする。これを25ずつ4つに分けて、各プロセスのy(1)〜y(25)へそれぞれ渡したいときは、全プロセスが次のようにコールすればよい。

      call MPI_Scatter(x(1), 25, MPI_REAL8, y(1), 25, MPI_REAL8,
     &                 0, MPI_COMM_WORLD, ierr)

戻る

MPI_Gather - ギャザ

      call MPI_Gather(sendbuf, sendcount, sendtype,
     &                recvbuf, recvcount, recvtype,
     &                root, comm, ierror)

引数        データ型          入力or出力  内容
------------------------------------------------------------
sendbuf     任意              入力        送信するデータ(の先頭アドレス)
sendcount   整数              入力        送信するデータの個数
sendtype    MPIデータ型       入力        送信するデータの型
recvbuf     任意              出力        受信するデータ(の先頭アドレス)
recvcount   整数              入力        受信するデータの個数
recvtype    MPIデータ型       入力        受信するデータの型
root        整数              入力        受信するプロセスのランク
comm        MPIコミュニケータ 入力        コミュニケータ
ierror      整数              出力        エラーコード
ギャザ

comm内のプロセス0から順に送られてくるsendbufを、rootプロセスのrecvbufへrecvcount個ずつ、配置していく。送受信に参加する全てのプロセスがMPI_Gatherをコールする必要があり、rootとcommはその全てのプロセスが同じ値を指定しなければならない。また、sendcountとrecvcount、sendtypeとrecvtypeはそれぞれ通常は同じであり、全プロセスにおいても同じはずである。

例1:
3つのプロセスがあり、プロセス0はy(1)〜y(20)、プロセス1はy(21)〜y(40)、プロセス2はy(41)〜y(60)というように20ずつずれた位置のデータを持っているとする。これら全てをプロセス0のx(1)〜x(60)に配置したいときは、次のようにすればよい。

      call MPI_Comm_rank(MPI_COMM_WORLD, myrank, ierr)
      i=myrank*20+1
      call MPI_Gather(y(i), 20, MPI_REAL8, x(1), 20, MPI_REAL8,
     &                0, MPI_COMM_WORLD, ierr)

戻る

MPI_Allgather - オールギャザ

      call MPI_Gather(sendbuf, sendcount, sendtype,
     &                recvbuf, recvcount, recvtype, comm, ierror)

引数        データ型          入力or出力  内容
------------------------------------------------------------
sendbuf     任意              入力        送信するデータ(の先頭アドレス)
sendcount   整数              入力        送信するデータの個数
sendtype    MPIデータ型       入力        送信するデータの型
recvbuf     任意              出力        受信するデータ(の先頭アドレス)
recvcount   整数              入力        受信するデータの個数
recvtype    MPIデータ型       入力        受信するデータの型
comm        MPIコミュニケータ 入力        コミュニケータ
ierror      整数              出力        エラーコード
オールギャザ

基本的にはMPI_Gatherと同じであるが、右の図のように、各プロセスから全プロセスへギャザするという点が異なる。このため、rootの指定はない。MPI_Gatherをプロセス数と同じ回数コールするのと結果は同じであるが、MPI_Allgatherの方が、バタフライと呼ばれる効率的な通信方法を用いるため、高速に行われる。

戻る

MPI_Alltoall - 全交換

      call MPI_Alltoall(sendbuf, sendcount, sendtype,
     &                  recvbuf, recvcount, recvtype, comm, ierror)

引数        データ型          入力or出力  内容
------------------------------------------------------------
sendbuf     任意              入力        送信するデータ(の先頭アドレス)
sendcount   整数              入力        送信するデータの個数
sendtype    MPIデータ型       入力        送信するデータの型
recvbuf     任意              出力        受信するデータ(の先頭アドレス)
recvcount   整数              入力        受信するデータの個数
recvtype    MPIデータ型       入力        受信するデータの型
comm        MPIコミュニケータ 入力        コミュニケータ
ierror      整数              出力        エラーコード
全交換

全プロセスが、全プロセスに対してスキャタを行うのと同じ操作が得られる。各プロセスは、sendbufの位置からsendcount個ずつ、comm内のプロセス0から順に向けて送信する。同時に、プロセス0から順に送られてくるデータを受け取り、recvbufの位置からrecvcount個ずつ、配置していく。全プロセスが、全プロセスに対してギャザを行った、と解釈することもできる。

戻る

MPI_Reduce - レデュース

      call MPI_Reduce(sendbuf, recvbuf, count, datatype,
     &                op, root, comm, ierror)

引数        データ型          入力or出力  内容
------------------------------------------------------------
sendbuf     任意              入力        送信するデータ(の先頭アドレス)
recvbuf     任意              出力        受信するデータ(の先頭アドレス)
count       整数              入力        データの個数
datatype    MPIデータ型       入力        データ型
op          MPIオペランド     入力        演算の種類
root        整数              入力        受信するプロセスのランク
comm        MPIコミュニケータ 入力        コミュニケータ
ierror      整数              出力        エラーコード
レデュース

comm内の全プロセスのsendbufに、opで指定した演算を施して、rootプロセスのrecvbufへ送る。右の図の例では、4つのプロセスがそれぞれ1、2、3、4という値を持っていて、これに「加算」という演算が施され(1+2+3+4=10)、その結果がプロセス0へ送られている。送受信に参加する全てのプロセスがMPI_Reduceをコールする必要があり、root、comm、opなどはその全てのプロセスが同じ値を指定しなければならない。

戻る

MPI_Allreduce - オールレデュース

      call MPI_Allreduce(sendbuf, recvbuf, count, datatype,
     &                   op, comm, ierror)

引数        データ型          入力or出力  内容
------------------------------------------------------------
sendbuf     任意              入力        送信するデータ(の先頭アドレス)
recvbuf     任意              出力        受信するデータ(の先頭アドレス)
count       整数              入力        データの個数
datatype    MPIデータ型       入力        データ型
op          MPIオペランド     入力        演算の種類
comm        MPIコミュニケータ 入力        コミュニケータ
ierror      整数              出力        エラーコード
オールレデュース

基本的にはMPI_Reduceと同じであるが、演算した結果を全プロセスへ送信するという点が異なる。このため、rootの指定はない。レデュースを行ったあとに、その結果をブロードキャストするのと結果は同じであるが、MPI_Allreduceの方が、バタフライと呼ばれる効率的な通信方法を用いるため、高速に行われる。

戻る