c - 最大消息长度 MPI_Type_vector 和 MPI_Gather

标签 c mpi openmpi

当我尝试使用 收集 double 类型的数组时,我收到错误消息“MPI_Gather 中发生错误”超过 750 元素放入表示矩阵的数组中。正在收集的数组应该代表矩阵的列,并且由于矩阵的构造使得行在内存中是连续的,因此我将派生数据类型定义为列 vector 并像这样调用 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 是 vector 的数量,m 是每个 vector 的长度(矩阵中的行数),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 的值。我完全改变了算法,以便矩阵的列连续存储在内存中,而不是通过完全避免派生数据类型来解决问题,但我仍然很好奇为什么会发生这种情况。

电脑规范:

CPU: Intel(R) Core(TM) i7-4790K CPU @ 4.00GHz

内存:8 GB

操作系统:Windows 10 家庭版 64 位

编译器:gcc 6.4.0

我使用 Cygwin。

有时会打印此错误消息:

"
通信器 MPI_COMM_WORLD 上的进程 [52635822596882433,77309411328] 报告的 MPI_Gather 发生错误

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

最佳答案

这是 known issue在集体操作使用匹配签名但不同数据类型时发生的 Open MPI
(例如,一方面是一个 vector ,另一方面是几个元素)。

解决此问题的最简单方法是禁用 coll/tuned模块

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

另一种选择是重写您的代码并使用描述行的其他派生数据类型(而不是使用 m 元素)

关于c - 最大消息长度 MPI_Type_vector 和 MPI_Gather,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50573602/

相关文章:

parallel-processing - #pragma for 末尾的隐式障碍

python - 使用 slurm 在网格上运行 helloworld.py 程序

c - 在 WDK 驱动程序中包含 hidpi.h 会导致编译错误

c - 如何将 float 数组转换为 GLfloat 数组?

c - 使用 MPI_THREAD_MULTIPLE 的混合循环并行化

c - MPI_Get_count 返回计数负值

c - 将指针的二维数组传递给函数 C 的不同方法

c - C中udp套接字上的poll()POLLIN事件

c++ - 在 OSX 中使用什么架构?

linux - 导致 OpenMPI 下运行的所有进程转储核心