使用 MPI 的 C 程序中的分段错误
Segmentation fault in C program using MPI
我下面的代码尝试将一组整数映射到具有多个并行处理器的数组中。我很困惑为什么它总是出现分段错误。我正在使用 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).
--------------------------------------------------------------------------
在 MPI 程序中,每个进程都执行相同的代码,但在单独的内存中 space。
在你的代码中,每个 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
不知道进程 id=0
中数组的值。什么都不会自动完成。
我下面的代码尝试将一组整数映射到具有多个并行处理器的数组中。我很困惑为什么它总是出现分段错误。我正在使用 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).
--------------------------------------------------------------------------
在 MPI 程序中,每个进程都执行相同的代码,但在单独的内存中 space。
在你的代码中,每个 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
不知道进程 id=0
中数组的值。什么都不会自动完成。