Максимальная длина сообщения MPI_Type_vector и MPI_Gather - PullRequest
0 голосов
/ 29 мая 2018

Я получаю сообщение об ошибке «Произошла ошибка в MPI_Gather», когда я пытаюсь собрать массивы типа double с более 750 элементов в массив, который представляет собой матрицу.Предполагается, что собираемые массивы представляют столбцы матрицы, и поскольку матрица построена таким образом, что строки находятся в памяти рядом, я определил производный тип данных как вектор столбцов и назвал MPI_Gather следующим образом:

for (i = 0; i < k; i++) {
    MPI_Gather(&Q_vector[i*m], m, MPI_DOUBLE, &Q[i*size], 1, vector_m, 0, MPI_COMM_WORLD);
}

где k - количество векторов, m - длина каждого вектора (количество строк в матрице), size - это числочисло процессов и vector_m - это производный тип данных, который построен следующим образом:

MPI_Type_vector(m, 1, n, MPI_DOUBLE, &vector_m_type);
MPI_Type_create_resized(vector_m_type, 0, sizeof(double), &vector_m);
MPI_Type_commit(&vector_m);

, где n - количество столбцов в матрице.

Это нормально работает до m > 750. Если, например, m = 751, возникает ошибка (751 элемент типа double).Это не зависит от значения n .Я полностью изменил алгоритм так, чтобы столбцы матрицы сохранялись последовательно в памяти, вместо этого, чтобы решить проблему, вообще избегая производного типа данных, но мне все еще любопытно, почему это происходит.

Спецификации компьютера:

Процессор: Intel® Core® TM CPU i7-4790K @ 4,00 ГГц

Оперативная память: 8 ГБ

ОС: Windows 10 Home 64-битная

Компилятор: gcc 6.4.0

Я использую Cygwin.

Это сообщение об ошибке иногда печатается:

"Произошла ошибка в MPI_Gather, о которой сообщил процесс [52635822596882433,77309411328] на коммуникаторе MPI_COMM_WORLD

MPI_ERR_IN_STATUS: код ошибки в статусе MPI_ERRORS_ARE_FATAL (процессы в этом коммуникаторе теперь прервутся и, возможно, ваша работа MPI) "

Минимальный рабочий пример кода для воспроизведения ошибки:

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

int main(int argc, char *argv[]) {
    int n, m, size, rank, i, j, k;
    double *Q, *Q_vector;
    MPI_Datatype vector_m_type, vector_m;

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

    m = atoi(argv[1]);
    n = atoi(argv[2]);

    if (rank == 0) {
        Q = (double *)malloc(m*n*sizeof(double));
        for (i = 0; i < m; i++) {
            for (j = 0; j < n; j++) {
                Q[i*n+j] = drand48()*10;
            }
        }
    }

    // k = number of (column) vectors per process
    k = n/size;
    Q_vector = (double *)malloc(k*m*sizeof(double));

    MPI_Type_vector(m, 1, n, MPI_DOUBLE, &vector_m_type);
    MPI_Type_create_resized(vector_m_type, 0, sizeof(double), &vector_m);
    MPI_Type_commit(&vector_m);

    for (i = 0; i < k; i++) {
        MPI_Scatter(&Q[i*size], 1, vector_m, &Q_vector[i*m], m, MPI_DOUBLE, 0, MPI_COMM_WORLD);
    }

    for (i = 0; i < k; i++) {
        MPI_Gather(&Q_vector[i*m], m, MPI_DOUBLE, &Q[i*size], 1, vector_m, 0, MPI_COMM_WORLD);
    }

    if (rank == 0) {
        printf("Success!\n");
        free(Q);
    }
    free(Q_vector);

    MPI_Finalize();
}

Скомпилирован и работает так:

mpicc -o test MPI_Type_vector_test.c -lmpi -lm
mpirun -np 8 ./test 751 750

1 Ответ

0 голосов
/ 29 мая 2018

Это известная проблема в Open MPI, которая возникает, когда коллективная операция использует совпадающие подписи, но разные типы данных (например, один вектор с одной стороны и несколько элементов с другой).

Самый простой способ обойти эту проблему - отключить модуль coll/tuned

mpirun --mca coll ^tuned -np 8 ./test 751 750

Другой вариант - переписать код и использовать другой производный тип данных, описывающий строку (вместо использованияm элементов)

...