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

Last change on this file since 515 was 515, checked in by alain, 9 years ago

Cosmetic.

File size: 6.8 KB
Line 
1//////////////////////////////////////////////////////////////////////////////////
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
6//
7// This application is an emulation of the Game of Life automaton.
8// The world size is defined by the HEIGHT and WIDTH parameters.
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// the chained buffer DMA controler.
13//
14// The number of processors must be a power of 2 not larger than HEIGHT.
15//////////////////////////////////////////////////////////////////////////////////
16
17#include "stdio.h"
18#include "limits.h"
19#include "user_barrier.h"
20#include "mapping_info.h"
21
22#define WIDTH           128
23#define HEIGHT          128
24#define NB_ITERATION    1000000000
25
26#define PRINTF(...) ({ if ( proc_id==0) { giet_shr_printf(__VA_ARGS__); } })
27
28typedef unsigned char uint8_t;
29
30uint8_t WORLD[2][HEIGHT][WIDTH] __attribute__((aligned(64)));
31
32uint8_t DISPLAY[2][HEIGHT][WIDTH] __attribute__((aligned(64)));
33
34giet_sqt_barrier_t barrier;
35
36volatile unsigned int init_ok;
37
38////////////////////////////////////
39void 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//////////////////////////////////////////////////////
54uint8_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/////////////////////////////////////////
73uint8_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/////////////////////////////////////////
92void 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++)
98   {
99      for(x = 0; x < WIDTH ; x++) 
100      {
101         WORLD[phase][y][x] = compute_cell( 1 - phase , x , y ); 
102      }
103   }
104}
105
106////////////////////////////////////
107void copy_world( unsigned int phase,
108                 unsigned int base_line,
109                 unsigned int nb_line )
110{
111   unsigned int x,y;
112   for (y = base_line; y < base_line + nb_line; y++)
113   {
114      for(x = 0; x < WIDTH ; x++) 
115      {
116         DISPLAY[phase][y][x] = WORLD[phase][y][x]*255; 
117      }
118   }
119}
120
121////////////////////////////////////////
122__attribute__((constructor)) void main()
123{
124   // get processor identifier
125   unsigned int x;
126   unsigned int y;
127   unsigned int p;
128   giet_proc_xyp( &x, &y, &p );
129
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
136   // compute continuous processor index & number of procs
137   unsigned int proc_id = (((x * y_size) + y) * n_local_procs) + p; 
138   unsigned int n_global_procs = x_size * y_size * n_local_procs; 
139
140   unsigned int i;
141
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
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"
153          " nprocs = %d / nlines = %d\n", 
154          giet_proctime() , n_global_procs, HEIGHT );
155
156   //////////// barrier & CMA initialization ( P(0,0,0) )
157
158   if ( proc_id == 0 )
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
167      sqt_barrier_init( &barrier , x_size , y_size , n_local_procs );
168
169      // activates all other processors
170      init_ok = 1;
171   }
172   else
173   {
174      while ( init_ok == 0 ) asm volatile("nop\n nop\n nop");
175   }
176
177   PRINTF("\n*** Starting world initialisation at cycle %d ***\n",
178          giet_proctime() );
179
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
189   sqt_barrier_wait( &barrier );
190
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
207      sqt_barrier_wait( &barrier );
208
209      // P(0,0,0) displays DISPLAY[1]
210      if ( proc_id == 0 ) giet_fbf_cma_display ( 1 );
211   
212      PRINTF(" - step %d\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\n", 2*i + 1 );
227   } // end main loop
228
229   PRINTF("\n*** End of main at cycle %d ***\n", giet_proctime());
230
231   giet_exit("Completed");
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.