【发布时间】:2015-10-03 22:43:31
【问题描述】:
使用 MPI 实现生命游戏的并行版本,出现分段错误(信号 11)。 MPI 的新手,无法真正让 valgrind 告诉我错误究竟存在于何处。简化我的代码,发现加粗的sn-p有问题。
编辑:标记出问题所在的代码块
#include "mpi.h"
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]){
if(argc!=5)
printf("Incorrect number of arguments.\n");
else{
// program logic here
int m, n, sum, pid, nprocs;
char outfilename[16];
FILE *outfile;
FILE *infile;
int r=atoi(argv[3]);
int c=atoi(argv[4]);
int gens=atoi(argv[2]);
int **old, **new, *new1d, *old1d;
int i,j;
MPI_Status status;
MPI_Init(&argc,&argv);
MPI_Comm_size(MPI_COMM_WORLD,&nprocs);
MPI_Comm_rank(MPI_COMM_WORLD,&pid); //initializing MPI here
//prevented segmentation error by using atoi
//domain decomposition start
// problem arisis here
int seg=c/nprocs; //divide by width
int ghost=seg+1;
int row=r+1;
int tsize=ghost*row; //ghost cells
old1d = malloc(tsize*sizeof(int));
new1d = malloc(tsize*sizeof(int));
old = malloc(r*sizeof(int*));
new = malloc(r*sizeof(int*));
for(i=0; i<ghost; i++){
old[i] = &old1d[i*row];
new[i] = &new1d[i*row];
}
// problem ends
if(pid==0){
MPI_Send(&old[0][seg], c, MPI_INT, 1, 0, MPI_COMM_WORLD);
MPI_Recv(&old[0][ghost],c, MPI_INT, 1, 1, MPI_COMM_WORLD, &status);
MPI_Send(&old[0][1], c, MPI_INT, 1, 2, MPI_COMM_WORLD);
MPI_Recv(&old[0][0], c, MPI_INT, 1, 3, MPI_COMM_WORLD, &status);
}
else{
MPI_Recv(&old[0][0], c, MPI_INT, 0, 0, MPI_COMM_WORLD, &status);
MPI_Send(&old[0][1], c, MPI_INT, 0, 1, MPI_COMM_WORLD);
MPI_Recv(&old[0][ghost],c, MPI_INT, 0, 2, MPI_COMM_WORLD, &status);
MPI_Send(&old[0][seg], c, MPI_INT, 0, 3, MPI_COMM_WORLD);
}
infile=fopen(argv[1],"r");
if(infile==NULL){
printf("Could not locate file.\n");
exit(1);
}
while(fscanf(infile,"%d %d",&m, &n)!=EOF){
old[m][n]=1;
}
fclose(infile);
//repeat for number of generations
for(n=0; n<gens; n++){
for(i=1; i<=r; i++){
for(j=1; j<=c; j++){
sum = old[i-1][j-1] + old[i-1][j] + old[i-1][j+1]
+ old[i][j-1] + old[i][j+1]
+ old[i+1][j-1] + old[i+1][j] + old[i+1][j+1];
if(sum==2 || sum==3)
new[i][j]=1;
else
new[i][j]=0;
}
}
//copying old state into new state
for(i=1; i<=r; i++){
for(j=1; j<=c; j++){
old[i][j] = new[i][j];
}
}
}
//create new output file
sprintf(outfilename,"output_%d",pid);
outfile=fopen(outfilename,"w");
for(i=1; i<=r; i++){
for(j=1; j<=c; j++){
if(new[i][j]==1){
fprintf(outfile,"%d\t%d\n",i ,j);
printf("%d %d",i,j);
}
}
}
fclose(outfile);
MPI_Finalize();
}
return 0;
}
编辑:输入文件 life.data.1 具有表示活细胞的 X Y 坐标。
【问题讨论】:
-
你做了什么来简化应用程序以便了解分段错误发生的位置?首先简化,然后添加更多代码来检测确切的故障位置。
-
我在没有进行域分解的情况下实现了一个并行版本。所以基本上这是没有 MPI_send / MPI_receive 的部分,也是我垂直划分域的部分。
-
不过,添加更多关于您尝试过的内容的详细信息,并尝试在您的问题中更加具体。这不是一个您可以转储代码并让人们解决您的问题的平台。
-
更新您的问题以指明问题出现的位置。请找出它出现的代码块或行。也许有人会帮忙。
-
argv[1] 应该是什么意思?我没有看到它在任何地方被引用。提示:C 使用零偏移。 (
for(i=1; i<=r; i++){也假设一个偏移量,恕我直言。
标签: c parallel-processing segmentation-fault mpi openmpi