source: soft/giet_vm/applications/gameoflife/main.c @ 514

Last change on this file since 514 was 509, checked in by alain, 10 years ago

Using the CMA component for display.

File size: 6.8 KB
RevLine 
[502]1//////////////////////////////////////////////////////////////////////////////////
[509]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
[502]6//
[509]7// This application is an emulation of the Game of Life automaton.
[502]8// The world size is defined by the HEIGHT and WIDTH parameters.
[509]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//
[502]14// The number of processors must be a power of 2 not larger than HEIGHT.
15//////////////////////////////////////////////////////////////////////////////////
[251]16
17#include "stdio.h"
18#include "limits.h"
[502]19#include "user_barrier.h"
[251]20#include "mapping_info.h"
21
22#define WIDTH           128
23#define HEIGHT          128
24#define NB_ITERATION    1000000000
25
[502]26#define PRINTF(...) ({ if ( proc_id==0) { giet_shr_printf(__VA_ARGS__); } })
[251]27
[509]28typedef unsigned char uint8_t;
[251]29
[509]30uint8_t WORLD[2][HEIGHT][WIDTH] __attribute__((aligned(64)));
[295]31
[509]32uint8_t DISPLAY[2][HEIGHT][WIDTH] __attribute__((aligned(64)));
[251]33
[509]34giet_sqt_barrier_t barrier;
[251]35
[509]36volatile unsigned int init_ok;
[251]37
[509]38////////////////////////////////////
39void init_world( unsigned int phase,
40                 unsigned int base_line,
41                 unsigned int nb_line )
[251]42{
[509]43   unsigned int x,y;
44   for (y = base_line ; y < base_line + nb_line ; y++)
[502]45   {
[509]46      for(x = 0 ; x < WIDTH ; x++) 
[502]47      {
[509]48         WORLD[phase][y][x] = (giet_rand() >> (x % 8)) & 0x1;
[251]49      }
50   }
51}
52
[509]53//////////////////////////////////////////////////////
54uint8_t number_of_alive_neighbour( unsigned int phase,
55                                   unsigned int x, 
56                                   unsigned int y )
[251]57{
58   uint8_t nb = 0;
59
[509]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];
[251]68
69   return nb;
70}
71
[509]72/////////////////////////////////////////
73uint8_t compute_cell( unsigned int phase,
74                      unsigned int x, 
75                      unsigned int y )
[251]76{
[509]77   uint8_t nb_neighbours_alive = number_of_alive_neighbour( phase, x , y );
78
79   if (WORLD[phase][y][x] == 1) 
[502]80   {
81      if (nb_neighbours_alive == 2 || nb_neighbours_alive == 3)  return 1;
[251]82   }
[502]83   else 
84   {
85      if (nb_neighbours_alive == 3) return 1;
[509]86      else                          return WORLD[phase][y][x];
[251]87   }
88   return 0;
89}
90
[509]91/////////////////////////////////////////
92void compute_new_gen( unsigned int phase,
93                      unsigned int base_line, 
94                      unsigned int nb_line )
[251]95{
[509]96   unsigned int x,y;
[295]97   for (y = base_line; y < base_line + nb_line; y++)
98   {
99      for(x = 0; x < WIDTH ; x++) 
100      {
[509]101         WORLD[phase][y][x] = compute_cell( 1 - phase , x , y ); 
[251]102      }
103   }
104}
105
[509]106////////////////////////////////////
107void copy_world( unsigned int phase,
108                 unsigned int base_line,
109                 unsigned int nb_line )
[251]110{
[509]111   unsigned int x,y;
[502]112   for (y = base_line; y < base_line + nb_line; y++)
113   {
114      for(x = 0; x < WIDTH ; x++) 
115      {
[509]116         DISPLAY[phase][y][x] = WORLD[phase][y][x]*255; 
[251]117      }
118   }
119}
120
[263]121////////////////////////////////////////
[251]122__attribute__((constructor)) void main()
123{
[432]124   // get processor identifier
125   unsigned int x;
126   unsigned int y;
127   unsigned int p;
128   giet_proc_xyp( &x, &y, &p );
129
[502]130   // get processors number
131   unsigned int x_size;
132   unsigned int y_size;
133   unsigned int n_local_procs;
134   giet_procs_number( &x_size, &y_size, &n_local_procs );
135
[509]136   // compute continuous processor index & number of procs
[502]137   unsigned int proc_id = (((x * y_size) + y) * n_local_procs) + p; 
[509]138   unsigned int n_global_procs = x_size * y_size * n_local_procs; 
[432]139
[509]140   unsigned int i;
[251]141
[502]142   if ( n_global_procs > HEIGHT )
143   {
144       PRINTF("[GAMEOFLIFE ERROR] Number or processors too large :"
145              " nb_procs = %d / image heigth = %d\n", n_global_procs, HEIGHT );
146       giet_exit("error");
147   }
148
[509]149   unsigned int nb_line       = HEIGHT / n_global_procs;
150   unsigned int base_line     = nb_line * proc_id; 
[251]151   
[509]152   PRINTF("\n*** Starting barrier and CMA initialisation at cycle %d ***\n"
[502]153          " nprocs = %d / nlines = %d\n", 
154          giet_proctime() , n_global_procs, HEIGHT );
[251]155
[509]156   //////////// barrier & CMA initialization ( P(0,0,0) )
157
[295]158   if ( proc_id == 0 )
159   {
[509]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
[502]167      sqt_barrier_init( &barrier , x_size , y_size , n_local_procs );
[509]168
169      // activates all other processors
[502]170      init_ok = 1;
[295]171   }
172   else
173   {
[504]174      while ( init_ok == 0 ) asm volatile("nop\n nop\n nop");
[295]175   }
176
[502]177   PRINTF("\n*** Starting world initialisation at cycle %d ***\n",
178          giet_proctime() );
[251]179
[509]180   ///////////// world  initialization ( All processors )
[502]181
[509]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
[502]189   sqt_barrier_wait( &barrier );
190
[509]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() );
[251]195   
[509]196   //////////// evolution : 2 steps per iteration
197
198   for (i = 0 ; i < NB_ITERATION ; i++)
[251]199   {
[509]200      // compute WORLD[1] from WORLD[0]
201      compute_new_gen( 1 , base_line , nb_line );
[502]202
[509]203      // copy WORLD[1] to DISPLAY[1]
204      copy_world( 1 , base_line , nb_line );
205
206      // synchronise with other procs
[502]207      sqt_barrier_wait( &barrier );
208
[509]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 );
[251]216
[509]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
228
[502]229   PRINTF("\n*** End of main at cycle %d ***\n", giet_proctime());
[251]230
[388]231   giet_exit("Completed");
[251]232} // end main()
233
234// Local Variables:
235// tab-width: 3
236// c-basic-offset: 3
237// c-file-offsets:((innamespace . 0)(inline-open . 0))
238// indent-tabs-mode: nil
239// End:
240
241// vim: filetype=cpp:expandtab:shiftwidth=3:tabstop=3:softtabstop=3
242
243
244
Note: See TracBrowser for help on using the repository browser.