使用MPI_Bcast时MPI分段错误

时间:2014-04-16 10:59:25

标签: c parallel-processing segmentation-fault mpi

我正在尝试计算使用MPI_Bcast和通常的MPI_send和MPI_Recv向所有进程广播100万个整数数组的加速和效率之间的差异。但我不明白为什么我得到这个分段错误,任何帮助将不胜感激。这是我的代码:

#define num_of_ints 1000000
int *create_random_array(int);
int main(int argc, char *argv[]){
int size=0, my_rank =0, i=0;
int tag =99;
double start, end;
int *array = NULL;
srand(time(NULL));

MPI_Status status;
MPI_Init(&argc, &argv);
MPI_Comm_size(MPI_COMM_WORLD, &size);
MPI_Comm_rank(MPI_COMM_WORLD, &my_rank);

if(my_rank ==0)
    array = create_random_array(size*num_of_ints);
MPI_Barrier(MPI_COMM_WORLD);
start = MPI_Wtime();
MPI_Bcast(&array, num_of_ints, MPI_INT, 0, MPI_COMM_WORLD);
MPI_Barrier(MPI_COMM_WORLD);
end = MPI_Wtime();
printf("time of broadcast using Bcast is %f seconds", end - start);

MPI_Barrier(MPI_COMM_WORLD);
start = MPI_Wtime();
if (my_rank == 0){
    for (i = 1; i < size; i++)
        MPI_Send(&array, num_of_ints, MPI_INT, i,tag, MPI_COMM_WORLD);
}else{
    MPI_Recv(&array, num_of_ints, MPI_INT, 0,tag,MPI_COMM_WORLD, &status);
}
MPI_Barrier(MPI_COMM_WORLD);
end = MPI_Wtime();

printf("time of broadcast using send/recv is %f seconds", end - start);
MPI_Finalize();
return 0;
}
 int *create_random_array(int size){
int i=0;
int *random_arr = (int*)malloc(size*sizeof(int));
for(i=0;i<size;i++)
    random_arr[i] = (rand()/(int)RAND_MAX);
return random_arr;
 }

2 个答案:

答案 0 :(得分:2)

你的代码中有一个非常常见的错误,它与MPI本身无关,但在C / C ++中正确使用了指针。 C中的所有MPI通信调用都需要指向数据的指针,大多数示例都显示为MPI_Somecall(&var, ...),但var通常是标量整数或浮点变量。如果&var是一个静态数组,var也可以工作,如果var是一个指针,它就不起作用,因为&var然后给出指针本身的位置,而不是它指向的地址。

简而言之:

MPI_Somecall(&var, ...)

var时:

  • 标量全局/静态或自动变量,例如int var;
  • 结构的全局/静态或自动实例,例如struct foo var;

否则:

MPI_Somecall(var, ...)

var时:

  • 静态数组,例如int var[10];
  • 指向堆变量或数组的指针,例如int *var = malloc(...);
  • 一般指针,例如int *var = &some_int_var;
  • 指针类型的函数参数,例如void func(..., int *var, ...);

使用&array替换代码中array的所有实例。

答案 1 :(得分:2)

除了&amp; @HristoLLiev报告的错误,您的代码在内存管理方面存在缺陷,除非您修复它,否则无法使用。

实际上,在开始时,对于所涉及的所有进程,数组变量都是NULL,但是仅在由rank为零的进程调用create_random_array()时分配。所有其他进程都不分配内存。因此,您会遇到分段错误。为了使代码正常工作,每个进程都必须正确分配数组。