+++ /dev/null
-
- /**********************************/
- /* */
- /* The Mandelbrot Set */
- /* */
- /* z = z*z + c */
- /* */
- /* parallel version */
- /* */
- /* MPE graph version */
- /* */
- /**********************************/
-
- /* Michel Vallieres */
-
-#include <stdio.h>
-#include <time.h>
-#include "mpi.h"
-#include "mpe.h"
-#include "mpe_graphics.h"
- /* large distance; if |z| reaches */
- /* it, point C is not a member */
- /* of the set */
-#define LARGE_RADIUS 2.0
- /* Maximum number of iterations */
- /* before declaring a point in */
- /* the Mandelbrot set */
-#define MAX_ITERATIONS 80
-#define NX 600 /* image size */
-#define NY 500
-#define N_STRIPE 37 /* number of stripes */
-#define MAX_PROC 100 /* max # of processes */
-
-
- /* prototypes */
-void compute_stripe( double crmin, double crmax, double cimin, double cimax,
- int i_min, int i_max, MPE_Point store_points[],
- int *store_n, MPE_Color colors[], int nc );
-void grid_stripes( double *crmin, double *crmax, double *cimin, double *cimax,
- int begin_stripe[], int last_stripe[] );
-int quit_by_touch( MPE_XGraph graph, int WINDOW_SIZE_X, int WINDOW_SIZE_Y );
-
-
-
-int main( int argc, char *argv[] )
-{
- double crmin, crmax, cimin, cimax;
- double global_store_iter[NY*NX];
- int begin_stripe[N_STRIPE], last_stripe[N_STRIPE];
- int stripe;
- int store_n, i_point, offset;
- int count;
- int myid, numprocs;
- MPI_Status mesgStatus;
- int stripe_in_proc[MAX_PROC], sent_stripe, recv_stripe, from_node,
- from_stripe, number_from_node, ip;
- int end_signal;
- int I_am_done, done_signal;
- int nc;
- MPE_XGraph graph;
- MPE_Point store_points[NY*(NX/N_STRIPE+1)];
- MPE_Color colors[500];
-
- /* start the MPI virtual machine */
- MPI_Init(&argc,&argv);
- MPI_Comm_size(MPI_COMM_WORLD,&numprocs);
- MPI_Comm_rank(MPI_COMM_WORLD,&myid);
-
- /* start MPE graphics */
- MPE_Open_graphics( &graph, MPI_COMM_WORLD, 0, -1, -1, NX, NY, 0 );
-
- /* make a new color palette */
- nc = 127;
- MPE_Make_color_array( graph, nc, colors );
-
-
- /* initialize grid & stripes */
- grid_stripes ( &crmin, &crmax, &cimin, &cimax, begin_stripe, last_stripe );
-
-
- /*****************/
- /* Master code */
- /*****************/
- if ( myid == 0 )
- {
-
- count = 0;
-
- /* initilalize send counter */
- sent_stripe = 0;
- /* send a stripe to each slave */
- /* to start local calculation */
- for ( ip=1 ; ip<numprocs ; ip++ )
- {
- MPI_Ssend( &sent_stripe, 1, MPI_INT, ip, 5, MPI_COMM_WORLD );
- stripe_in_proc[ip] = sent_stripe;
- sent_stripe++;
- }
- /* receive results back from nodes */
- for ( recv_stripe = 0 ; recv_stripe < N_STRIPE ; recv_stripe++ )
- {
- MPI_Recv( &done_signal, 1, MPI_DOUBLE,
- MPI_ANY_SOURCE, 7, MPI_COMM_WORLD, &mesgStatus );
- from_node = mesgStatus.MPI_SOURCE;
- from_stripe = stripe_in_proc[from_node];
-
- fprintf ( stderr, " From node: %d -- stripe & # %d \n",
- from_node, stripe_in_proc[from_node] );
-
- /* new stripe for this slave */
- if ( sent_stripe < N_STRIPE )
- {
-
- fprintf( stderr, "Node %d will send stripe = %d to node %d\n",
- myid, sent_stripe, from_node );
-
- MPI_Ssend( &sent_stripe, 1, MPI_INT, from_node, 5, MPI_COMM_WORLD );
- stripe_in_proc[from_node] = sent_stripe;
- sent_stripe++;
- }
-
- }
- /* all stripes done */
- /* wait for a touch - quit */
- quit_by_touch( graph, NX, NY );
- /* kill slave processes */
- for ( ip=1 ; ip<numprocs ; ip++ )
- {
- end_signal = -2;
- MPI_Ssend( &end_signal, 1, MPI_INT, ip, 5, MPI_COMM_WORLD );
- }
- /* end MPI virtual machine */
- /* end graphics in master */
- MPE_Close_graphics( &graph );
- MPI_Finalize();
- exit(0);
- }
- /*****************/
- /* Slave code */
- /*****************/
- else
- {
- /* loop for more stripes until */
- for ( ; ; ) /* negative signal received */
- {
- /* receive a stripe to do */
- MPI_Recv( &stripe, 1, MPI_INT, 0, 5, MPI_COMM_WORLD,
- &mesgStatus );
-
- fprintf( stderr, "From within node: %d -- Stripe: %d \n", myid, stripe );
-
- /* end graphics and MPI */
- if ( stripe == -2 )
- {
-
- fprintf( stderr,"Node %d exiting \n", myid);
- MPE_Close_graphics( &graph );
- MPI_Finalize();
- exit(0);
- }
- /* find the points in the set */
- compute_stripe( crmin, crmax, cimin, cimax, begin_stripe[stripe],
- last_stripe[stripe], store_points, &store_n,
- colors, nc );
-
- /* send done signal to master */
- I_am_done = 1 ;
- MPI_Ssend( &I_am_done, 1, MPI_INT, 0, 7, MPI_COMM_WORLD );
-
- /* draw the points in the stripe */
- MPE_Draw_points( graph, store_points, store_n);
- /* update the graph */
- MPE_Update( graph );
-
- }
- }
-
-}
-
-
-
-
-void grid_stripes( double *crmin, double *crmax, double *cimin, double *cimax,
- int begin_stripe[], int last_stripe[] )
-{
- int w_stripe, stripe, left_over;
- /* define grid spanning */
- /* the complex plane for */
- /* the C variable */
- *crmin =-1.7;
- *crmax = 0.8;
- *cimin = -1.0;
- *cimax = 1.0;
- /* stripe definition */
- /* stripe # does not have to be */
- /* commensurate with grid size */
- /* in which case add 1 to some */
- /* stripes */
- w_stripe= NX/N_STRIPE;
- left_over = NX % N_STRIPE;
- /* fist stripe */
- begin_stripe[0] = 0;
- last_stripe[0] = begin_stripe[0] + w_stripe - 1;
- if ( left_over > 0 )
- {
- last_stripe[0] = last_stripe[0] + 1;
- left_over--;
- }
- /* other stripes */
- for ( stripe = 1; stripe < N_STRIPE ; stripe++ )
- {
- begin_stripe[stripe] = last_stripe[stripe-1] + 1 ;
- last_stripe[stripe] = begin_stripe[stripe] + w_stripe - 1;
- if ( left_over > 0 )
- {
- last_stripe[stripe] = last_stripe[stripe] + 1;
- left_over--;
- }
- }
-}
-
-
-
-
-void compute_stripe( double crmin, double crmax, double cimin, double cimax,
- int i_min, int i_max, MPE_Point store_points[],
- int *store_n, MPE_Color colors[], int nc )
-{
- double z_real, z_img, z_magnitude;
- double c_real, c_img, z_current_real;
- double dcr, dci;
- int i, j;
- int counter;
- int color_pointer;
-
- /* scan C values on complex plane */
- dcr = (crmax - crmin)/(double)(NX-1);
- dci = (cimax - cimin)/(double)(NY-1);
- /* scan stripe */
- *store_n=0;
- for ( i=i_min ; i<=i_max; i++ )
- {
- for ( j=0 ; j<NY; j++ )
- {
- c_real = crmin + i*dcr;
- c_img = cimin + j*dci;
- /* z starts a origin */
- z_real = 0.0;
- z_img = 0.0;
- /* set counter to zero */
- counter = 0;
- /* iterate map for */
- /* MAX_ITERATIONS times or ...*/
- while ( counter < MAX_ITERATIONS )
- {
- z_current_real = z_real;
- z_real = z_real*z_real - z_img*z_img + c_real;
- z_img = 2.0*z_current_real*z_img + c_img;
- counter = counter + 1;
- /* ... until magnitude of z */
- /* is larger than some */
- /* large radius */
- z_magnitude = z_real*z_real+z_img*z_img;
- if ( z_magnitude > LARGE_RADIUS ) break;
- }
- /* store iteration numbers */
- /* for use in ploting the set */
- store_points[*store_n].x = i;
- store_points[*store_n].y = j;
- color_pointer = (int)( (double)(nc*counter) / (double)MAX_ITERATIONS );
- store_points[*store_n].c = colors[ color_pointer];
- (*store_n)++;
- }
- }
-
-}
-
-
-
-
-
-int quit_by_touch( MPE_XGraph graph, int WINDOW_SIZE_X, int WINDOW_SIZE_Y )
-{
- /* interacting with graphic */
- int x, y, button, xc, yc, w, h, xs, ys;
-
- xc = 0; /* draw filled rectangle */
- yc = 0.95*WINDOW_SIZE_Y; /* lower left bottom */
- w = 0.05*WINDOW_SIZE_X; /* corner of graphic window */
- h = WINDOW_SIZE_Y - yc;
- /* write a -- Q -- in rectangle */
- MPE_Fill_rectangle( graph, xc, yc, w, h, MPE_BLACK );
- xs = xc + 0.4*w;
- ys = yc + 0.8*h;
- MPE_Draw_string( graph, xs, ys, MPE_WHITE, "Q" );
-
- /* infinite loop */
- /* wait for different touch */
- for ( ; ; )
- {
- /* wait for mouse to touch graph */
- /* can only be done by master */
- MPE_Get_mouse_press( graph, &x, &y, &button );
- /* result is touch point */
- fprintf( stderr, "\n Graph coordinates of the touch: %d %d %d \n", x, y, button );
- if ( x < xc+w && y > yc )
- {
- fprintf( stderr, "\n Last touch was in the -- quit -- rectangle \n\n" );
- return;
- }
- }
-}
-
-
-
-
-
-
-