使用MPI的C程序中的分段错误

时间:2018-01-28 22:41:15

标签: c parallel-processing mpi fault

下面的代码尝试在多个并行处理器的数组中映射一组整数。我很困惑为什么它不断出现分段错误。我正在使用Ubuntu 17.10。任何帮助将不胜感激。

#include <mpi.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>

#define IN 16   //input size

int main(int argc, char** argv){
   // Initialize the MPI environment
   MPI_Init(&argc, &argv);
   MPI_Win win;
   // Find out rank, size
   int id;  //process id
   MPI_Comm_rank(MPI_COMM_WORLD, &id);
   int p;   //number of processes
   MPI_Comm_size(MPI_COMM_WORLD, &p);

   srand(time(0));
   int mapper[IN];
   int toMap[IN];
   int result[IN];
   if(id==0){
       for(int n=0; n<IN; n++){   //predecided map values
           toMap[n] = rand()%IN;
           mapper[n] = rand()%101;
           printf("[%d, %d]", n, mapper[n]);
       }
       printf("\n");
   }

   int d = IN/p;
   int i = id*d;
   while(i<id*d+d && i<IN){
        result[i] = mapper[toMap[i]];
        i++;
   }
   MPI_Barrier(MPI_COMM_WORLD);
   if(id == 0){
       for(int n=0; n<IN; n++){   //map results
           printf("[%d -> %d]\n", toMap[n], result[n]);
       }
   }
   MPI_Finalize();
   return 0;
}

当我使用:

执行程序时
mpiexec -np 2 parallelMap

我收到错误:

[sanjiv-Inspiron-5558:00943]     *** Process received signal ***
[sanjiv-Inspiron-5558:00943] Signal: Segmentation fault (11)
[sanjiv-Inspiron-5558:00943] Signal code: Address not mapped (1)
[sanjiv-Inspiron-5558:00943] Failing at address: 0x7ffecfc33a90
[sanjiv-Inspiron-5558:00943] [ 0] /lib/x86_64-linux-gnu/libpthread.so.0(+0x13150)[0x7f8c74400150]
[sanjiv-Inspiron-5558:00943] [ 1] parallelMap(+0xbf2)[0x5652d5561bf2]
[sanjiv-Inspiron-5558:00943] [ 2] /lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xf1)[0x7f8c7402e1c1]
[sanjiv-Inspiron-5558:00943] [ 3] parallelMap(+0x99a)[0x5652d556199a]
[sanjiv-Inspiron-5558:00943] *** End of error message ***
--------------------------------------------------------------------------
mpiexec noticed that process rank 1 with PID 0 on node sanjiv-Inspiron-5558 exited on signal 11 (Segmentation fault).
--------------------------------------------------------------------------

1 个答案:

答案 0 :(得分:2)

在MPI程序中,每个进程执行相同的代码,但是在单独的内存空间中。

在您的代码中,每个MPI进程都有自己的int mapper[IN],它们彼此之间没有关系。在这里你正在使用

while(i<id*d+d && i<IN){
    result[i] = mapper[toMap[i]];
    i++;
}

对于所有进程,但只有id == 0进程初始化了这些数组。对于其他进程,这些数组中的值是垃圾,这会导致您的分段错误。

您甚至无法调用任何MPI通信例程。事实上,MPI通信是通过调用其通信例程来实现的,例如MPI_Send()MPI_Bcast()。流程id=1并不了解数组&#39;流程id=0中的值。没有什么是自动完成的。