【问题标题】:MPI_Reduce C/C++ - Signal: Segmentation Fault (11)MPI_Reduce C/C++ - 信号:分段错误 (11)
【发布时间】:2021-02-27 14:15:38
【问题描述】:

我不太了解MPI_Reduce 如何与数组一起使用。 我需要做一个元素明智的总和。

为了测试MPI_Reduce 函数,我编写了这个简单的代码并且它可以工作:

double a[4] = {0,1,2,(double)process_id};
double b[4];
MPI_Reduce(&a, &b, 4, MPI_DOUBLE, MPI_SUM, p-1, MPI_COMM_WORLD);
if(id == p-1) {
    for(int i = 0; i < 4; i++){
        printf("%f, ", b[i]);
    }
}

它打印这个:

0.00000, 4.00000, 8.00000, 6.00000 

当我使用 4 个进程运行此代码时。有效!

现在我实现了我的问题。假设我使用p 进程,我需要减少p 维度的矩阵m * n 所以我以数组的形式重写每个矩阵

double *a;
double **A;

A = new double*[n];
//code that compute matrix A
a = (double *) malloc(m * n * sizeof(double));
int k = 0;
for(int i = 0; i < m; i++) {
    for(int j = 0; j < n; j++){
        a[k] = A[i][j];
        k++;
    }
}

通过这种方式,我得到了需要以数组形式减少的矩阵。现在我执行这个缩减:

if(id == p-1){
    reduce_storage = (double *) malloc(m * n * sizeof(double));
}

MPI_Reduce(&a, &reduce_storage, m * n, MPI_DOUBLE, MPI_SUM, p-1, MPI_COMM_WORLD);

数组 areduce_storage 以相同的方式分配,因此它们具有相同的维度 m * n,即 count 参数的值MPI_Reduce。我不明白为什么我尝试运行它会返回此错误:

*** stack smashing detected ***: <unknown> terminated
[EdoardoPC:01104] *** Process received signal ***
[EdoardoPC:01104] Signal: Aborted (6)
[EdoardoPC:01104] Signal code:  (-6)
[EdoardoPC:01104] *** Process received signal ***
[EdoardoPC:01104] Signal: Segmentation fault (11)
[EdoardoPC:01104] Signal code:  (128)
[EdoardoPC:01104] Failing at address: (nil)

【问题讨论】:

    标签: c++ c parallel-processing mpi reduction


    【解决方案1】:

    我不太了解 MPI_Reduce 如何与数组一起使用。我需要 做一个元素明智的总和。

    来自source的关于MPI_Reduce的可以读到:

    将所有进程的值减少为单个值

    int MPI_Reduce(const void *sendbuf, void *recvbuf, int count, MPI_Datatype 数据类型, MPI_Op op, int root, MPI_Comm comm)

    在您的情况下,MPI_Reduce 将如下图所示:

    (图片取自https://mpitutorial.com/tutorials/mpi-reduce-and-allreduce/

    从同一来源可以阅读:

    MPI_Reduce 获取每个进程的输入元素数组,然后 将输出元素数组返回到根进程。输出 元素包含缩减的结果。

    现在让我们看看你的问题

    为了测试 MPI_Reduce 函数,我编写了这个简单的代码并且它可以工作:

    double a[4] = {0,1,2,(double)process_id};
    double b[4];
    MPI_Reduce(&a, &b, 4, MPI_DOUBLE, MPI_SUM, p-1, MPI_COMM_WORLD);
    

    所有参数都正确; &amp;a&amp;b 分别匹配 const void *sendbufvoid *recvbuf。这同样适用于其余参数,即intMPI_DatatypeMPI_OpintMPI_Comm

    在这种情况下,ab&amp;a 和 &b 分别是 “相同”。在a&amp;a 产生相同的内存地址的意义上相同。尽管如此,使用a&amp;a 之间还是有重要区别的,更深入的解释请阅读以下difference between “array” and “&array”

    数组 a 和 reduce_storage 以相同的方式分配,因此 相同的维度 m * n,MPI_Reduce 的 count 参数的值。一世 不明白为什么我尝试运行它返回此错误:

    在第二次通话中

    MPI_Reduce(&a, &reduce_storage, m * n, MPI_DOUBLE, MPI_SUM, p-1, MPI_COMM_WORLD);
    

    参数areduce_storage 现在都是double* 类型,您将&amp;a&amp;reduce_storage 作为MPI_Reduce 的参数传递。这是错误的,因为&amp;a&amp;reduce_storage 将分别返回变量areduce_storage 的地址,这将是一个指向双精度指针的指针。

    假设我使用p进程,我需要减少p

    旁注:使用“p”作为尺寸的总数有点混乱,更好的 IMO 名称应该是 total_processesnumber_of_processes 或类似的名称。

    【讨论】:

      猜你喜欢
      • 2016-05-08
      • 1970-01-01
      • 2015-08-10
      • 2014-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多