Changeset 2308 in /cluster/svnroot


Ignore:
Timestamp:
Apr 3, 2010 4:02:58 PM (11 years ago)
Author:
fitz
Message:

(#486) First refactoring run

  • Split off X stuff into separate header
  • Consistent indenting across source
  • Function source moved to header
  • Minor formatting changes
  • Add some default variables, change variable names
  • Other minor changes
Location:
bccd-ng/branches/fitz-devel/trees/home/bccd/Life
Files:
1 added
3 edited

Legend:

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

    r1966 r2308  
    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;
    2716
    2817int 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;
     18        int rank, size;
     19        int ngrid, ncols, nrows;
     20        int generations;
     21        bool do_display;
     22        int count;
     23        int 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) doDraw(rank,ncols,nrows,grid);
    86         do_step(rank,size,ncols,nrows,grid,next_grid);
    87         //doDraw(rank,ncols,nrows,next_grid);
    88         //do_step(ncols,nrows,next_grid,grid);
    89         for (i=0;i<ncols+2;i++) {
    90             for (j=0;j<nrows+2;j++) {
    91                 grid[i][j]=next_grid[i][j];
    92             }
    93         }
    94     }
    95    
    96    
    97 
    98     cleanup_grid(ncols, nrows, &grid);
    99     cleanup_grid(ncols, nrows, &next_grid);
    100     if(do_display==1) free_video();
    101     MPI_Finalize();
    102 
    103 
    104 }
    105 
    106 void do_step(int rank, int size, int ncols, int nrows, int ** grid,
    107         int ** next_grid) {
    108     int i,j,k,l,neighbors;
    109    
    110     // side by side grid
    111     // top and bottom we get from current cell.
    112     //left right and corners we get from neighboring grids.
    113     // start off with non blocking sends of each "row"
    114     // left is rank - 1 % size, right is rank + 1 % size.
    115 
    116     // copy sides
    117     int left_rank = (rank-1+size)%size;
    118     int right_rank = (rank+1)%size;
    119    
    120     if (left_rank>=rank) {
    121         MPI_Send(grid[1],nrows+2,MPI_INT,left_rank,MPI_TOLEFT,
    122             MPI_COMM_WORLD);
    123         MPI_Recv(grid[ncols+1],nrows+2,MPI_INT,right_rank,
    124             MPI_TOLEFT,
    125             MPI_COMM_WORLD, &mpi_status);
    126     } else {
    127         MPI_Recv(grid[ncols+1],nrows+2,MPI_INT,right_rank,
    128             MPI_TOLEFT,MPI_COMM_WORLD, &mpi_status);
    129         MPI_Send(grid[1],nrows+2,MPI_INT,left_rank,MPI_TOLEFT,
    130             MPI_COMM_WORLD);
    131     }
    132    
    133     if (right_rank>=rank) {
    134         MPI_Send(grid[ncols],nrows+2,MPI_INT,right_rank,MPI_TORIGHT,
    135             MPI_COMM_WORLD);
    136         MPI_Recv(grid[0],nrows+2,MPI_INT,left_rank,
    137             MPI_TORIGHT,
    138             MPI_COMM_WORLD, &mpi_status);
    139     } else {
    140         MPI_Recv(grid[0],nrows+2,MPI_INT,left_rank,
    141             MPI_TORIGHT,
    142             MPI_COMM_WORLD, &mpi_status);
    143         MPI_Send(grid[ncols],nrows+2,MPI_INT,right_rank,MPI_TORIGHT,
    144             MPI_COMM_WORLD);
    145     }
    146    
    147     // copy corners
    148         grid[0][0]=grid[0][nrows];
    149         grid[0][nrows+1]=grid[0][1];
    150         grid[ncols+1][0]=grid[ncols+1][nrows];
    151         grid[ncols+1][nrows+1]=grid[ncols+1][1];
    152        
    153         //copy top and bottom
    154         for (i=1;i<=ncols;i++) {
    155                 grid[i][0]=grid[i][nrows];
    156                 grid[i][nrows+1]=grid[i][1];
     40        // command line arguments
     41        if (argc > 1) {
     42                sscanf(argv[1],"%d",&nrows);
     43        }
     44        if (argc > 2) {
     45                sscanf(argv[2],"%d",&ncols);
     46        }
     47        if (argc > 3) {
     48                sscanf(argv[3],"%d",&generations);
     49        }
     50        if (argc > 4) {
     51                sscanf(argv[4],"%d",&do_display);
    15752        }
    15853
     54        allocate_grid(ncols, nrows, &grid);
     55        allocate_grid(ncols, nrows, &next_grid);
     56        randomize_grid(ncols, nrows, grid, 0.25);
    15957
    160         //update
    161         for (i=1;i<=ncols;i++) {
    162                 for (j=1;j<=nrows;j++) {
    163                         neighbors=0;
    164                         for (k=i-1;k<=i+1; k++) {
    165                                 for (l=j-1;l<=j+1; l++) {
    166                                         if (!(k==i&&l==j)&&grid[k][l]>0) {
    167                                                 neighbors++;
    168                                         }
    169                                 }
    170                                 if (neighbors>3) continue;
    171                         }
    172                         if (neighbors<2||neighbors>3) {
    173                                 next_grid[i][j]=0;
    174                         } else if (grid[i][j]>0||neighbors==3) {
    175                                 next_grid[i][j]=grid[i][j]+1;
    176                         }
    177                 }
     58        if (do_display) {
     59                setupWindow(ncols, nrows);
     60                moveWindow(rank,size,ncols,nrows);
    17861        }
     62
     63        for (count = 0; count < generations; count++) {
     64                if (do_display)
     65                        do_draw(rank,ncols,nrows,grid);
     66
     67                do_step(rank,size,ncols,nrows,grid,next_grid);
     68
     69                // copy next_grid to grid
     70                for (i = 0; i < ncols+2; i++)
     71                        for (j = 0; j < nrows+2; j++)
     72                                grid[i][j] = next_grid[i][j];
     73        }
     74
     75        free_grid(ncols, nrows, &grid);
     76        free_grid(ncols, nrows, &next_grid);
     77
     78        if(do_display)
     79                free_video();
     80
     81        MPI_Finalize();
    17982}
    180 
    181 typedef int * intarray;
    182 
    183 void allocate_grid(int ncols, int nrows, int *** grid){
    184     int i,j;
    185     (*grid) = (int **) malloc(sizeof(intarray)*(ncols+2));
    186     for (i=0; i<ncols+2;i++) {
    187         (*grid)[i] = (int *) malloc(sizeof(int)*(nrows+2));
    188         for (j=0;j<nrows+2;j++) {
    189             (*grid)[i][j]=0;
    190         }
    191     }
    192 }
    193 void cleanup_grid(int ncols, int nrows, int *** grid){
    194     int i;
    195     for (i=0;i<ncols+2;i++) {
    196         free((*grid)[i]);
    197     }
    198     free(*grid);
    199 }
    200 void randomize_grid(int ncols, int nrows, int ** grid, double prob){
    201     int i,j;
    202     for (i=1;i<=ncols;i++) {
    203         for (j=1;j<=nrows;j++) {
    204             if (rand_double()<prob) {
    205                 grid[i][j]=1;
    206             }
    207         }
    208     }
    209 }
    210 
    211 double rand_double() {
    212     return (double)rand()/(double)RAND_MAX;
    213 }
    214 
    215 
    216 
    217 // X information, at some point this should be cleaned up so
    218 // that it does not use global variables
    219 
    220 // setupWindow modified from the tutorial on
    221 // http://tronche.com/gui/x/xlib-tutorial/
    222 // by Christophe Tronche
    223 
    224 
    225 Display *dpy;
    226 int blackColor;
    227 int whiteColor;
    228 Window w;
    229 GC gc;
    230 Pixmap buffer;
    231 Colormap theColormap;
    232 int numXGrayscale=10;
    233 XColor Xgrayscale[10];
    234 int IMAGE_WIDTH=LIFE_IMAGE_WIDTH;
    235 int IMAGE_HEIGHT=LIFE_IMAGE_HEIGHT;
    236 
    237 void free_video() {
    238      XCloseDisplay(dpy);
    239 }
    240 
    241 void moveWindow(int rank,int size,int ncols, int nrows) {
    242       int posx, posy;
    243       posx = 50+(int)((double)rank/(double)size*(double)LIFE_IMAGE_WIDTH);
    244       posy = 50;
    245       XMoveWindow(dpy, w, posx, posy);
    246 }
    247 
    248 
    249 void setupWindow(int ncols, int nrows) {
    250       int i;
    251       XTextProperty xtp;
    252         Status xst;
    253 
    254         // Generate name object
    255         char *name="Life";
    256         xst = XStringListToTextProperty(&name,1,&xtp);
    257         assert(xst != 0);
    258 
    259       // Open the display
    260 
    261       dpy = XOpenDisplay(NIL);
    262       assert(dpy);
    263 
    264       // Get some colors
    265 
    266       blackColor = BlackPixel(dpy, DefaultScreen(dpy));
    267       whiteColor = WhitePixel(dpy, DefaultScreen(dpy));
    268 
    269       // Create the window
    270       if (nrows>ncols) {
    271          IMAGE_WIDTH = (int)((double)LIFE_IMAGE_WIDTH*(double)ncols/(double)nrows);
    272          IMAGE_HEIGHT = LIFE_IMAGE_HEIGHT;
    273       } else {
    274          IMAGE_HEIGHT = (int)((double)LIFE_IMAGE_HEIGHT*(double)nrows/(double)ncols);
    275          IMAGE_WIDTH = LIFE_IMAGE_WIDTH;
    276       }
    277      
    278 
    279       w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0,
    280                                      IMAGE_WIDTH, IMAGE_HEIGHT, 0, blackColor,
    281                                      blackColor);
    282         XSetWMProperties(dpy,w,&xtp,NULL,NULL,0,NULL,NULL,NULL);
    283       buffer = XCreatePixmap(dpy,DefaultRootWindow(dpy),
    284           IMAGE_WIDTH,IMAGE_HEIGHT,DefaultDepth(dpy,
    285           DefaultScreen(dpy)));
    286          
    287       theColormap = XCreateColormap(dpy, DefaultRootWindow(dpy),
    288           DefaultVisual(dpy,DefaultScreen(dpy)), AllocNone);
    289          
    290       for (i=0;i<numXGrayscale;i++) {
    291           int color = (int)((double)i*35535.0/(double)numXGrayscale)+30000;
    292           Xgrayscale[i].red=color;
    293           Xgrayscale[i].green=color;
    294           Xgrayscale[i].blue=color;
    295           XAllocColor(dpy,theColormap,&(Xgrayscale[i]));
    296       }
    297 
    298       // We want to get MapNotify events
    299 
    300       XSelectInput(dpy, w, StructureNotifyMask);
    301 
    302       // "Map" the window (that is, make it appear on the screen)
    303 
    304       XMapWindow(dpy, w);
    305 
    306       // Create a "Graphics Context"
    307 
    308       gc = XCreateGC(dpy, w, 0, NIL);
    309 
    310       // Tell the GC we draw using the white color
    311 
    312       XSetForeground(dpy, gc, whiteColor);
    313 
    314       // Wait for the MapNotify event
    315 
    316       for(;;) {
    317             XEvent e;
    318             XNextEvent(dpy, &e);
    319             if (e.type == MapNotify)
    320                   break;
    321       }
    322 
    323 }
    324 
    325 void doDraw(int rank, int ncols, int nrows, int ** grid) {
    326 
    327     int x1,x2,y1,y2;
    328     int i,j;
    329     char string[2];
    330     sprintf(string,"%d",rank);
    331    
    332     XSetForeground(dpy, gc, blackColor);
    333     XFillRectangle(dpy,buffer,gc,0,0,IMAGE_WIDTH,IMAGE_HEIGHT);
    334     int rect_width=(int)((double)IMAGE_WIDTH/(double)(ncols+1));
    335     int rect_height=(int)((double)IMAGE_HEIGHT/(double)(nrows+1));
    336     for (i=1;i<=ncols;i++) {
    337         x1 = (int)((double)(i-1)/(double)(ncols+1)*(double)IMAGE_WIDTH);
    338         for (j=1;j<=nrows;j++) {
    339             y1 = (int)((double)(j-1)/(double)(nrows+1)*
    340                 (double)IMAGE_HEIGHT);
    341             if (grid[i][j]>0) {
    342                 int life =grid[i][j];
    343                 if (life>numXGrayscale-1) life=numXGrayscale-1;
    344                 XSetForeground(dpy, gc, Xgrayscale[life].pixel);
    345             } else {
    346                 XSetForeground(dpy, gc, blackColor);
    347             }
    348             XFillRectangle(dpy,buffer,gc,x1,y1,rect_width,rect_height);
    349          }
    350      }
    351      XSetForeground(dpy,gc,blackColor);
    352      XFillRectangle(dpy,buffer,gc,10,10,15,15);
    353      XSetForeground(dpy,gc,whiteColor);
    354      XDrawRectangle(dpy,buffer,gc,10,10,15,15);
    355      XDrawString(dpy,buffer,gc,12,23,string,2);
    356      
    357      XCopyArea(dpy, buffer, w, gc, 0, 0,
    358          IMAGE_WIDTH, IMAGE_HEIGHT,  0, 0);
    359      XFlush(dpy);
    360          
    361 }
    362 
    363 void random_initByTime(int rank) {
    364     time_t ltime;
    365 
    366     time(&ltime);
    367     srand((unsigned) ltime + 100*rank);
    368 }
  • bccd-ng/branches/fitz-devel/trees/home/bccd/Life/Life.h

    r1879 r2308  
    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
     9#include <mpi.h>
     10#include <time.h>     // For seeding random
     11#include <stdio.h>    // For sscanf
     12#include <stdlib.h>   // For malloc et al.
     13#include <stdbool.h>  // For true/false
    714
    815#define LIFE_IMAGE_WIDTH 500
    916#define LIFE_IMAGE_HEIGHT 500
    1017
    11 void allocate_grid(int ncols, int nrows, int *** grid);
    12 void cleanup_grid(int ncols, int nrows, int *** grid);
    13 void free_video();
    14 void randomize_grid(int ncols, int nrows, int ** grid, double prob);
    15 double rand_double();
     18#define MPI_TORIGHT 0
     19#define MPI_TOLEFT  1
    1620
    17 void setupWindow(int , int);
    18 void moveWindow(int rank,int size,int ncols, int nrows) ;
    19 void doDraw(int rank, int ncols, int nrows, int ** grid);
    20 void do_step(int rank,int size,int ncols,int nrows,int ** grid,int ** next_grid);
     21void do_step(int rank, int size, int ncols, int nrows, int ** grid,
     22                int ** next_grid) {
     23        int i,j,k,l,neighbors;
     24        MPI_Status status;
    2125
    22 void random_initByTime(int rank) ;
     26        // side by side grid
     27        // top and bottom we get from current cell.
     28        //left right and corners we get from neighboring grids.
     29        // start off with non blocking sends of each "row"
     30        // left is rank - 1 % size, right is rank + 1 % size.
    2331
     32        // copy sides
     33        int left_rank = (rank-1+size)%size;
     34        int right_rank = (rank+1)%size;
    2435
     36        // If we're only 1, no need to do the communication
     37        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                }
     50
     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                }
     64        }
     65
     66        // copy corners
     67        grid[0][0]             = grid[0][nrows];
     68        grid[0][nrows+1]       = grid[0][1];
     69        grid[ncols+1][0]       = grid[ncols+1][nrows];
     70        grid[ncols+1][nrows+1] = grid[ncols+1][1];
     71
     72        // copy top and bottom
     73        for (i = 1; i <= ncols; i++) {
     74                grid[i][0]       = grid[i][nrows];
     75                grid[i][nrows+1] = grid[i][1];
     76        }
     77
     78        // update
     79        for (i=1;i<=ncols;i++) {
     80                for (j=1;j<=nrows;j++) {
     81                        neighbors=0;
     82                        for (k=i-1;k<=i+1; k++) {
     83                                for (l=j-1;l<=j+1; l++) {
     84                                        if (!(k==i && l==j) && grid[k][l]>0) {
     85                                                neighbors++;
     86                                        }
     87                                }
     88                                if (neighbors > 3) continue;
     89                        }
     90                        if (neighbors < 2 || neighbors > 3) {
     91                                next_grid[i][j] = 0;
     92                        } else if (grid[i][j] > 0 || neighbors == 3) {
     93                                next_grid[i][j] = grid[i][j]+1;
     94                        }
     95                }
     96        }
     97}
     98
     99typedef int * intarray;
     100
     101void allocate_grid(int ncols, int nrows, int *** grid){
     102        int i,j;
     103        (*grid) = (int **) malloc(sizeof(intarray)*(ncols+2));
     104        for (i=0; i<ncols+2;i++) {
     105                (*grid)[i] = (int *) malloc(sizeof(int)*(nrows+2));
     106                for (j=0;j<nrows+2;j++) {
     107                        (*grid)[i][j]=0;
     108                }
     109        }
     110}
     111
     112void free_grid(int ncols, int nrows, int *** grid){
     113        int i;
     114        for (i = 0; i < ncols+2; i++) {
     115                free((*grid)[i]);
     116        }
     117        free(*grid);
     118}
     119
     120double rand_double() {
     121        return (double)random()/(double)RAND_MAX;
     122}
     123
     124void randomize_grid(int ncols, int nrows, int ** grid, double prob){
     125        int i,j;
     126        for (i=1;i<=ncols;i++) {
     127                for (j=1;j<=nrows;j++) {
     128                        if (rand_double()<prob) {
     129                                grid[i][j]=1;
     130                        }
     131                }
     132        }
     133}
     134
     135void random_initByTime(int rank) {
     136        srandom(time(NULL) + 100*rank);
     137}
  • bccd-ng/branches/fitz-devel/trees/home/bccd/Life/Makefile

    r1879 r2308  
    1 
    21CC        = mpicc
    32
    4 #
    5 # Modify TOPDIR if you use your own include files and library files
    6 #
    7 
    83LIBS      = -lX11 -lm
    9 
    10 
    114CFLAGS    =
    125LDFLAGS   = -L/usr/X11R6/lib $(LIBS)
Note: See TracChangeset for help on using the changeset viewer.