#include <cm/cmmd.h> #include <cm/timers.h> #include <math.h> #include "fish.h" #define RANDOM(r) ((random()%10000)*r/10000.0) #define DT 0.1 /* time step resolution */ #define SIZE 256 /* width of ocean */ #define PROCS CMMD_partition_size() #define ME CMMD_self_address() float cell[10][SIZE+2]; /* cell owned by each proc */ float count[10][SIZE+2]; /* neighbor counts */ /* the procs are laid from top to down in a 1-D array*/ main() { struct arg_data args; int fish; int tsteps; int psteps; int x,y; int i,j,k,t; int next_proc; int ROW; CMMD_enable_host (); CMMD_receive_bc_from_host (&args, sizeof (struct arg_data)); fish = args.fish; tsteps = args.tsteps; psteps = args.psteps; CMNA_timer_clear (0); CMNA_timer_start (0); ROW = SIZE/PROCS; /* initialize random number generator */ srandom(CMMD_self_address()); /* initialize cell */ for (i=0;i<ROW+2;++i) for (j=0;j<SIZE+2;++j) cell[i][j]=0; /* place the fish in the cell */ for (i=0;i<fish;++i) { x = RANDOM(ROW); y = RANDOM(SIZE); cell[x+1][y+1] = 1; } /* loop over all time steps */ for (k=0,t=0;t<tsteps;++t) { /* exchange boundary row for odd/even procs */ if (CMMD_self_address()%2) { next_proc = (ME + 1) % PROCS; CMMD_swap(next_proc,&cell[ROW+1][1],sizeof(float)*SIZE, &cell[ROW][1],sizeof(float)*SIZE); } else { next_proc = (ME - 1 + PROCS) % PROCS; CMMD_swap(next_proc,&cell[0][1],sizeof(float)*SIZE, &cell[1][1],sizeof(float)*SIZE); } /* exchange boundary row for even/odd procs */ if (CMMD_self_address()%2) { next_proc = (ME - 1 + PROCS) % PROCS; CMMD_swap(next_proc,&cell[0][1],sizeof(float)*SIZE, &cell[1][1],sizeof(float)*SIZE); } else { next_proc = (ME + 1) % PROCS; CMMD_swap(next_proc,&cell[ROW+1][1],sizeof(float)*SIZE, &cell[ROW][1],sizeof(float)*SIZE); } /* enforce boundary condition */ if (ME == 0) for (i=0;i<SIZE+2;++i) cell[0][i] = 0; if (ME+1 == PROCS) for (i=0;i<SIZE+2;++i) cell[ROW+1][i] = 0; /* compute number of neighbors */ for (i=1;i<=ROW;++i) for (j=1;j<=SIZE;++j) count[i][j] = cell[i-1][j-1] + cell[i-1][j] + cell[i-1][j+1] + cell[i][j-1] + cell[i][j+1] + cell[i+1][j-1] + cell[i+1][j] + cell[i+1][j+1]; /* determine life or death */ for (i=1;i<=ROW;++i) for (j=1;j<=SIZE;++j) if ((cell[i][j]==0)&&(count[i][j]==3)) cell[i][j] = 1; else if (count[i][j]<=1) cell[i][j] = 0; else if (count[i][j]>=4) cell[i][j] = 0; /* send info. to host for display */ if (++k > psteps) { k = 0; CMMD_send(CMMD_host_node(),0,&cell[1][0], sizeof(float)*ROW*(SIZE+2)); } } /* synchronize with host to end program */ CMNA_timer_stop (0); CMMD_reduce_to_host_double (CMNA_timer_busy (0), CMMD_combiner_dmax); return; }