MPI Gatherv с подматрицами - PullRequest
       10

MPI Gatherv с подматрицами

0 голосов
/ 30 ноября 2018

У меня проблемы с тем, чтобы MPI_Gatherv работал так, как я намереваюсь, и мне было интересно, что те из вас, кто более опытен, могут понять, что я делаю неправильно.

У меня большая матрица (ТЕСТ)из [N, M].Каждый процесс выполняет некоторую работу над подмножеством [nrows, M] (WORK_MATRIX), а затем каждый процесс собирает эти подматрицы (вдоль измерения строки) в полную матрицу.

Кажется, что он не собирает ни одного изданные, и я изо всех сил пытаюсь выяснить, почему!

Здесь я использую Eigen, чтобы обернуть эти (смежные) матрицы.

Вывод:

mpirun -np 5 ./pseudo.x
1 1 1 1 1
0 1 2 3 4
TEST: 5 10
0 0 2 0 0 0 0 0 0 0 
1 1 2 0 0 0 0 0 0 0 
2 2 2 0 0 0 0 0 0 0 
3 2 2 0 0 0 0 0 0 0 
4 2 0 0 0 0 0 0 0 0

Я создал простую версию кода ниже:

mpiicc -I / path / to / Eigen -o pseudo.x pseudo.cpp

#include <mpi.h>
#include <Eigen/Dense>
#include <iostream>

using namespace Eigen;
using namespace std;

int main(int argc, char ** argv) {
int RSIZE = 5;
int CSIZE = 10;

int rank;
int num_tasks;

MPI_Init(&argc, &argv);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
MPI_Comm_size(MPI_COMM_WORLD, &num_tasks);

MatrixXd TEST_MATRIX = MatrixXd::Zero(RSIZE, CSIZE);

VectorXi recv = VectorXi::Zero(num_tasks);
VectorXi displs = VectorXi::Zero(num_tasks);

int nrows = (RSIZE + rank) / num_tasks;

MPI_Allgather(&nrows, 1, MPI_INT, recv.data(), 1, MPI_INT, MPI_COMM_WORLD);

int start = 0;
for (int i = 0; i < rank; i++)
    start += recv[i];

MPI_Allgather(&start, 1, MPI_INT, displs.data(), 1, MPI_INT, MPI_COMM_WORLD);

if (rank == 0) {
    cout << recv.transpose() << endl;
    cout << displs.transpose() << endl;
}

MatrixXd WORK_MATRIX = MatrixXd::Zero(nrows, CSIZE);

for (int row = 0; row < nrows; row++)
    for (int col = 0; col < CSIZE; col++)
        WORK_MATRIX(row, col) += rank;

MPI_Datatype rowsized, row;

int sizes[2] = { RSIZE, CSIZE };
int subsizes[2] = { nrows, CSIZE };
int starts[2] = { 0, 0 };
MPI_Type_create_subarray(2, sizes, subsizes, starts, MPI_ORDER_C, MPI_DOUBLE, &rowsized);
MPI_Type_create_resized(rowsized, 0, sizeof(double), &row);
MPI_Type_commit(&row);

MPI_Allgatherv(WORK_MATRIX.data(), recv[rank], row, TEST_MATRIX.data(), recv.data(), displs.data(), row, MPI_COMM_WORLD);

if (rank == 0) {
    cout << "TEST: " << TEST_MATRIX.rows() << " " << TEST_MATRIX.cols() << endl;

    for (int i = 0; i < TEST_MATRIX.rows(); i++) {
        for (int j = 0; j < TEST_MATRIX.cols(); j++) {
            cout << TEST_MATRIX(i, j) << " ";
        }
        cout << endl;
    }
}

}

1 Ответ

0 голосов
/ 01 декабря 2018

in C, 2D матрицы хранятся в строках, и я сомневаюсь, что Eigen изменяет это.

, что означает, что вам не нужно изменять размеры типов данных, и смещение должно быть скорректировано

start += recv[i] * CSIZE;

Для вкуса вам совсем не нужно два MPI_Allgather(), поскольку nrows и start могут быть вычислены локально.Я бы предпочел, чтобы вы просто создали производный тип данных для одной строки с MPI_Type_contiguous() (и этот тип не должен быть изменен), поскольку MPI_Type_create_subarray() действительно является избыточным.

...