如何解决MPI_Reduce C/C++ - 信号:分段错误11
我不太明白 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_COMM_WORLD);
Array a 和 reduce_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)
解决方法
我不太明白 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);
所有参数都正确; &a
和 &b
分别匹配 const void *sendbuf
和 void *recvbuf
。这同样适用于其余参数,即 int
、MPI_Datatype
、MPI_Op
、int
和 MPI_Comm
。
在这种情况下,分别具有 a
和 b
或 &a
和 &b 是 “相同”。在 a
和 &a
产生相同的内存地址的意义上相同。尽管如此,使用 a
和 &a
之间存在重要区别,有关深入解释,请阅读以下 difference between “array” and “&array”。
数组 a 和 reduce_storage 以相同的方式分配,所以它们是 相同维度m * n,MPI_Reduce的count参数的值。一世 不明白为什么我尝试运行它会返回此错误:
在第二次通话中
MPI_Reduce(&a,&reduce_storage,m * n,MPI_COMM_WORLD);
参数 a
和 reduce_storage
现在都是 double*
类型,您将 &a
和 &reduce_storage
作为 MPI_Reduce
的参数传递.这是错误的,因为 &a
和 &reduce_storage
将分别返回变量 a
和 reduce_storage
的地址,它们将是指向双精度指针的指针。
假设我使用p进程,我需要减少p
旁注:使用“p”作为大小的总数有点混乱,IMO 更好的名称是 total_processes
、number_of_processes
或类似的东西。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。