user2657029
user2657029

Reputation: 43

MPI Gather not merging array as expected

Im working on a mandelbrot generator using MPI which outputs PPM file on finish. I used MPI gather to gather the chunks of the results from the computation into the final array. The code generates the file but it's incomplete; only the top half of the picture is shown. Where did I go wrong?

CALCULATION CODE:

     const int iXmax = 10000;
     const int iYmax = 10000;
     static unsigned char storeArray[25000000];
     static unsigned char FstoreArray[10000*10000*3];

  int chunk = (iYmax / p_num);
  mystart = (iYmax / p_num) * my_rank;
if (iYmax % p_num > my_rank) {
    mystart += my_rank;
    myend = mystart + (iYmax / p_num) + 1;
} else {
    mystart += iYmax % p_num;
    myend = mystart + (iYmax / p_num);
}
printf("%i start %i end %i rank %i chunk\n\n",mystart,myend,my_rank,chunk);

for(iY=mystart;iY<myend;iY++)
{
Cy=CyMin + iY*PixelHeight;
if (fabs(Cy)< PixelHeight/2) Cy=0.0; /* Main antenna */
for(iX=0;iX<iXmax;iX++)
{    

  //Alternate between colors for saving in array
  color1 = (iY*iXmax*3) + (iX*3)+0;
  color2 = (iY*iXmax*3) + (iX*3)+1;
  color3 = (iY*iXmax*3) + (iX*3)+2;

   Cx=CxMin + iX*PixelWidth;
   /* initial value of orbit = critical point Z= 0 */
   Zx=0.0;
   Zy=0.0;
   Zx2=Zx*Zx;
   Zy2=Zy*Zy;
   /* */
   for (iteration=0;iteration<iterationMax && ((Zx2+Zy2)<ER2);iteration++)
   {
     Zy=2*Zx*Zy + Cy;
     Zx=Zx2-Zy2 +Cx;
     Zx2=Zx*Zx;
     Zy2=Zy*Zy;
   };
   /* compute  pixel color (24 bit = 3 bytes) */
   if (iteration==iterationMax)
   { /*  interior of Mandelbrot set = black */
     storeArray[color1]=0;
     storeArray[color2]=0;
     storeArray[color3]=0;
   }
   else
   { /* exterior of Mandelbrot set = white */
     b=iterationMax-iteration;      /* Blue */
     g=b*b/iterationMax;            /* Green*/
     r=b*g/iterationMax;            /* Red */
     storeArray[color3]=b*pixelMax/iterationMax;
     storeArray[color2]=g*pixelMax/iterationMax;
     storeArray[color1]=r*pixelMax/iterationMax;
   };
 }
 }


int sendDataCount = chunk*iXmax;

printf("Processor %d::Finished.\n", my_rank);

printf("Processor %d::Sending Buffer: %d.\n", my_rank ,sendDataCount);
MPI_Gather(storeArray, sendDataCount, MPI_UNSIGNED_CHAR, FstoreArray, sendDataCount ,MPI_UNSIGNED_CHAR, 0, MPI_COMM_WORLD); 
printf("MPI_Gather called on %d.\n", my_rank);
fflush(stdout);

FILE WRITE:

  if calculations done and if rank == 0 do the following:

  FILE * fp;
  char *filename="cool_stuff.ppm";
  char *comment="# mandel is a headache";/* comment should start with # */

  /*create new file,give it a name and open it in binary mode  */
  fp= fopen(filename,"wb"); /* b -  binary mode */
  /*write ASCII header to the file*/
  fprintf(fp,"P6\n %s\n %d\n %d\n %d\n",comment,iXmax,iYmax,pixelMax);

  fwrite(FstoreArray,sizeof(FstoreArray),1,fp);
  fclose(fp);
  printf("array F %i, array S %i \n",     sizeof(FstoreArray),sizeof(storeArray));

Any help is VERY APPRECIATED! The file output is the last part of this headache and solving this would bring order back to my life...

Upvotes: 2

Views: 383

Answers (2)

Rob Latham
Rob Latham

Reputation: 5223

Since you are using MPI, why not use MPI-IO and bypass the gather alltogether? You don't even have to do a "where should I write?" communication step, since everyone has the same size data (except rank 0 who might additionally write out a ppm header -- I don't know the ppm file format)

Upvotes: 1

Cos314
Cos314

Reputation: 302

It appears that you have the parameters for fwrite reversed in 2 & 3. Your code:

fwrite(FstoreArray,sizeof(FstoreArray),1,fp);

Flip to:

fwrite(FstoreArray,1,sizeof(FstoreArray),fp);

Although I find it hard to imagine it would make much difference, but maybe the guts of fwrite limit the size of each byte element.

Upvotes: 0

Related Questions