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

Last change on this file since 436 was 432, checked in by alain, 10 years ago

1) Introduce the "applications" directory.
2) Introduce the fixed format (X_WIDTH / Y_WIDTH / P_WIDTH) for processor index in all applications.

File size: 4.7 KB
Line 
1/*
2 * This application is an emulation of the game of life automaton
3 * It must be deployed from processor 0 and use contiguous processor
4 * (example 0,1,2,3)
5 */
6
7
8#include "stdio.h"
9#include "limits.h"
10#include "barrier.h"
11#include "hard_config.h"
12#include "mapping_info.h"
13
14#define WIDTH           128
15#define HEIGHT          128
16#define NB_CLUSTER_MAX  256
17#define NB_ITERATION    1000000000
18
19#define PRINTF(...) ({ if ( proc_id==0) { giet_tty_printf(__VA_ARGS__); } })
20
21giet_barrier_t barriers[2];
22
23unsigned int init_ok = 1;
24
25#define NEW 0
26#define OLD 1
27
28typedef unsigned char uint8_t;
29typedef unsigned int size_t;
30
31uint8_t world[2][HEIGHT][WIDTH];
32uint8_t world_yuv[HEIGHT][WIDTH];
33
34/* Generate binary values for world between base_line and base_line + nb_line */
35void init_world(size_t base_line, size_t nb_line)
36{
37   size_t x,y;
38   for (y = base_line ; y < base_line + nb_line; y++){
39      for(x = 0; x < WIDTH ; x++) {
40         // TODO OPTIMIZE RANDOM INIT
41         world[OLD][y][x] = giet_rand() % 2; 
42      }
43   }
44}
45
46uint8_t number_of_alive_neigh(size_t x, size_t y)
47{
48   uint8_t nb = 0;
49
50   nb += world[OLD][(y - 1) % HEIGHT][(x - 1) % WIDTH];
51   nb += world[OLD][ y              ][(x - 1) % WIDTH];
52   nb += world[OLD][(y + 1) % HEIGHT][(x - 1) % WIDTH];
53   nb += world[OLD][(y - 1) % HEIGHT][ x             ];
54   nb += world[OLD][(y + 1) % HEIGHT][ x             ];
55   nb += world[OLD][(y - 1) % HEIGHT][(x + 1) % WIDTH];
56   nb += world[OLD][ y              ][(x + 1) % WIDTH];
57   nb += world[OLD][(y + 1) % HEIGHT][(x + 1) % WIDTH];
58
59   return nb;
60}
61
62/* Compute cell x,y */
63uint8_t compute_cell(size_t x, size_t y)
64{
65   uint8_t nb_neighbours_alive = number_of_alive_neigh(x,y);
66   if (world[OLD][y][x] == 1) {
67      if (nb_neighbours_alive == 2 ||
68          nb_neighbours_alive == 3) 
69      {
70         return 1;   
71      }
72   }
73   else {
74      if (nb_neighbours_alive == 3) {
75         return 1;
76      }
77      else {
78         return world[OLD][y][x];
79      }
80   }
81   return 0;
82}
83
84//////////////////////////////////////////////////////
85void compute_new_gen(size_t base_line, size_t nb_line)
86{
87   size_t x,y;
88   for (y = base_line; y < base_line + nb_line; y++)
89   {
90      for(x = 0; x < WIDTH ; x++) 
91      {
92         world[NEW][y][x] = compute_cell(x,y); 
93      }
94   }
95}
96
97////////////////////////////////////////////////////
98void display_world(size_t base_line, size_t nb_line)
99{
100   size_t x,y;
101   for (y = base_line; y < base_line + nb_line; y++){
102      for(x = 0; x < WIDTH ; x++) {
103         //world_yuv[y][x] = world[NEW][y][x]*100; 
104         world[NEW][y][x] = world[NEW][y][x]*255; 
105      }
106   }
107
108   giet_fb_sync_write( base_line * WIDTH , 
109                       &world[NEW][base_line][0], 
110                       nb_line * WIDTH);
111}
112
113/////////////////////////////////////////////////////
114void grow_old_world(size_t base_line, size_t nb_line)
115{
116   size_t x,y;
117   for (y = base_line; y < base_line + nb_line; y++)
118   {
119      for(x = 0; x < WIDTH ; x++) 
120      {
121         world[OLD][y][x] = world[NEW][y][x]; 
122      }
123   }
124}
125
126////////////////////////////////////////
127__attribute__((constructor)) void main()
128{
129   // get processor identifier
130   unsigned int x;
131   unsigned int y;
132   unsigned int p;
133   giet_proc_xyp( &x, &y, &p );
134
135   // compute continuous processor index
136   unsigned int proc_id = (((x * Y_SIZE) + y) * NB_PROCS_MAX) + p; 
137
138   unsigned int nlocal_procs  = NB_PROCS_MAX;               // processors per cluster
139   unsigned int nclusters     = X_SIZE*Y_SIZE;              // number of clusters
140   unsigned int nglobal_procs = nclusters * nlocal_procs;   // number of processors
141   size_t i;
142
143   size_t       nb_line       = HEIGHT / nglobal_procs;
144   size_t       base_line     = nb_line * proc_id; 
145   
146   PRINTF("*** Starting init at cycle %d ***\n", giet_proctime());
147
148   //  barriers initialization
149   if ( proc_id == 0 )
150   {
151      barrier_init(&barriers[0], nglobal_procs);
152      barrier_init(&barriers[1], nglobal_procs);
153
154      init_ok = 0;
155   }
156   else
157   {
158      while ( init_ok == 1 );
159   }
160
161   init_world(base_line, nb_line);
162
163   PRINTF("*** Completing init at cycle %d ***\n", giet_proctime());
164   barrier_wait(&barriers[0]);
165   
166   for (i = 0; i < NB_ITERATION; i++)
167   {
168      compute_new_gen(base_line, nb_line);
169      grow_old_world(base_line, nb_line);
170      display_world(base_line, nb_line);
171      barrier_wait(&barriers[1]);
172      barrier_init(&barriers[1], nglobal_procs);
173   }
174
175   PRINTF("*** End of main at cycle %d ***\n", giet_proctime());
176
177   giet_exit("Completed");
178} // end main()
179
180// Local Variables:
181// tab-width: 3
182// c-basic-offset: 3
183// c-file-offsets:((innamespace . 0)(inline-open . 0))
184// indent-tabs-mode: nil
185// End:
186
187// vim: filetype=cpp:expandtab:shiftwidth=3:tabstop=3:softtabstop=3
188
189
190
Note: See TracBrowser for help on using the repository browser.