MPI_Scatter 动态二维数组行导致分段错误
MPI_Scatter dynamic 2d array rows result in segmentation fault
我有一个分配在连续内存中的动态二维数组 space,但是如果我尝试使用 MPI_Scatter 将此数组分散到两个 MPI 进程中,将导致分段错误,整个代码粘贴在这里:
dynamic_2d_array.h
#ifndef _DYNAMIC_2D_ARRAY_H_
#define _DYNAMIC_2D_ARRAY_H_
#include <stdio.h>
#include <stdlib.h>
//typedef double real;
typedef float real;
real **allocate_dynamic_2d_array(int nrows, int ncols);
void free_dynamic_2d_array(real** array_dynamic);
void print_matrix(real** array_dynamic, int nrows, int ncols, char* fmt_string);
real** allocate_dynamic_2d_array(int nrows, int ncols) {
/* here is the method to correct the non-contiguous memory problem */
int i;
real** array_dynamic=(real**)malloc(nrows*sizeof(real*));
real* data=(real*)malloc(nrows*ncols*sizeof(real));
for (i=0; i<nrows; i++){
array_dynamic[i]=&(data[ncols*i]);
}
return array_dynamic;
}
void free_dynamic_2d_array(real** array_dynamic){
free((void*)array_dynamic[0]);
free((void*)array_dynamic);
}
void print_matrix(real** array_dynamic, int nrows, int ncols, char* fmt_string) {
//void print_matrix(real array_dynamic[][4], int nrows, int ncols, char* fmt_string) {
int i,j;
for (i = 0; i < nrows; i++){
for (j = 0; j < ncols; j++){
printf(fmt_string, array_dynamic[i][j]);
}
printf("\n");
}
}
#endif // #ifndef _DYNAMIC_2D_ARRAY_H_
这里是 scatter_mat.h:
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
#include "dynamic_2d_array.h"
int main(int argc, char ** argv)
{
MPI_Init(&argc, &argv);
int rank, psize, root = 0;
int i,j;
int ncols;
int M=48,N=3;
real *sub_mat;
real **A;
MPI_Comm_size(MPI_COMM_WORLD, &psize);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank==0) {
A = allocate_dynamic_2d_array(M,N);
printf("before scatter:\n");
int idx=0;
for (i=0;i<M;i++){
for (j=0;j<N;j++) {
A[i][j]=idx++;
printf("%4.1f\t",A[i][j]);
}
printf("\n");
}
}
ncols = M/psize;
sub_mat = (real*)malloc(N*ncols*sizeof(real));
MPI_Scatter(&(A[0][0]),N*ncols,MPI_FLOAT,sub_mat,N*ncols,MPI_FLOAT,root,MPI_COMM_WORLD);
for (i=0;i<ncols*N;i++)
printf("%3.1f\t",sub_mat[i]);
printf("\n");
if (rank==0) {
free_dynamic_2d_array(A);
}
free(sub_mat);
MPI_Finalize();
return 0;
}
如果我使用 mpicc 编译它,运行 使用 mpi运行 -np 2 编译它,它将导致等级 1 的分段错误,更让我困惑的是它使用调试模式 (mpicc -g) 但是在发布模式下崩溃,我想一定有一些内存访问问题但是我无法弄清楚,有人可以提供一些建议吗?
下面是MPI编译器信息:
$ mpiexec --version
mpiexec (OpenRTE) 1.6.2
Report bugs to http://www.open-mpi.org/community/help/
$ mpicc -show
icc -I/usr/local/packages/openmpi/1.6.2/Intel-13.0.0/include -L/usr/local/packages/openmpi/1.6.2/Intel-13.0.0/lib -lmpi -ldl -lm -Wl,--export-dynamic -lrt -lnsl -libverbs -libumad -lpthread -lutil
非常感谢!
问题是您在所有级别中取消引用 &(A[0][0])
,但它仅在根级别中分配。将 NULL 作为第一个参数传递给所有级别中的 MPI_Scatter
,但根级别除外。
您还应该将 ncols
重命名为 nrows
(语义上)。
我有一个分配在连续内存中的动态二维数组 space,但是如果我尝试使用 MPI_Scatter 将此数组分散到两个 MPI 进程中,将导致分段错误,整个代码粘贴在这里:
dynamic_2d_array.h
#ifndef _DYNAMIC_2D_ARRAY_H_
#define _DYNAMIC_2D_ARRAY_H_
#include <stdio.h>
#include <stdlib.h>
//typedef double real;
typedef float real;
real **allocate_dynamic_2d_array(int nrows, int ncols);
void free_dynamic_2d_array(real** array_dynamic);
void print_matrix(real** array_dynamic, int nrows, int ncols, char* fmt_string);
real** allocate_dynamic_2d_array(int nrows, int ncols) {
/* here is the method to correct the non-contiguous memory problem */
int i;
real** array_dynamic=(real**)malloc(nrows*sizeof(real*));
real* data=(real*)malloc(nrows*ncols*sizeof(real));
for (i=0; i<nrows; i++){
array_dynamic[i]=&(data[ncols*i]);
}
return array_dynamic;
}
void free_dynamic_2d_array(real** array_dynamic){
free((void*)array_dynamic[0]);
free((void*)array_dynamic);
}
void print_matrix(real** array_dynamic, int nrows, int ncols, char* fmt_string) {
//void print_matrix(real array_dynamic[][4], int nrows, int ncols, char* fmt_string) {
int i,j;
for (i = 0; i < nrows; i++){
for (j = 0; j < ncols; j++){
printf(fmt_string, array_dynamic[i][j]);
}
printf("\n");
}
}
#endif // #ifndef _DYNAMIC_2D_ARRAY_H_
这里是 scatter_mat.h:
#include <stdio.h>
#include <stdlib.h>
#include "mpi.h"
#include "dynamic_2d_array.h"
int main(int argc, char ** argv)
{
MPI_Init(&argc, &argv);
int rank, psize, root = 0;
int i,j;
int ncols;
int M=48,N=3;
real *sub_mat;
real **A;
MPI_Comm_size(MPI_COMM_WORLD, &psize);
MPI_Comm_rank(MPI_COMM_WORLD, &rank);
if (rank==0) {
A = allocate_dynamic_2d_array(M,N);
printf("before scatter:\n");
int idx=0;
for (i=0;i<M;i++){
for (j=0;j<N;j++) {
A[i][j]=idx++;
printf("%4.1f\t",A[i][j]);
}
printf("\n");
}
}
ncols = M/psize;
sub_mat = (real*)malloc(N*ncols*sizeof(real));
MPI_Scatter(&(A[0][0]),N*ncols,MPI_FLOAT,sub_mat,N*ncols,MPI_FLOAT,root,MPI_COMM_WORLD);
for (i=0;i<ncols*N;i++)
printf("%3.1f\t",sub_mat[i]);
printf("\n");
if (rank==0) {
free_dynamic_2d_array(A);
}
free(sub_mat);
MPI_Finalize();
return 0;
}
如果我使用 mpicc 编译它,运行 使用 mpi运行 -np 2 编译它,它将导致等级 1 的分段错误,更让我困惑的是它使用调试模式 (mpicc -g) 但是在发布模式下崩溃,我想一定有一些内存访问问题但是我无法弄清楚,有人可以提供一些建议吗?
下面是MPI编译器信息:
$ mpiexec --version
mpiexec (OpenRTE) 1.6.2
Report bugs to http://www.open-mpi.org/community/help/
$ mpicc -show
icc -I/usr/local/packages/openmpi/1.6.2/Intel-13.0.0/include -L/usr/local/packages/openmpi/1.6.2/Intel-13.0.0/lib -lmpi -ldl -lm -Wl,--export-dynamic -lrt -lnsl -libverbs -libumad -lpthread -lutil
非常感谢!
问题是您在所有级别中取消引用 &(A[0][0])
,但它仅在根级别中分配。将 NULL 作为第一个参数传递给所有级别中的 MPI_Scatter
,但根级别除外。
您还应该将 ncols
重命名为 nrows
(语义上)。