Ejemplo n.º 1
0
/*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);
}
Ejemplo n.º 2
0
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);
}
Ejemplo n.º 3
0
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;
}
Ejemplo n.º 4
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;
}
Ejemplo n.º 5
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;
}
Ejemplo n.º 7
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);
}
Ejemplo n.º 8
0
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);
}
Ejemplo n.º 9
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;
}