Где инициализировать массив, чтобы потом его разбрасывать. MPI_Scatter - PullRequest
0 голосов
/ 08 ноября 2019

Мне нужно отправить части массива всем процессам, используя MPI_Scatter, чтобы получить сумму всех элементов. Где мне инициализировать массив, чтобы потом его разбрасывать? В корне ранга?

Если я инициализирую массив в корне ранга, то другие ранги не получают свои данные. В противном случае я могу инициализировать массив для каждого (из if(rank == root)...else), но это означает, что я создаю массив несколько раз.

#include <stdio.h>
#include <stdlib.h>
#include <mpi.h>
#include <iostream>
#include <time.h>

using namespace std;

int main(int argc, char* argv[])
{
    int size;
    int rank;

    srand(time(NULL));

    MPI_Init(&argc, &argv);

    MPI_Comm_size(MPI_COMM_WORLD, &size);
    MPI_Comm_rank(MPI_COMM_WORLD, &rank);

    int arr_size = size * 2;
    int block = arr_size / (size);

    int* B = new int[block];

    if (rank == 0)
    {
        int* A = new int[arr_size];

        cout << "generated array: " << endl;
        for (int i = 0; i < arr_size; i++)
        {
            A[i] = rand() % 100;
            cout << A[i] << " ";
        }
        cout << endl;

        MPI_Scatter(A, block, MPI_INT, B, block, MPI_INT, 0, MPI_COMM_WORLD);       
    }

    cout << "process " << rank << " received: " << endl;
    for (int i = 0; i < block; i++)
    {
        cout << B[i] << " ";
    }
    cout << endl;

    int local_sum = 0;
    for (int i = 0; i < block; i++)
    {
        local_sum += B[i];
    }
    cout << "sum in process " << rank << " = " << local_sum << endl;
    cout << endl;

    int global_sum;
    MPI_Reduce(&local_sum, &global_sum, 1, MPI_INT, MPI_SUM, 0, MPI_COMM_WORLD);

    if (rank == 0)
    {
        cout << "sum = " << global_sum << endl;
    }

    MPI_Finalize();
    return 0;
}

Я получаю что-то вроде этого (только данные о корне получили данные):

process 1 received:
process 3 received:
-842150451 -842150451
-842150451 -842150451
sum in process 1 = -1684300902
sum in process 3 = -1684300902


process 2 received:
-842150451 -842150451
sum in process 2 = -1684300902

process 0 received:
4 9
sum in process 0 = 13

sum = -757935397

1 Ответ

0 голосов
/ 08 ноября 2019
  1. MPI_Scatter() является коллективной операцией и поэтому должна вызываться всеми рангами.
  2. Объявлять int *A = NULL; во всех рангах и распределять и заполнять только на нулевом ранге.
int* A = NULL;
int* B = new int[block];

if (rank == 0)
{
    A = new int[arr_size];

    cout << "generated array: " << endl;
    for (int i = 0; i < arr_size; i++)
    {
        A[i] = rand() % 100;
        cout << A[i] << " ";
    }
    cout << endl;
}

MPI_Scatter(A, block, MPI_INT, B, block, MPI_INT, 0, MPI_COMM_WORLD);
...