Reputation: 43
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
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
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