Changeset 2364 in /cluster/svnroot


Ignore:
Timestamp:
Apr 22, 2010 6:13:06 PM (11 years ago)
Author:
fitz
Message:

Cleaning up and additional refactoring of Life (#486)

Location:
bccd-ng/branches/fitz-devel/trees/home/bccd/Life
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • bccd-ng/branches/fitz-devel/trees/home/bccd/Life/Life.c

    • Property svn:executable deleted
    r2336 r2364  
    33// Copyright 2002, David Joiner and
    44//   The Shodor Education Foundation, Inc.
     5// Updated (c) 2010, Andrew Fitz Gibbon and
     6//   The Shodor Education Foundation, Inc.
    57////////////////////////////////////////////
    68
    7 #include <stdlib.h>
    8 #include <stdio.h>
    99#include "Life.h"
    10 #include "mpi.h"
    11 #include <time.h>
     10#include "XLife.h"
    1211
    13 #include <X11/Xlib.h> // Every Xlib program must include this
    14 #include <X11/Xutil.h>
    15 #include <assert.h>   // I include this to test return values the lazy way
    16 #include <unistd.h>   // So we got the profile for 10 seconds
    17 #define NIL (0)       // A name for the void pointer
    18 
    19 typedef unsigned int bool;
    20 #define false 0;
    21 #define true 1;
    22 
    23 #define MPI_TORIGHT 0
    24 #define MPI_TOLEFT 1
    25 
    26 MPI_Status mpi_status;
     12// defaults
     13const int  DEFAULT_GRID = 105;
     14const int  DEFAULT_GENS = 1000;
     15const bool DEFAULT_DISP = true;
     16const double  INIT_PROB = 0.25;
    2717
    2818int main(int argc, char ** argv) {
    29     int size;
    30     int rank;
    31     int ngrid;
    32     int ncols;
    33     int nrows;
    34     int max_count;
    35     int do_display;
    36     int count;
    37     int i,j;
    38     int ** grid;
    39     int ** next_grid;
     19        int rank, size;
     20        int ngrid, ncols, nrows;
     21        int generations;
     22        bool do_display;
     23        int count, i, j;
     24        int ** grid;
     25        int ** next_grid;
    4026
    41     // Set up MPI
    42     MPI_Init(&argc,&argv);
    43     MPI_Comm_rank(MPI_COMM_WORLD,&rank);
    44     MPI_Comm_size(MPI_COMM_WORLD,&size);
     27        // Set up MPI
     28        MPI_Init(&argc,&argv);
     29        MPI_Comm_rank(MPI_COMM_WORLD,&rank);
     30        MPI_Comm_size(MPI_COMM_WORLD,&size);
    4531
    46     random_initByTime(rank);
     32        random_initByTime(rank);
    4733
    48     // defaults
    49     ngrid=105;
    50     ncols=ngrid;
    51     nrows=ngrid;
    52     max_count=1000;
    53     do_display=1;
    54    
    55     // command line arguments
    56     if (argc > 1) {
    57         sscanf(argv[1],"%d",&nrows);
    58     }
    59     if (argc > 2) {
    60         sscanf(argv[2],"%d",&ncols);
    61     }
    62     if (argc > 3) {
    63         sscanf(argv[3],"%d",&max_count);
    64     }
    65     if (argc > 4) {
    66         sscanf(argv[4],"%d",&do_display);
    67     }
    68     if (do_display!=0) do_display=1;
     34        ngrid       = DEFAULT_GRID;
     35        ncols       = ngrid;
     36        nrows       = ngrid;
     37        generations = DEFAULT_GENS;
     38        do_display  = DEFAULT_DISP;
    6939
    70 
    71     allocate_grid(ncols, nrows, &grid);
    72     allocate_grid(ncols, nrows, &next_grid);
    73     randomize_grid(ncols, nrows, grid, 0.25);
    74     if (do_display==1)
    75         setupWindow(ncols, nrows);
    76     if (do_display==1)
    77         moveWindow(rank,size,ncols,nrows);
    78 
    79 
    80     bool done=false;
    81     count=0;
    82     while(!done) {
    83         if (count++>max_count) done=true;
    84         // output
    85         if (count%1==0&&do_display==1) {
    86                 doDraw(rank,ncols,nrows,grid);
     40        // command line arguments
     41        if (argc > 1) {
     42                sscanf(argv[1],"%d",&nrows);
    8743        }
    88         do_step(rank,size,ncols,nrows,grid,next_grid);
    89         //doDraw(rank,ncols,nrows,next_grid);
    90         //do_step(ncols,nrows,next_grid,grid);
    91         for (i=0;i<ncols+2;i++) {
    92             for (j=0;j<nrows+2;j++) {
    93                 grid[i][j]=next_grid[i][j];
    94             }
    95         }
    96     }
    97    
    98    
    99     cleanup_grid(ncols, nrows, &grid);
    100     cleanup_grid(ncols, nrows, &next_grid);
    101     if(do_display==1) free_video();
    102     MPI_Finalize();
    103 
    104 
    105 }
    106 
    107 void do_step(int rank, int size, int ncols, int nrows, int ** grid,
    108         int ** next_grid) {
    109     int i,j,k,l,neighbors;
    110    
    111     // side by side grid
    112     // top and bottom we get from current cell.
    113     //left right and corners we get from neighboring grids.
    114     // start off with non blocking sends of each "row"
    115     // left is rank - 1 % size, right is rank + 1 % size.
    116 
    117     // copy sides
    118     int left_rank = (rank-1+size)%size;
    119     int right_rank = (rank+1)%size;
    120    
    121     // If we're only 1, no need to do the communication
    122     if (size != 1) {
    123             if (left_rank>=rank) {
    124                 MPI_Send(grid[1],nrows+2,MPI_INT,left_rank,MPI_TOLEFT,
    125                     MPI_COMM_WORLD);
    126                 MPI_Recv(grid[ncols+1],nrows+2,MPI_INT,right_rank,
    127                     MPI_TOLEFT,
    128                     MPI_COMM_WORLD, &mpi_status);
    129             } else {
    130                 MPI_Recv(grid[ncols+1],nrows+2,MPI_INT,right_rank,
    131                     MPI_TOLEFT,MPI_COMM_WORLD, &mpi_status);
    132                 MPI_Send(grid[1],nrows+2,MPI_INT,left_rank,MPI_TOLEFT,
    133                     MPI_COMM_WORLD);
    134             }
    135            
    136             if (right_rank>=rank) {
    137                 MPI_Send(grid[ncols],nrows+2,MPI_INT,right_rank,MPI_TORIGHT,
    138                     MPI_COMM_WORLD);
    139                 MPI_Recv(grid[0],nrows+2,MPI_INT,left_rank,
    140                     MPI_TORIGHT,
    141                     MPI_COMM_WORLD, &mpi_status);
    142             } else {
    143                 MPI_Recv(grid[0],nrows+2,MPI_INT,left_rank,
    144                     MPI_TORIGHT,
    145                     MPI_COMM_WORLD, &mpi_status);
    146                 MPI_Send(grid[ncols],nrows+2,MPI_INT,right_rank,MPI_TORIGHT,
    147                     MPI_COMM_WORLD);
    148             }
     44        if (argc > 2) {
     45                sscanf(argv[2],"%d",&ncols);
    14946        }
    150    
    151     // copy corners
    152         grid[0][0]=grid[0][nrows];
    153         grid[0][nrows+1]=grid[0][1];
    154         grid[ncols+1][0]=grid[ncols+1][nrows];
    155         grid[ncols+1][nrows+1]=grid[ncols+1][1];
    156        
    157         //copy top and bottom
    158         for (i=1;i<=ncols;i++) {
    159                 grid[i][0]=grid[i][nrows];
    160                 grid[i][nrows+1]=grid[i][1];
     47        if (argc > 3) {
     48                sscanf(argv[3],"%d",&generations);
     49        }
     50        if (argc > 4) {
     51                if (atoi(argv[4]) != 1)
     52                        do_display = false;
    16153        }
    16254
     55        allocate_grid(ncols, nrows, &grid);
     56        allocate_grid(ncols, nrows, &next_grid);
     57        randomize_grid(ncols, nrows, grid, INIT_PROB);
    16358
    164         //update
    165         for (i=1;i<=ncols;i++) {
    166                 for (j=1;j<=nrows;j++) {
    167                         neighbors=0;
    168                         for (k=i-1;k<=i+1; k++) {
    169                                 for (l=j-1;l<=j+1; l++) {
    170                                         if (!(k==i&&l==j)&&grid[k][l]>0) {
    171                                                 neighbors++;
    172                                         }
    173                                 }
    174                                 if (neighbors>3) continue;
    175                         }
    176                         if (neighbors<2||neighbors>3) {
    177                                 next_grid[i][j]=0;
    178                         } else if (grid[i][j]>0||neighbors==3) {
    179                                 next_grid[i][j]=grid[i][j]+1;
    180                         }
    181                 }
     59        if (do_display) {
     60                setupWindow(ncols, nrows);
     61                moveWindow(rank,size,ncols,nrows);
    18262        }
     63
     64        for (count = 0; count < generations; count++) {
     65                if (do_display)
     66                        do_draw(rank,ncols,nrows,grid);
     67
     68                do_step(rank,size,ncols,nrows,grid,next_grid);
     69
     70                // copy next_grid to grid
     71                for (i = 0; i < ncols+2; i++)
     72                        for (j = 0; j < nrows+2; j++)
     73                                grid[i][j] = next_grid[i][j];
     74        }
     75
     76        free_grid(ncols, nrows, &grid);
     77        free_grid(ncols, nrows, &next_grid);
     78
     79        if(do_display)
     80                free_video();
     81
     82        MPI_Finalize();
    18383}
    184 
    185 typedef int * intarray;
    186 
    187 void allocate_grid(int ncols, int nrows, int *** grid){
    188     int i,j;
    189     (*grid) = (int **) malloc(sizeof(intarray)*(ncols+2));
    190     for (i=0; i<ncols+2;i++) {
    191         (*grid)[i] = (int *) malloc(sizeof(int)*(nrows+2));
    192         for (j=0;j<nrows+2;j++) {
    193             (*grid)[i][j]=0;
    194         }
    195     }
    196 }
    197 void cleanup_grid(int ncols, int nrows, int *** grid){
    198     int i;
    199     for (i=0;i<ncols+2;i++) {
    200         free((*grid)[i]);
    201     }
    202     free(*grid);
    203 }
    204 void randomize_grid(int ncols, int nrows, int ** grid, double prob){
    205     int i,j;
    206     for (i=1;i<=ncols;i++) {
    207         for (j=1;j<=nrows;j++) {
    208             if (rand_double()<prob) {
    209                 grid[i][j]=1;
    210             }
    211         }
    212     }
    213 }
    214 
    215 double rand_double() {
    216     return (double)rand()/(double)RAND_MAX;
    217 }
    218 
    219 
    220 
    221 // X information, at some point this should be cleaned up so
    222 // that it does not use global variables
    223 
    224 // setupWindow modified from the tutorial on
    225 // http://tronche.com/gui/x/xlib-tutorial/
    226 // by Christophe Tronche
    227 
    228 
    229 Display *dpy;
    230 int blackColor;
    231 int whiteColor;
    232 Window w;
    233 GC gc;
    234 Pixmap buffer;
    235 Colormap theColormap;
    236 int numXGrayscale=10;
    237 XColor Xgrayscale[10];
    238 int IMAGE_WIDTH=LIFE_IMAGE_WIDTH;
    239 int IMAGE_HEIGHT=LIFE_IMAGE_HEIGHT;
    240 
    241 void free_video() {
    242      XCloseDisplay(dpy);
    243 }
    244 
    245 void moveWindow(int rank,int size,int ncols, int nrows) {
    246       int posx, posy;
    247       posx = 50+(int)((double)rank/(double)size*(double)LIFE_IMAGE_WIDTH);
    248       posy = 50;
    249       XMoveWindow(dpy, w, posx, posy);
    250 }
    251 
    252 
    253 void setupWindow(int ncols, int nrows) {
    254       int i;
    255       XTextProperty xtp;
    256         Status xst;
    257 
    258         // Generate name object
    259         char *name="Life";
    260         xst = XStringListToTextProperty(&name,1,&xtp);
    261         assert(xst != 0);
    262 
    263       // Open the display
    264 
    265       dpy = XOpenDisplay(NIL);
    266       assert(dpy);
    267 
    268       // Get some colors
    269 
    270       blackColor = BlackPixel(dpy, DefaultScreen(dpy));
    271       whiteColor = WhitePixel(dpy, DefaultScreen(dpy));
    272 
    273       // Create the window
    274       if (nrows>ncols) {
    275          IMAGE_WIDTH = (int)((double)LIFE_IMAGE_WIDTH*(double)ncols/(double)nrows);
    276          IMAGE_HEIGHT = LIFE_IMAGE_HEIGHT;
    277       } else {
    278          IMAGE_HEIGHT = (int)((double)LIFE_IMAGE_HEIGHT*(double)nrows/(double)ncols);
    279          IMAGE_WIDTH = LIFE_IMAGE_WIDTH;
    280       }
    281      
    282 
    283       w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0,
    284                                      IMAGE_WIDTH, IMAGE_HEIGHT, 0, blackColor,
    285                                      blackColor);
    286         XSetWMProperties(dpy,w,&xtp,NULL,NULL,0,NULL,NULL,NULL);
    287       buffer = XCreatePixmap(dpy,DefaultRootWindow(dpy),
    288           IMAGE_WIDTH,IMAGE_HEIGHT,DefaultDepth(dpy,
    289           DefaultScreen(dpy)));
    290          
    291       theColormap = XCreateColormap(dpy, DefaultRootWindow(dpy),
    292           DefaultVisual(dpy,DefaultScreen(dpy)), AllocNone);
    293          
    294       for (i=0;i<numXGrayscale;i++) {
    295           int color = (int)((double)i*35535.0/(double)numXGrayscale)+30000;
    296           Xgrayscale[i].red=color;
    297           Xgrayscale[i].green=color;
    298           Xgrayscale[i].blue=color;
    299           XAllocColor(dpy,theColormap,&(Xgrayscale[i]));
    300       }
    301 
    302       // We want to get MapNotify events
    303 
    304       XSelectInput(dpy, w, StructureNotifyMask);
    305 
    306       // "Map" the window (that is, make it appear on the screen)
    307 
    308       XMapWindow(dpy, w);
    309 
    310       // Create a "Graphics Context"
    311 
    312       gc = XCreateGC(dpy, w, 0, NIL);
    313 
    314       // Tell the GC we draw using the white color
    315 
    316       XSetForeground(dpy, gc, whiteColor);
    317 
    318       // Wait for the MapNotify event
    319 
    320       for(;;) {
    321             XEvent e;
    322             XNextEvent(dpy, &e);
    323             if (e.type == MapNotify)
    324                   break;
    325       }
    326 
    327 }
    328 
    329 void doDraw(int rank, int ncols, int nrows, int ** grid) {
    330 
    331     int x1,x2,y1,y2;
    332     int i,j;
    333     char string[2];
    334     sprintf(string,"%d",rank);
    335    
    336     XSetForeground(dpy, gc, blackColor);
    337     XFillRectangle(dpy,buffer,gc,0,0,IMAGE_WIDTH,IMAGE_HEIGHT);
    338     int rect_width=(int)((double)IMAGE_WIDTH/(double)(ncols+1));
    339     int rect_height=(int)((double)IMAGE_HEIGHT/(double)(nrows+1));
    340     for (i=1;i<=ncols;i++) {
    341         x1 = (int)((double)(i-1)/(double)(ncols+1)*(double)IMAGE_WIDTH);
    342         for (j=1;j<=nrows;j++) {
    343             y1 = (int)((double)(j-1)/(double)(nrows+1)*
    344                 (double)IMAGE_HEIGHT);
    345             if (grid[i][j]>0) {
    346                 int life =grid[i][j];
    347                 if (life>numXGrayscale-1) life=numXGrayscale-1;
    348                 XSetForeground(dpy, gc, Xgrayscale[life].pixel);
    349             } else {
    350                 XSetForeground(dpy, gc, blackColor);
    351             }
    352             XFillRectangle(dpy,buffer,gc,x1,y1,rect_width,rect_height);
    353          }
    354      }
    355      XSetForeground(dpy,gc,blackColor);
    356      XFillRectangle(dpy,buffer,gc,10,10,15,15);
    357      XSetForeground(dpy,gc,whiteColor);
    358      XDrawRectangle(dpy,buffer,gc,10,10,15,15);
    359      XDrawString(dpy,buffer,gc,12,23,string,2);
    360      
    361      XCopyArea(dpy, buffer, w, gc, 0, 0,
    362          IMAGE_WIDTH, IMAGE_HEIGHT,  0, 0);
    363      XFlush(dpy);
    364          
    365 }
    366 
    367 void random_initByTime(int rank) {
    368     time_t ltime;
    369 
    370     time(&ltime);
    371     srand((unsigned) ltime + 100*rank);
    372 }
  • bccd-ng/branches/fitz-devel/trees/home/bccd/Life/Life.h

    • Property svn:executable deleted
    r2308 r2364  
    2626        // side by side grid
    2727        // top and bottom we get from current cell.
    28         //left right and corners we get from neighboring grids.
     28        // left right and corners we get from neighboring grids.
    2929        // start off with non blocking sends of each "row"
    3030        // left is rank - 1 % size, right is rank + 1 % size.
     
    3636        // If we're only 1, no need to do the communication
    3737        if (size != 1) {
    38                 if (left_rank>=rank) {
    39                         MPI_Send(grid[1],nrows+2,MPI_INT,left_rank,MPI_TOLEFT,
    40                                         MPI_COMM_WORLD);
    41                         MPI_Recv(grid[ncols+1],nrows+2,MPI_INT,right_rank,
    42                                         MPI_TOLEFT,
    43                                         MPI_COMM_WORLD, &status);
    44                 } else {
    45                         MPI_Recv(grid[ncols+1],nrows+2,MPI_INT,right_rank,
    46                                         MPI_TOLEFT,MPI_COMM_WORLD, &status);
    47                         MPI_Send(grid[1],nrows+2,MPI_INT,left_rank,MPI_TOLEFT,
    48                                         MPI_COMM_WORLD);
    49                 }
     38                MPI_Send(grid[1],nrows+2,MPI_INT,left_rank,MPI_TOLEFT,
     39                                MPI_COMM_WORLD);
     40                MPI_Recv(grid[ncols+1],nrows+2,MPI_INT,right_rank,
     41                                MPI_TOLEFT,
     42                                MPI_COMM_WORLD, &status);
    5043
    51                 if (right_rank>=rank) {
    52                         MPI_Send(grid[ncols],nrows+2,MPI_INT,right_rank,MPI_TORIGHT,
    53                                         MPI_COMM_WORLD);
    54                         MPI_Recv(grid[0],nrows+2,MPI_INT,left_rank,
    55                                         MPI_TORIGHT,
    56                                         MPI_COMM_WORLD, &status);
    57                 } else {
    58                         MPI_Recv(grid[0],nrows+2,MPI_INT,left_rank,
    59                                         MPI_TORIGHT,
    60                                         MPI_COMM_WORLD, &status);
    61                         MPI_Send(grid[ncols],nrows+2,MPI_INT,right_rank,MPI_TORIGHT,
    62                                         MPI_COMM_WORLD);
    63                 }
     44                MPI_Send(grid[ncols],nrows+2,MPI_INT,right_rank,MPI_TORIGHT,
     45                                MPI_COMM_WORLD);
     46                MPI_Recv(grid[0],nrows+2,MPI_INT,left_rank,
     47                                MPI_TORIGHT,
     48                                MPI_COMM_WORLD, &status);
    6449        }
    6550
  • bccd-ng/branches/fitz-devel/trees/home/bccd/Life/LifeHandout.pdf

    • Property svn:executable deleted
  • bccd-ng/branches/fitz-devel/trees/home/bccd/Life/Makefile

    • Property svn:executable deleted
    r2308 r2364  
     1
    12CC        = mpicc
    23
     4#
     5# Modify TOPDIR if you use your own include files and library files
     6#
     7
    38LIBS      = -lX11 -lm
     9
     10
    411CFLAGS    =
    512LDFLAGS   = -L/usr/X11R6/lib $(LIBS)
Note: See TracChangeset for help on using the changeset viewer.