Changeset 509
- Timestamp:
- Feb 10, 2015, 7:16:54 PM (10 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/applications/gameoflife/main.c
r504 r509 1 1 ////////////////////////////////////////////////////////////////////////////////// 2 // File : main.c (for gameoflife) 3 // Date : November 2013 4 // Author : Alexandre Joannou <alexandre.joannou@lip6.fr> 2 // File : main.c (for gameoflife) 3 // Date : November 2013 / February 2015 4 // Authors : Alexandre Joannou <alexandre.joannou@lip6.fr> november 2013 5 // Alain Greiner <alain.greiner@lip6.fr> february 2015 5 6 // 6 // This application is an emulation of the game of life automaton.7 // This application is an emulation of the Game of Life automaton. 7 8 // The world size is defined by the HEIGHT and WIDTH parameters. 8 // There is one task per processor, and each task compute HEIGHT/nbprocs lines. 9 // There is one task per processor. 10 // Each task compute HEIGHT/nbprocs lines. 11 // Task running on processor P(0,0,0) initialises the barrier, and 12 // control the chained buffer DMA controler, when it is used. 13 // 9 14 // The number of processors must be a power of 2 not larger than HEIGHT. 10 15 ////////////////////////////////////////////////////////////////////////////////// … … 21 26 #define PRINTF(...) ({ if ( proc_id==0) { giet_shr_printf(__VA_ARGS__); } }) 22 27 28 typedef unsigned char uint8_t; 29 30 uint8_t WORLD[2][HEIGHT][WIDTH] __attribute__((aligned(64))); 31 32 uint8_t DISPLAY[2][HEIGHT][WIDTH] __attribute__((aligned(64))); 33 23 34 giet_sqt_barrier_t barrier; 24 35 25 36 volatile unsigned int init_ok; 26 37 27 #define OLD 0 28 #define NEW 1 29 #define DSP 2 30 31 typedef unsigned char uint8_t; 32 typedef unsigned int size_t; 33 34 uint8_t world[3][HEIGHT][WIDTH]; 35 36 ///////////////////////////////////////////////// 37 void init_world(size_t base_line, size_t nb_line) 38 { 39 size_t x,y; 40 for (y = base_line ; y < base_line + nb_line; y++) 38 //////////////////////////////////// 39 void init_world( unsigned int phase, 40 unsigned int base_line, 41 unsigned int nb_line ) 42 { 43 unsigned int x,y; 44 for (y = base_line ; y < base_line + nb_line ; y++) 45 { 46 for(x = 0 ; x < WIDTH ; x++) 47 { 48 WORLD[phase][y][x] = (giet_rand() >> (x % 8)) & 0x1; 49 } 50 } 51 } 52 53 ////////////////////////////////////////////////////// 54 uint8_t number_of_alive_neighbour( unsigned int phase, 55 unsigned int x, 56 unsigned int y ) 57 { 58 uint8_t nb = 0; 59 60 nb += WORLD[phase][(y - 1) % HEIGHT][(x - 1) % WIDTH]; 61 nb += WORLD[phase][ y ][(x - 1) % WIDTH]; 62 nb += WORLD[phase][(y + 1) % HEIGHT][(x - 1) % WIDTH]; 63 nb += WORLD[phase][(y - 1) % HEIGHT][ x ]; 64 nb += WORLD[phase][(y + 1) % HEIGHT][ x ]; 65 nb += WORLD[phase][(y - 1) % HEIGHT][(x + 1) % WIDTH]; 66 nb += WORLD[phase][ y ][(x + 1) % WIDTH]; 67 nb += WORLD[phase][(y + 1) % HEIGHT][(x + 1) % WIDTH]; 68 69 return nb; 70 } 71 72 ///////////////////////////////////////// 73 uint8_t compute_cell( unsigned int phase, 74 unsigned int x, 75 unsigned int y ) 76 { 77 uint8_t nb_neighbours_alive = number_of_alive_neighbour( phase, x , y ); 78 79 if (WORLD[phase][y][x] == 1) 80 { 81 if (nb_neighbours_alive == 2 || nb_neighbours_alive == 3) return 1; 82 } 83 else 84 { 85 if (nb_neighbours_alive == 3) return 1; 86 else return WORLD[phase][y][x]; 87 } 88 return 0; 89 } 90 91 ///////////////////////////////////////// 92 void compute_new_gen( unsigned int phase, 93 unsigned int base_line, 94 unsigned int nb_line ) 95 { 96 unsigned int x,y; 97 for (y = base_line; y < base_line + nb_line; y++) 41 98 { 42 99 for(x = 0; x < WIDTH ; x++) 43 100 { 44 world[OLD][y][x] = (giet_rand() >> (x % 8)) & 0x1;101 WORLD[phase][y][x] = compute_cell( 1 - phase , x , y ); 45 102 } 46 103 } 47 104 } 48 105 49 ///////////////////////////////////////////////// 50 uint8_t number_of_alive_neigh(size_t x, size_t y) 51 { 52 uint8_t nb = 0; 53 54 nb += world[OLD][(y - 1) % HEIGHT][(x - 1) % WIDTH]; 55 nb += world[OLD][ y ][(x - 1) % WIDTH]; 56 nb += world[OLD][(y + 1) % HEIGHT][(x - 1) % WIDTH]; 57 nb += world[OLD][(y - 1) % HEIGHT][ x ]; 58 nb += world[OLD][(y + 1) % HEIGHT][ x ]; 59 nb += world[OLD][(y - 1) % HEIGHT][(x + 1) % WIDTH]; 60 nb += world[OLD][ y ][(x + 1) % WIDTH]; 61 nb += world[OLD][(y + 1) % HEIGHT][(x + 1) % WIDTH]; 62 63 return nb; 64 } 65 66 ///////////////////////////////////////////////// 67 uint8_t compute_cell(size_t x, size_t y) 68 { 69 uint8_t nb_neighbours_alive = number_of_alive_neigh(x,y); 70 if (world[OLD][y][x] == 1) 71 { 72 if (nb_neighbours_alive == 2 || nb_neighbours_alive == 3) return 1; 73 } 74 else 75 { 76 if (nb_neighbours_alive == 3) return 1; 77 else return world[OLD][y][x]; 78 } 79 return 0; 80 } 81 82 ////////////////////////////////////////////////////// 83 void compute_new_gen(size_t base_line, size_t nb_line) 84 { 85 size_t x,y; 106 //////////////////////////////////// 107 void copy_world( unsigned int phase, 108 unsigned int base_line, 109 unsigned int nb_line ) 110 { 111 unsigned int x,y; 86 112 for (y = base_line; y < base_line + nb_line; y++) 87 113 { 88 114 for(x = 0; x < WIDTH ; x++) 89 115 { 90 world[NEW][y][x] = compute_cell(x,y); 91 } 92 } 93 } 94 95 //////////////////////////////////////////////////// 96 void display_world(size_t base_line, size_t nb_line) 97 { 98 size_t x,y; 99 for (y = base_line; y < base_line + nb_line; y++) 100 { 101 for(x = 0; x < WIDTH ; x++) 102 { 103 world[DSP][y][x] = world[OLD][y][x]*255; 104 } 105 } 106 107 giet_fbf_sync_write( base_line * WIDTH , 108 &world[DSP][base_line][0], 109 nb_line * WIDTH ); 110 } 111 112 ///////////////////////////////////////////////////// 113 void grow_old_world(size_t base_line, size_t nb_line) 114 { 115 size_t x,y; 116 for (y = base_line; y < base_line + nb_line; y++) 117 { 118 for(x = 0; x < WIDTH ; x++) 119 { 120 world[OLD][y][x] = world[NEW][y][x]; 116 DISPLAY[phase][y][x] = WORLD[phase][y][x]*255; 121 117 } 122 118 } … … 138 134 giet_procs_number( &x_size, &y_size, &n_local_procs ); 139 135 140 // compute continuous processor index 136 // compute continuous processor index & number of procs 141 137 unsigned int proc_id = (((x * y_size) + y) * n_local_procs) + p; 142 143 unsigned int n_clusters = x_size * y_size; // number of clusters 144 unsigned int n_global_procs = n_clusters * n_local_procs; // number of processors 145 size_t i; 138 unsigned int n_global_procs = x_size * y_size * n_local_procs; 139 140 unsigned int i; 146 141 147 142 if ( n_global_procs > HEIGHT ) … … 152 147 } 153 148 154 size_tnb_line = HEIGHT / n_global_procs;155 size_tbase_line = nb_line * proc_id;156 157 PRINTF("\n*** Starting barrier initialisation at cycle %d ***\n"149 unsigned int nb_line = HEIGHT / n_global_procs; 150 unsigned int base_line = nb_line * proc_id; 151 152 PRINTF("\n*** Starting barrier and CMA initialisation at cycle %d ***\n" 158 153 " nprocs = %d / nlines = %d\n", 159 154 giet_proctime() , n_global_procs, HEIGHT ); 160 155 161 // barrier initialization 156 //////////// barrier & CMA initialization ( P(0,0,0) ) 157 162 158 if ( proc_id == 0 ) 163 159 { 160 // initialises CMA component 161 giet_fbf_cma_alloc(); 162 giet_fbf_cma_start( &DISPLAY[0][0][0] , 163 &DISPLAY[1][0][0] , 164 HEIGHT * WIDTH ); 165 166 // initialises barrier 164 167 sqt_barrier_init( &barrier , x_size , y_size , n_local_procs ); 168 169 // activates all other processors 165 170 init_ok = 1; 166 171 } … … 173 178 giet_proctime() ); 174 179 175 // parallel world initialization 176 init_world( base_line , nb_line ); 177 display_world( base_line , nb_line ); 178 180 ///////////// world initialization ( All processors ) 181 182 // initialises WORLD[0] 183 init_world( 0 , base_line , nb_line ); 184 185 // copy WORLD[0] to DISPLAY[0] 186 copy_world( 0 , base_line , nb_line ); 187 188 // synchronise with other procs 179 189 sqt_barrier_wait( &barrier ); 180 190 181 PRINTF("\n*** Starting life at cycle %d ***\n", 182 giet_proctime() ); 183 184 for (i = 0; i < NB_ITERATION; i++) 185 { 186 compute_new_gen( base_line, nb_line ); 187 grow_old_world( base_line, nb_line ); 188 display_world( base_line, nb_line ); 189 191 // P(0,0,0) displays DISPLAY[0] 192 if ( proc_id == 0 ) giet_fbf_cma_display ( 0 ); 193 194 PRINTF("\n*** Starting evolution at cycle %d ***\n", giet_proctime() ); 195 196 //////////// evolution : 2 steps per iteration 197 198 for (i = 0 ; i < NB_ITERATION ; i++) 199 { 200 // compute WORLD[1] from WORLD[0] 201 compute_new_gen( 1 , base_line , nb_line ); 202 203 // copy WORLD[1] to DISPLAY[1] 204 copy_world( 1 , base_line , nb_line ); 205 206 // synchronise with other procs 190 207 sqt_barrier_wait( &barrier ); 191 208 192 PRINTF(" - iteration %d completed\n", i ); 193 } 209 // P(0,0,0) displays DISPLAY[1] 210 if ( proc_id == 0 ) giet_fbf_cma_display ( 1 ); 211 212 PRINTF(" - step %d completed\n", 2*i ); 213 214 // compute WORLD[0] from WORLD[1] 215 compute_new_gen( 0 , base_line , nb_line ); 216 217 // copy WORLD[0] to DISPLAY[0] 218 copy_world( 0 , base_line , nb_line ); 219 220 // synchronise with other procs 221 sqt_barrier_wait( &barrier ); 222 223 // P(0,0,0) displays DISPLAY[0] 224 if ( proc_id == 0 ) giet_fbf_cma_display ( 0 ); 225 226 PRINTF(" - step %d completed\n", 2*i + 1 ); 227 } // end main loop 194 228 195 229 PRINTF("\n*** End of main at cycle %d ***\n", giet_proctime());
Note: See TracChangeset
for help on using the changeset viewer.