2 /**********************************/
4 /* The Mandelbrot Set */
8 /* Adapted to calculate the Set */
9 /* in stripes parallel to Img axis*/
11 /* Improved routines structure */
12 /* to facilitate parallel */
14 /**********************************/
16 /* Michel Vallieres */
21 /* large distance; if |z| reaches */
22 /* it, point C is not a member */
24 #define LARGE_RADIUS 2.0
25 /* Maximum number of iterations */
26 /* before declaring a point in */
27 /* the Mandelbrot set */
28 #define MAX_ITERATIONS 80
29 #define NX 600 /* image size */
31 #define N_STRIPE 37 /* number of stripes */
35 void compute_stripe( double crmin, double crmax, double cimin, double cimax,
36 int i_min, int i_max, double store_iter[],
38 void grid_stripes( double *crmin, double *crmax, double *cimin, double *cimax,
39 int begin_stripe[], int last_stripe[] );
42 int main( int argc, char *argv[] )
44 double crmin, crmax, cimin, cimax;
45 double store_iter[NY*(NX/N_STRIPE+1)];
46 int begin_stripe[N_STRIPE], last_stripe[N_STRIPE];
50 int my_id, numprocs, ip;
51 int sent_stripe, recv_stripe, stripe_in_proc[MAX_PROCS];
52 int from_node, number_from_node;
55 MPI_Status mesgStatus;
57 MPI_Init(&argc, &argv); /* start MPI virtual machine */
59 MPI_Comm_rank(MPI_COMM_WORLD, &my_id);
60 MPI_Comm_size(MPI_COMM_WORLD, &numprocs);
63 /* initialize grid & stripes */
64 grid_stripes ( &crmin, &crmax, &cimin, &cimax, begin_stripe, last_stripe );
73 recv_stripe = 0; /* logic of stripes */
74 /* send original stripe to slaves */
75 for( ip = 1; ip < numprocs; ip++)
77 MPI_Ssend(&sent_stripe, 1, MPI_INT, ip, 5, MPI_COMM_WORLD);
78 stripe_in_proc[ip] = sent_stripe;
82 for( recv_stripe = 0; recv_stripe < N_STRIPE; recv_stripe++)
84 /* Recieve result back from a node */
85 MPI_Recv(store_iter, NY*(NX/N_STRIPE+1), MPI_DOUBLE, MPI_ANY_SOURCE, 7,
86 MPI_COMM_WORLD, &mesgStatus);
87 from_node = mesgStatus.MPI_SOURCE;
88 MPI_Get_count( &mesgStatus, MPI_DOUBLE, &number_from_node );
89 fprintf( stderr, "From node %d -- stripe & # %d %d \n", from_node,
90 stripe_in_proc[from_node], number_from_node );
91 /* Termination logic. */
93 fprintf( stderr, "I'm sending a termination signal to %d \n", from_node);
95 MPI_Ssend( &end_signal, 1, MPI_INT, from_node, 5, MPI_COMM_WORLD);
96 fprintf( stderr, "I have sent a termination signal to %d \n", from_node);
108 /* I'm getting a stripe to do, YAHOO! */
109 MPI_Recv(&stripe, 1, MPI_INT, 0, 5, MPI_COMM_WORLD, &mesgStatus);
110 fprintf(stderr, "my ID: %d -- recieved stripe: %d \n", my_id, stripe);
114 fprintf(stderr, "Node %d is quitting. \n", my_id);
119 /* find the points in the set */
120 compute_stripe( crmin, crmax, cimin, cimax, begin_stripe[stripe],
121 last_stripe[stripe], store_iter, &store_n);
123 /* send stripe results back to master */
124 MPI_Ssend(store_iter, store_n, MPI_DOUBLE, 0, 7, MPI_COMM_WORLD);
134 void grid_stripes( double *crmin, double *crmax, double *cimin, double *cimax,
135 int begin_stripe[], int last_stripe[] )
137 int w_stripe, stripe, left_over;
138 /* define grid spanning */
139 /* the complex plane for */
145 /* stripe definition */
146 /* stripe # does not have to be */
147 /* commensurate with grid size */
148 /* in which case add 1 to some */
150 w_stripe= NX/N_STRIPE;
151 left_over = NX % N_STRIPE;
154 last_stripe[0] = begin_stripe[0] + w_stripe - 1;
157 last_stripe[0] = last_stripe[0] + 1;
161 for ( stripe = 1; stripe < N_STRIPE ; stripe++ )
163 begin_stripe[stripe] = last_stripe[stripe-1] + 1 ;
164 last_stripe[stripe] = begin_stripe[stripe] + w_stripe - 1;
167 last_stripe[stripe] = last_stripe[stripe] + 1;
176 void compute_stripe( double crmin, double crmax, double cimin, double cimax,
177 int i_min, int i_max, double store_iter[],
180 double z_real, z_img, z_magnitude;
181 double c_real, c_img, z_current_real;
186 /* scan C values on complex plane */
187 dcr = (crmax - crmin)/(double)(NX-1);
188 dci = (cimax - cimin)/(double)(NY-1);
191 for ( i=i_min ; i<=i_max; i++ )
193 for ( j=0 ; j<NY; j++ )
195 c_real = crmin + i*dcr;
196 c_img = cimin + j*dci;
197 /* z starts a origin */
200 /* set counter to zero */
202 /* iterate map for */
203 /* MAX_ITERATIONS times or ...*/
204 while ( counter < MAX_ITERATIONS )
206 z_current_real = z_real;
207 z_real = z_real*z_real - z_img*z_img + c_real;
208 z_img = 2.0*z_current_real*z_img + c_img;
209 counter = counter + 1;
210 /* ... until magnitude of z */
211 /* is larger than some */
213 z_magnitude = z_real*z_real+z_img*z_img;
214 if ( z_magnitude > LARGE_RADIUS ) break;
216 /* store iteration numbers */
217 /* to plot the set */
218 store_iter[*store_n] =
219 (double)(255*counter) / (double)MAX_ITERATIONS ;