/*initiate the Environment*/ void initEnv(int argc, char** argv) { int err; err = MPI_Init(&argc, &argv); /* Initialize MPI */ if (err != MPI_SUCCESS) { printf("MPI_init failed!\n"); exit(1); } err = MPI_Comm_size(MPI_COMM_WORLD, &np); /* Get nr of tasks */ if (err != MPI_SUCCESS) { printf("MPI_Comm_size failed!\n"); MPI_Finalize(); exit(1); } if(np < 2) { printf("At least 2 processes are needed\n"); MPI_Finalize(); exit(1); } err = MPI_Comm_rank(MPI_COMM_WORLD, &id); /* Get id of this process */ if (err != MPI_SUCCESS) { printf("MPI_Comm_rank failed!\n"); MPI_Finalize(); exit(1); } MPE_Open_graphics(&graph, MPI_COMM_WORLD, NULL, 0, 0, W, H, 0 ); MPE_Make_color_array(graph, 256, color); }
void simulate(const int tmax, int rank, int size, const int gran, body *bodies){ int t=tmax, i, round; int sendto = (rank + 1) % size; int recvfrom = ((rank + size) - 1) % size; MPI_Datatype bodytype; MPI_Type_contiguous(3, MPI_DOUBLE, &bodytype); MPI_Type_commit(&bodytype); MPI_Status status; MPE_XGraph bodyWin; int winSize = 800; body *inbuf = (body *) malloc(gran*sizeof(body)); body *outbuf = (body *) malloc(gran*sizeof(body)); fvp *f = (fvp *) malloc(gran*sizeof(fvp)); fvp *v = (fvp *) malloc(gran*sizeof(fvp)); for(i=0; i < gran; i++){ v[i].x=0; v[i].y=0; } MPE_Open_graphics(&bodyWin,MPI_COMM_WORLD,NULL,-1,-1,winSize,winSize,0); while(1){ --t; round=size; memcpy(outbuf, bodies, gran*sizeof(body)); frcInit(gran, bodies, f); while (round > 1) { --round; if (!(rank % 2)){ MPI_Send(outbuf, gran, bodytype, sendto, 0, MPI_COMM_WORLD); MPI_Recv(inbuf, gran, bodytype, recvfrom, 0, MPI_COMM_WORLD, &status); } else { MPI_Recv(inbuf, gran, bodytype, recvfrom, 0, MPI_COMM_WORLD, &status); MPI_Send(outbuf, gran, bodytype, sendto, 0, MPI_COMM_WORLD); } memcpy(outbuf, inbuf, gran*sizeof(body)); frcUpdt(gran, bodies, inbuf, f); } posUpdt(gran, bodies, f, v); for(i=0; i<gran; i++) MPE_Draw_circle(bodyWin,bodies[i].x,bodies[i].y,2,(rank*gran+i)%15+1); MPE_Update(bodyWin); usleep(300000); if(t > 0) for(i=0;i<gran;i++) MPE_Draw_circle(bodyWin,bodies[i].x,bodies[i].y,2,MPE_WHITE); if(t==0) break; } MPE_Close_graphics(&bodyWin); free(inbuf); free(outbuf); free(f); free(v); }
int main( int argc, char** argv ) { MPE_XGraph graph; int ierr, mp_size, my_rank; MPE_Color my_color; char ckey; /* char displayname[MPI_MAX_PROCESSOR_NAME+4] = ""; */ MPI_Init( &argc, &argv ); MPI_Comm_size( MPI_COMM_WORLD, &mp_size ); MPI_Comm_rank( MPI_COMM_WORLD, &my_rank ); /* if ( my_rank == 0 ) strcpy( displayname, getenv( "DISPLAY" ) ); MPI_Bcast( displayname, MPI_MAX_PROCESSOR_NAME+4, MPI_CHAR, 0, MPI_COMM_WORLD ); fprintf( stdout, "%d : $DISPLAY at process 0 = %s\n", my_rank, displayname ); fflush( stdout ); ierr = MPE_Open_graphics( &graph, MPI_COMM_WORLD, displayname, -1, -1, 400, 400, 0 ); */ ierr = MPE_Open_graphics( &graph, MPI_COMM_WORLD, NULL, -1, -1, 400, 400, 0 ); if ( ierr != MPE_SUCCESS ) { fprintf( stderr, "%d : MPE_Open_graphics() fails\n", my_rank ); ierr = MPI_Abort( MPI_COMM_WORLD, 1 ); exit(1); } my_color = (MPE_Color) (my_rank + 1); if ( my_rank == 0 ) ierr = MPE_Draw_string( graph, 187, 205, MPE_BLUE, "Hello" ); ierr = MPE_Draw_circle( graph, 200, 200, 20+my_rank*5, my_color ); ierr = MPE_Update( graph ); if ( my_rank == 0 ) { fprintf( stdout, "Hit any key then return to continue " ); fscanf( stdin, "%s", &ckey ); fprintf( stdout, "\n" ); } MPI_Barrier( MPI_COMM_WORLD ); ierr = MPE_Close_graphics( &graph ); MPI_Finalize(); return 0; }
int main(int argc, char **argv) { int myrank, nums; int namelen; char myHostname[MPI_MAX_PROCESSOR_NAME]; MPI_Init(&argc, &argv); MPI_Comm_size(MPI_COMM_WORLD, &nums); MPI_Comm_rank(MPI_COMM_WORLD, &myrank); MPI_Get_processor_name(myHostname, &namelen); // graphic handle: MPE_XGraph window; //create window of size 100x100 MPE_Open_graphics(&window,MPI_COMM_WORLD,NULL,-1,-1,100,100,0); //draw a black point at x=5*(myrank+1) and y=50 MPE_Draw_point(window,5*(myrank+1),50,MPE_BLACK); // update draws the picture on the screen MPE_Update(window); sleep(10); //sleep for 10 seconds and close window MPE_Close_graphics(&window); return 0; }
static void DrawScreen_0(int procid, int np) { int width, procNum, radius; double angle; readyToDraw_0 = 0; procCoords_0 = (point *) malloc( sizeof( point ) * np ); radius = (PROC_SEPARATION_0*np)/3.1416; width = (radius + PROC_RADIUS_0) * 2 * MARGIN_0; MPE_Open_graphics( &prof_graph_0, MPI_COMM_WORLD, 0, xpos_0, ypos_0, width, width, 0 ); readyToDraw_0 = 1; if (procid == 0) MPE_Fill_rectangle( prof_graph_0, 0, 0, width, width, MPE_WHITE ); MPE_Draw_logic( prof_graph_0, MPE_LOGIC_INVERT ); for (procNum=0; procNum < np; procNum++) { angle = (((double)procNum)/np)*3.1416*2 + 3.1416/2; procCoords_0[procNum].x = width/2 + radius * cos( angle ); procCoords_0[procNum].y = width/2 - radius * sin( angle ); if (procid_0 == 0) { MPE_Fill_circle( prof_graph_0, procCoords_0[procNum].x, procCoords_0[procNum].y, PROC_RADIUS_0, MPE_GREEN ); } } MPE_Update( prof_graph_0 ); }
int main(int argc, char* argv[]) { const int WINDOW_SIZE = 1024; int n,ix, iy, i; double spacing=.005, x, y, c_real, c_imag, x_center = 0.0, y_center = 0.0; int cur_rank, total_process, message; int tag = 199; MPI_Status status; double starttime, endtime; #ifdef USE_MPE MPE_XGraph graph; #endif MPI_Init(&argc,&argv); MPI_Comm_rank(MPI_COMM_WORLD, &cur_rank); MPI_Comm_size(MPI_COMM_WORLD, &total_process); #ifdef USE_MPE MPE_Open_graphics( &graph, MPI_COMM_WORLD, getDisplay(), -1, -1, WINDOW_SIZE, WINDOW_SIZE, 0 ); #endif i=0; MPI_Send(&cur_rank,1, MPI_INT, cur_rank, tag, MPI_COMM_WORLD); while(1) { MPI_Recv(&message, 1, MPI_INT, cur_rank, tag, MPI_COMM_WORLD, &status); iy = message; for (ix = 0; ix < WINDOW_SIZE; ix++) { c_real=(ix - 400) * spacing - x_center; c_imag=(iy - 400) * spacing - y_center; x = y = 0.0; n = 0; while (n < 50 && distance(x,y) < 4.0) { compute(x,y,c_real,c_imag,&x,&y); n++; } if (n < 50) { #ifdef USE_MPE MPE_Draw_point(graph,ix,iy,MPE_RED); #else //fprintf (stdout, "%d,%d,RED\n", ix, iy); #endif } else { #ifdef USE_MPE MPE_Draw_point(graph,ix,iy,MPE_BLACK); #else //fprintf (stdout, "%d,%d,BLACK\n", ix, iy); #endif } } int nextRowIndex = message + total_process; if( nextRowIndex > WINDOW_SIZE) break; else MPI_Send(&nextRowIndex,1, MPI_INT, cur_rank, tag, MPI_COMM_WORLD); } getchar(); #ifdef USE_MPE MPE_Close_graphics( &graph ); #endif MPI_Finalize(); return 0; }
double life( int matrix_size, int ntimes, MPI_Comm comm ) { int rank, size ; int next, prev ; int i, j, k; int mysize, sum ; int **matrix, **temp, **addr ; double slavetime, totaltime, starttime ; int my_offset; /* Determine size and my rank in communicator */ MPI_Comm_size(comm, &size) ; MPI_Comm_rank(comm, &rank) ; /* Set neighbors */ if (rank == 0) prev = MPI_PROC_NULL; else prev = rank-1; if (rank == size - 1) next = MPI_PROC_NULL; else next = rank+1; /* Determine my part of the matrix */ mysize = matrix_size/size + ((rank < (matrix_size % size)) ? 1 : 0 ) ; my_offset = rank * (matrix_size/size); if (rank > (matrix_size % size)) my_offset += (matrix_size % size); else my_offset += rank; /* allocate the memory dynamically for the matrix */ matrix = (int **) malloc(sizeof(int *)*(mysize+2)) ; temp = (int **) malloc(sizeof(int *)*(mysize+2)) ; for (i = 0; i < mysize+2; i++) { matrix[i] = (int *) malloc(sizeof(int)*(matrix_size+2)) ; temp[i] = (int *) malloc(sizeof(int)*(matrix_size+2)) ; } /* Initialize the boundaries of the life matrix */ for (j = 0; j < matrix_size+2; j++) matrix[0][j] = matrix[mysize+1][j] = temp[0][j] = temp[mysize+1][j] = DIES ; for (i = 0; i < mysize+2; i++) matrix[i][0] = matrix[i][matrix_size+1] = temp[i][0] = temp[i][matrix_size+1] = DIES ; /* Initialize the life matrix */ for (i = 1; i <= mysize; i++) { srand48((long)(1000^(i-1+mysize))) ; for (j = 1; j<= matrix_size; j++) if (drand48() > 0.5) matrix[i][j] = BORN ; else matrix[i][j] = DIES ; } /* Open the graphics display */ MPE_Open_graphics( &graph, MPI_COMM_WORLD, displayname, -1, -1, width, height, 0 ); /* Play the game of life for given number of iterations */ starttime = MPI_Wtime() ; for (k = 0; k < ntimes; k++) { MPI_Request req[4]; MPI_Status status[4]; /* Send and receive boundary information */ MPI_Isend(&matrix[1][0],matrix_size+2,MPI_INT,prev,0,comm,req); MPI_Irecv(&matrix[0][0],matrix_size+2,MPI_INT,prev,0,comm,req+1); MPI_Isend(&matrix[mysize][0],matrix_size+2,MPI_INT,next,0,comm,req+2); MPI_Irecv(&matrix[mysize+1][0],matrix_size+2,MPI_INT,next,0,comm,req+3); MPI_Waitall(4, req, status); /* For each element of the matrix ... */ for (i = 1; i <= mysize; i++) { for (j = 1; j < matrix_size+1; j++) { /* find out the value of the current cell */ sum = matrix[i-1][j-1] + matrix[i-1][j] + matrix[i-1][j+1] + matrix[i][j-1] + matrix[i][j+1] + matrix[i+1][j-1] + matrix[i+1][j] + matrix[i+1][j+1] ; /* check if the cell dies or life is born */ if (sum < 2 || sum > 3) temp[i][j] = DIES ; else if (sum == 3) temp[i][j] = BORN ; else temp[i][j] = matrix[i][j] ; { int xloc, yloc, xwid, ywid; xloc = ((my_offset + i - 1) * width) / matrix_size; yloc = ((j - 1) * height) / matrix_size; xwid = ((my_offset + i) * width) / matrix_size - xloc; ywid = (j * height) / matrix_size - yloc; MPE_Fill_rectangle( graph, xloc, yloc, xwid, ywid, temp[i][j] ); } } } MPE_Update( graph ); /* Swap the matrices */ addr = matrix ; matrix = temp ; temp = addr ; } /* Return the average time taken/processor */ slavetime = MPI_Wtime() - starttime; MPI_Reduce(&slavetime, &totaltime, 1, MPI_DOUBLE, MPI_SUM, 0, comm); return (totaltime/(double)size); }
main(int argc, char* argv[]) { int me, np, i; int x, y, w, h; int x1, y1, x2, y2; int color, button, pressed; int space, num_colors; MPE_Color col_array[64]; /* Color array */ MPE_Point points[80]; /* Array to store 80 pixels in */ w=10; h=20; /* Width and height of colored rectangles */ MPI_Init (&argc, &argv); /* Initialize MPI */ MPI_Comm_size(MPI_COMM_WORLD, &np); /* Get nr of processes */ MPI_Comm_rank(MPI_COMM_WORLD, &me); /* Get own id */ /* Check that we have exactly two processes */ if (np != 2) { if (me == 0) printf("You have to run this program with 2 processes\n"); MPI_Finalize(); exit(0); } if (me == 0) printf("Opening a graphics window\n") ; /* Open the graphics window in position (0,0) on the display */ MPE_Open_graphics(&graph, MPI_COMM_WORLD, displayname, 0, 0, width, height, 0 ); /* Get number of colors */ MPE_Num_colors(graph, &num_colors); if (me == 0) { printf("Number of colors = %d,\n", num_colors) ; } /* Processor 0 puts a pink rectangle of size 100*240 in position (0,0) */ if (me==0) { MPE_Fill_rectangle( graph, 0, 0, 100, 240, MPE_PINK ); MPE_Update( graph ); } /* Both processors draws one rectangle for each colour, placed in a row */ x=0; y=(me)*50; space=2; for (color=0; color<num_colors; color++) { x=x+w+space; /* Set position of rectangles */ MPE_Fill_rectangle( graph, x, y, w, h, color ); } MPE_Update( graph ); /* Create a new color array with 64 colours */ MPE_Make_color_array(graph, 64, col_array); /* Get number of colors */ MPE_Num_colors(graph, &num_colors); if ( me == 0 ) { printf("Number of colors = %d,\n", num_colors) ; } /* Both processors draw one rectangle for each colour, placed in a row */ x=0; y=(me+1)*100; for (color=0; color<num_colors; color++) { x=x+w+space; /* Set position of rectangles */ MPE_Fill_rectangle( graph, x, y, w, h, color ); } MPE_Update( graph ); /* Set lines to be 2 pixels thick */ MPE_Line_thickness(graph, 2); /* Both processes draw a line, each with different color */ MPE_Draw_line(graph, 300+(20*me), 10+(20*me), 800+(20*me), 70+(20*me), 30+(20*me)); MPE_Update( graph ); /* Both processes draw a circle of different size and color */ MPE_Draw_circle(graph, 100+(50*me), 300+(50*me), 20+(5*me), num_colors-(20*me)); MPE_Update(graph); /* Both processes draw 50 pixels with different colors */ for (i=0; i<50; i++) { int rx, ry; rx = 200+rand()%15; /* Random positions where to draw points */ ry = 300+rand()%15+40*me; MPE_Draw_point(graph, rx, ry, num_colors-(20*me)); } MPE_Update(graph); /* Build 80 pixels with randomly chosen colors in the array points */ for (i=0; i<80; i++) { points[i].x = 250+rand()%15; /* Set x coordinate */ points[i].y = 300+rand()%15+40*me; /* Set y coordinate */ points[i].c = rand()%num_colors; /* Set a color */ } MPE_Draw_points(graph, points, 80); /* Draw all 80 points */ MPE_Update(graph); /* Draw a text string */ MPE_Draw_string(graph, 400, 250, MPE_BLACK, "Hello from MPE_Draw_string"); MPE_Update(graph); /* Wait until the user selects a region of the graph, using button 1 */ /* Print out the coordinates of the selected region and draw a black */ /* rectangle around the selected region */ button=1; /* Use button 1 */ if (me==0) { printf("Select a region of the graph using mouse button %d\n", button); MPE_Get_drag_region( graph, button, MPE_DRAG_RECT, &x1, &y1, &x2, &y2 ); printf("Selected region is (%d,%d) to (%d,%d)\n", x1, y1, x2, y2); /* Draw a black rectangle around the selected area */ /* This should of course be implemented in a procedure MPE_Draw_rectangle */ /* Maybe I will write one some day ... */ MPE_Draw_line(graph, x1, y1, x1, y2, MPE_BLACK); MPE_Draw_line(graph, x1, y2, x2, y2, MPE_BLACK); MPE_Draw_line(graph, x2, y2, x2, y1, MPE_BLACK); MPE_Draw_line(graph, x2, y1, x1, y1, MPE_BLACK); MPE_Update(graph); } /* Wait until the user presses a mouse button */ if (me == 0) { printf("Press a mouse button to terminate\n"); MPE_Get_mouse_press(graph, &x, &y, &button); printf("User clicked button %d in position (%d,%d)\n", button, x, y); } /* We can also poll the mouse buttons with MPE_Iget_mouse_pressed */ /* pressed = 0; */ /* if (me == 0) { */ /* do { */ /* MPE_Iget_mouse_press(graph, &x, &y, &button, &pressed); */ /* } while (!pressed); */ /* printf("User clicked button %d in position (%d,%d)\n", button, x, y); */ /* } */ /* Wait here for terminationn signal from process 0 */ /* MPI_Barrier(MPI_COMM_WORLD); */ /* Close the graphics window and terminate */ MPE_Close_graphics(&graph); MPI_Finalize(); exit(0); }
int main( int argc, char *argv[] ) { int numprocs, myid, server, workerid, ranks[1], request, i, iter, ix, iy, done; long rands[CHUNKSIZE], max, in, out, totalin, totalout; double x, y, Pi, error, epsilon; MPI_Comm world, workers; MPI_Group world_group, worker_group; MPI_Status status; MPI_Init( &argc, &argv ); world = MPI_COMM_WORLD; MPI_Comm_size( world, &numprocs ); MPI_Comm_rank( world, &myid ); server = numprocs-1; // Last process is a random server /*** * Now Master should read epsilon from command line * and distribute it to all processes. */ if (myid == 0) // Read epsilon from command line sscanf( argv[1], "%lf", &epsilon ); MPI_Bcast( &epsilon, 1, MPI_DOUBLE, 0, MPI_COMM_WORLD ); /*** * Create new process group called world_group containing all * processes and its communicator called world * and a group called worker_group containing all processes * except the last one (called here server) * and its communicator called workers. */ MPI_Comm_group( world, &world_group ); ranks[0] = server; MPI_Group_excl( world_group, 1, ranks, &worker_group ); MPI_Comm_create( world, worker_group, &workers ); MPI_Group_free( &worker_group ); MPE_XGraph graph; MPE_Open_graphics(&graph,MPI_COMM_WORLD,(char*)0, -1,-1,WINDOW_SIZE,WINDOW_SIZE,MPE_GRAPH_INDEPENDENT); /*** * Server part * * Server should loop until request code is 0, in each iteration: * - receiving request code from any slave * - generating a vector of CHUNKSIZE randoms <= INT_MAX * - sending vector back to slave */ if (myid == server) { // I am the random generator server do { MPI_Recv( &request, 1, MPI_INT, MPI_ANY_SOURCE, REQUEST, world, &status ); if (request) { for (i = 0; i < CHUNKSIZE; ) { rands[i] = rand(); if ( rands[i] <= INT_MAX ) i++; } MPI_Send( rands, CHUNKSIZE, MPI_LONG, status.MPI_SOURCE, REPLY, world ); } } while( request > 0 ); } /*** * Workers (including Master) part * * Worker should send initial request to server. * Later, in a loop worker should: * - receive vector of randoms * - compute x,y point inside unit square * - check (and count result) if point is inside/outside * unit circle * - sum both counts over all workers * - calculate pi and its error (from "exact" value) * - test if error is within epsilon limit * - test continuation condition (error and max. points limit) * - print pi by master only * - send a request to server (all if more or master only if finish) * Before finishing workers should free their communicator. */ else { // I am a worker process request = 1; done = 0; in = out = 0; max = INT_MAX; // max int, for normalization MPI_Send( &request, 1, MPI_INT, server, REQUEST, world ); MPI_Comm_rank( workers, &workerid ); iter = 0; while (!done) { iter++; request = 1; MPI_Recv( rands, CHUNKSIZE, MPI_LONG, server, REPLY, world, &status ); for (i = 0; i < CHUNKSIZE - 1; ) { x = (((double) rands[i++])/max) * 2 - 1; y = (((double) rands[i++])/max) * 2 - 1; if ( x*x + y*y < 1.0 ) { MPE_Draw_point(graph,(int)(WINDOW_SIZE/2+x*WINDOW_SIZE/2),(int)(WINDOW_SIZE+y*WINDOW_SIZE/2),MPE_RED); in++; } else out++; } MPI_Allreduce( &in, &totalin, 1, MPI_LONG, MPI_SUM, workers ); MPI_Allreduce( &out, &totalout, 1, MPI_LONG, MPI_SUM, workers ); Pi = ( 4.0 * totalin ) / ( totalin + totalout ); error = fabs( Pi - PI ); done = ( error < epsilon || (totalin + totalout) > THROW_MAX ); request = (done) ? 0 : 1; MPE_Update(graph); if (myid == 0) { printf( "\rpi = %23.20f", Pi ); MPI_Send( &request, 1, MPI_INT, server, REQUEST, world ); } else { if (request) MPI_Send( &request, 1, MPI_INT, server, REQUEST, world ); } } MPI_Comm_free( &workers ); } /*** * Master should print final point counts. */ if (myid == 0) { printf( "\npoints: %ld\nin: %ld, out: %ld, <ret> to exit\n", totalin+totalout, totalin, totalout ); getchar(); } MPE_Close_graphics(graph); MPI_Finalize(); return 0; }