Implementing a parallel version of Game of Life using MPI, getting a segmentation fault (signal 11). New to MPI, and couldn't really get valgrind to tell me where exactly the error exists. Simplified my code and found that there exists a problem in the bold snippet.
Edit: marked the block of code where the problem exists
#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;
}
Edit: The input file life.data.1 has X Y co-ordinates that denote live cells.
for(i=1; i<=r; i++){
assumes one-offset, too, IMHO. - wildplasser