void slave() { float real_min=-2, imag_min = -2; float real_max=2, imag_max = 2; float scale_real = (real_max - real_min)/X_RES; float scale_imag = (imag_max - imag_min)/Y_RES; int canvas [X_RES][Y_RES]; int color[Y_RES]; //it will be iteratively updated by a slave processor //Y_RES: number of columns in tha array int row; MPI_Status status; //color contains the values for the row colors MPI_Recv(&row, X_RES, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status); while(status.MPI_TAG==DATA_TAG) { //let's compute a row of the canvas int i = row; //c.real = j; //c.imag = i; //Y_RES lies on the x-axis!! for(int j=0; j<Y_RES; i++) { complex c; c.real = real_min + ((float) j*scale_real); c.imag = imag_min + ((float) i*scale_imag); color[j] = cal_pixel(c); } MPI_Send(color, Y_RES, MPI_INT, 0, RESULT_TAG, MPI_COMM_WORLD); MPI_Send(&row, 1, MPI_INT, 0, RESULT_TAG, MPI_COMM_WORLD); MPI_Recv(&row, 1, MPI_INT, 0, MPI_ANY_TAG, MPI_COMM_WORLD, &status); } if(status.MPI_TAG==TERMINATE_TAG) { return; } }
int main(int argc, char *argv[]) { int disp_width, disp_height; float real_min, real_max, imag_min, imag_max, scale_real, scale_imag; FILE *f; struct complex c; int x,y,i; char str[256]; int map[3][257]; int** pic; if (argc != 9) { printf("Usage:\n Mandelbrot width heightA1 real-min real-max imag-min imag-max mapfile outfile\n"); exit(1); } /* Decode arguments */ disp_width = atoi(argv[1]); disp_height = atoi(argv[2]); real_min = atof(argv[3]); real_max = atof(argv[4]); imag_min = atof(argv[5]); imag_max = atof(argv[6]); /* Load the required colour map file */ f = fopen(argv[7],"r"); for(i=0;i<=256;i++) { fgets(str,1000,f); sscanf(str,"%d %d %d",&(map[0][i]),&(map[1][i]),&(map[2][i])); } fclose(f); /* Allocate space for the image */ pic = (int**)malloc(sizeof(int*)*disp_width); for (x=0;x<disp_width;x++) pic[x] = (int*)malloc(sizeof(int)*disp_height); /* Compute scaling factors */ scale_real = (real_max-real_min)/disp_width; scale_imag = (imag_max-imag_min)/disp_height; for (y=0; y < disp_height; y++) { for (x=0; x<disp_width; x++) { c.real = real_min + ((float) x * scale_real); c.imag = imag_min + ((float) y * scale_imag); i = cal_pixel(c); pic[x][y] = i; } } f = fopen(argv[8],"w"); fprintf(f,"P3\n%d %d\n255\n",disp_width,disp_height); for (y=0; y<disp_height; y++) { for (x=0; x<disp_width; x++) { fprintf(f,"%d %d %d ",map[0][pic[x][y]],map[1][pic[x][y]],map[2][pic[x][y]]); } fprintf(f,"\n"); } fclose(f); }
int main(int argc, char *argv[]) { /******************* Timing Variables ***********/ struct timeval tIO1, tIO2; struct timeval tComm1, tComm2; struct timeval tCal1, tCal2; struct timeval tG1, tG2; gettimeofday(&tG1, NULL); /******************* Image Variables ***********/ FILE *f; int disp_width, disp_height; float real_min, real_max, imag_min, imag_max, scale_real, scale_imag; struct complex c; int x,y,i; char str[256]; int map[3][257]; int *pic; if (argc != 9) { printf("Usage:\n Mandelbrot width height real-min real-max imag-min imag-max mapfile outfile\n"); exit(1); } /******************* Decode arguments *************/ disp_width = atoi(argv[1]); disp_height = atoi(argv[2]); real_min = atof(argv[3]); real_max = atof(argv[4]); imag_min = atof(argv[5]); imag_max = atof(argv[6]); /* ****************** MPI Variables ****************** */ int rank, size; MPI_Status status; /* ****************** MPI Init ****************** */ MPI_Init(&argc, &argv); MPI_Comm_rank(MPI_COMM_WORLD, &rank); MPI_Comm_size(MPI_COMM_WORLD, &size); /* ****************** More MPI Variables ****************** */ int slaveStartCol, slaveWidth; int slaveID, xIndex; int colPerSlave = disp_width / (size - 1); /* Allocate Memory for the entire picture */ pic = (int *)malloc(disp_width*disp_height*sizeof(int)); /************************** MASTER ******************************/ if (rank == MASTER) { printf("Master Started . . . \n"); /* Load the required colour map file */ f = fopen(argv[7],"r"); for(i=0;i<=256;i++) { fgets(str,1000,f); sscanf(str,"%d %d %d",&(map[0][i]),&(map[1][i]),&(map[2][i])); } fclose(f); gettimeofday(&tComm1, NULL); /* Open file to print */ f = fopen(argv[8],"w"); fprintf(f, "P6\n%d %d\n255\n", disp_width, disp_height); for (i = 1; i < size; i++){ MPI_Recv(&slaveID, 1, MPI_INT, MPI_ANY_SOURCE, ID_TAG, MPI_COMM_WORLD, &status); /* calculate the width for that processor*/ slaveWidth = colPerSlave + (disp_width%(size-1) >= rank ? 1 : 0); slaveStartCol = (colPerSlave * (slaveID - 1)) + (slaveID > disp_width%(size-1) ? disp_width%(size-1) : slaveID-1); MPI_Recv(&pic[slaveStartCol*disp_height], disp_height*slaveWidth, MPI_INT, slaveID, DATA_TAG, MPI_COMM_WORLD, &status); printf("Master received from SlaveId = %d from Column = %d\n", slaveID, slaveStartCol); } gettimeofday(&tComm2, NULL); printTime(rank, tComm1, tComm2); gettimeofday(&tIO1, NULL); /* Print the picture */ for (y=0; y<disp_height; y++) { for (x=0; x<disp_width; x++) { static unsigned char color[3]; color[0] = map[0][pic[x*disp_height + y]]; // red color[1] = map[1][pic[x*disp_height + y]]; // green color[2] = map[2][pic[x*disp_height + y]]; // blue (void)fwrite(color, 1, 3, f); } } fclose(f); gettimeofday(&tIO2, NULL); printTime(rank, tIO1, tIO2); } /************************** SLAVES ******************************/ else if (rank > MASTER){ gettimeofday(&tCal1, NULL); /* calculate the width for that processor*/ slaveWidth = colPerSlave + (disp_width%(size-1) >= rank ? 1 : 0); slaveStartCol = (colPerSlave * (rank - 1)) + (rank > disp_width%(size-1) ? disp_width%(size-1) : rank-1); /* Allocate Memory for the slave part of the picture */ pic = (int *)malloc(slaveWidth*disp_height*sizeof(int)); printf("slaveWidth = %d, slaveStartCol = %d\n", slaveWidth, slaveStartCol); /* Compute scaling factors */ scale_real = (real_max-real_min)/disp_width; scale_imag = (imag_max-imag_min)/disp_height; for (x=slaveStartCol, xIndex = 0; x<slaveStartCol + slaveWidth; x++, xIndex++) { for (y=0; y<disp_height; y++) { c.real = real_min + ((float) x * scale_real); c.imag = imag_min + ((float) y * scale_imag); i = cal_pixel(c); pic[xIndex*disp_height + y] = i; } } gettimeofday(&tCal2, NULL); printTime(rank, tCal1, tCal2); printf("SlaveID = %d Sending back from Column = %d\n", rank, slaveStartCol); /* Send back the Pic Part */ MPI_Send(&rank, 1, MPI_INT, MASTER, ID_TAG, MPI_COMM_WORLD); MPI_Send(pic, slaveWidth * disp_height, MPI_INT, MASTER, DATA_TAG, MPI_COMM_WORLD); /* ****************** End of WORKER ****************** */ } gettimeofday(&tG2, NULL); printTime(rank, tG1, tG2); MPI_Finalize(); }