2.4.4. MPI_Scatter

 1#include <mpi.h>
 2
 3#include <iostream>
 4#include <vector>
 5#include <cstdlib>
 6
 7/*
 8 * 配列データを区切って各プロセスに分配する
 9 *
10 * 実行方法: mpiexec -n 4 mpi_sample4
11 * プロセス数は 1 〜 9 まで指定可能
12 */
13
14int main(int argc, char *argv[])
15{
16    MPI_Init(&argc, &argv);
17
18    int num_procs;
19    int my_rank;
20
21    MPI_Comm_size(MPI_COMM_WORLD, &num_procs);
22    MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);
23
24    if (num_procs > 10)
25    {
26        std::cerr << "Number of processes must be 10 at max." << std::endl;
27        return EXIT_FAILURE;
28    }
29
30    int send_data_count;
31    if (my_rank == 0)
32    {
33        send_data_count = 10;
34    } else
35    {
36        send_data_count = 0;
37    }
38    int total_send_data_count = send_data_count * num_procs;
39    std::vector<double> send_data(total_send_data_count, 0);
40    const double *send_data_address = &send_data[0];
41
42    int recv_data_count = 10;
43    std::vector<double> recv_data(recv_data_count, 0);
44    double *recv_data_address = &recv_data[0];
45
46    if (my_rank == 0)
47    {
48        /* 送り元rankでは送信データを用意する */
49        for (int i = 0; i < total_send_data_count; i++)
50        {
51            send_data[i] = i;
52        }
53
54        std::cout << "rank: 0, send_data: [" << std::endl;
55        for (int k = 0; k < num_procs; k++)
56        {
57            for (int i = 0 ; i< send_data_count; i++)
58            {
59                std::cout << " " << send_data[k*send_data_count + i];
60            }
61            std::cout << std::endl;
62        }
63        std::cout << "]" << std::endl;
64    }
65
66    MPI_Scatter(
67        send_data_address,
68        send_data_count, // rank == 0 でのみ正
69        MPI_DOUBLE,
70        recv_data_address, // 全rankで受信
71        recv_data_count,
72        MPI_DOUBLE,
73        0, /* 送り元とするrank */
74        MPI_COMM_WORLD
75        );
76
77    // 受信できたデータを表示する
78    std::cout << "rank: " << my_rank << ", recv_data: [";
79    for (int i = 0; i < 10; i++)
80    {
81        std::cout << " " << recv_data[i];
82    }
83    std::cout << " ]" << std::endl;
84
85    MPI_Finalize();
86    return EXIT_SUCCESS;
87}

Download the source code

MPI_Scatter では、グループ操作のルートとして指定した rank で 用意した配列データを等しい個数ずつ、全てのrankに分配します。

ルートrankを含む全てのrankでは分配された分のデータだけを受信します。

送信するのはルートrankだけですが、関数のインタフェース上は 全てのrankで送信バッファと受信バッファの双方を指定します。

コンパイルと実行例を示します。:

$ mpic++ -o mpi_sample4 mpi_sample4.cpp
$ mpiexec -n 4 mpi_sample4
rank: 0, send_data: [
 0 1 2 3 4 5 6 7 8 9
 10 11 12 13 14 15 16 17 18 19
 20 21 22 23 24 25 26 27 28 29
 30 31 32 33 34 35 36 37 38 39
]
rank: 0, recv_data: [ 0 1 2 3 4 5 6 7 8 9 ]
rank: 3, recv_data: [ 30 31 32 33 34 35 36 37 38 39 ]
rank: 1, recv_data: [ 10 11 12 13 14 15 16 17 18 19 ]
rank: 2, recv_data: [ 20 21 22 23 24 25 26 27 28 29 ]