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

Last change on this file since 508 was 504, checked in by alain, 10 years ago

Bug fix in the distributed heap mapping.

File size: 5.5 KB
Line 
1//////////////////////////////////////////////////////////////////////////////////
2// File : main.c  (for gameoflife)
3// Date : November 2013
4// Author :  Alexandre Joannou <alexandre.joannou@lip6.fr>
5//
6// This application is an emulation of the game of life automaton.
7// 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// The number of processors must be a power of 2 not larger than HEIGHT.
10//////////////////////////////////////////////////////////////////////////////////
11
12#include "stdio.h"
13#include "limits.h"
14#include "user_barrier.h"
15#include "mapping_info.h"
16
17#define WIDTH           128
18#define HEIGHT          128
19#define NB_ITERATION    1000000000
20
21#define PRINTF(...) ({ if ( proc_id==0) { giet_shr_printf(__VA_ARGS__); } })
22
23giet_sqt_barrier_t barrier;
24
25volatile unsigned int init_ok;
26
27#define OLD 0
28#define NEW 1
29#define DSP 2
30
31typedef unsigned char uint8_t;
32typedef unsigned int size_t;
33
34uint8_t world[3][HEIGHT][WIDTH];
35
36/////////////////////////////////////////////////
37void 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++)
41   {
42      for(x = 0; x < WIDTH ; x++) 
43      {
44         world[OLD][y][x] = (giet_rand() >> (x % 8)) & 0x1;
45      }
46   }
47}
48
49/////////////////////////////////////////////////
50uint8_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/////////////////////////////////////////////////
67uint8_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//////////////////////////////////////////////////////
83void compute_new_gen(size_t base_line, size_t nb_line)
84{
85   size_t x,y;
86   for (y = base_line; y < base_line + nb_line; y++)
87   {
88      for(x = 0; x < WIDTH ; x++) 
89      {
90         world[NEW][y][x] = compute_cell(x,y); 
91      }
92   }
93}
94
95////////////////////////////////////////////////////
96void 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/////////////////////////////////////////////////////
113void 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]; 
121      }
122   }
123}
124
125////////////////////////////////////////
126__attribute__((constructor)) void main()
127{
128   // get processor identifier
129   unsigned int x;
130   unsigned int y;
131   unsigned int p;
132   giet_proc_xyp( &x, &y, &p );
133
134   // get processors number
135   unsigned int x_size;
136   unsigned int y_size;
137   unsigned int n_local_procs;
138   giet_procs_number( &x_size, &y_size, &n_local_procs );
139
140   // compute continuous processor index
141   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;
146
147   if ( n_global_procs > HEIGHT )
148   {
149       PRINTF("[GAMEOFLIFE ERROR] Number or processors too large :"
150              " nb_procs = %d / image heigth = %d\n", n_global_procs, HEIGHT );
151       giet_exit("error");
152   }
153
154   size_t       nb_line       = HEIGHT / n_global_procs;
155   size_t       base_line     = nb_line * proc_id; 
156   
157   PRINTF("\n*** Starting barrier initialisation at cycle %d ***\n"
158          " nprocs = %d / nlines = %d\n", 
159          giet_proctime() , n_global_procs, HEIGHT );
160
161   // barrier initialization
162   if ( proc_id == 0 )
163   {
164      sqt_barrier_init( &barrier , x_size , y_size , n_local_procs );
165      init_ok = 1;
166   }
167   else
168   {
169      while ( init_ok == 0 ) asm volatile("nop\n nop\n nop");
170   }
171
172   PRINTF("\n*** Starting world initialisation at cycle %d ***\n",
173          giet_proctime() );
174
175   //  parallel world  initialization
176   init_world( base_line , nb_line );
177   display_world( base_line , nb_line );
178
179   sqt_barrier_wait( &barrier );
180
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
190      sqt_barrier_wait( &barrier );
191
192      PRINTF(" - iteration %d completed\n", i );
193   }
194
195   PRINTF("\n*** End of main at cycle %d ***\n", giet_proctime());
196
197   giet_exit("Completed");
198} // end main()
199
200// Local Variables:
201// tab-width: 3
202// c-basic-offset: 3
203// c-file-offsets:((innamespace . 0)(inline-open . 0))
204// indent-tabs-mode: nil
205// End:
206
207// vim: filetype=cpp:expandtab:shiftwidth=3:tabstop=3:softtabstop=3
208
209
210
Note: See TracBrowser for help on using the repository browser.