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

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

1) Introduce distributed barriers in the multi-threads applications
(classif) transpose, convol, sort, gameoflife)

2) Introducing support for architectures containing empty clusters
in the mapping of these multi-threaded applications.

3) Removing the "command line arguments" in the sort application
(replaced by the giet_procs_number() system call.

File size: 5.6 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
25unsigned int init_ok = 0;
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() % 2; 
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");
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
178PRINTF("coucou 0\n");
179
180   display_world( base_line , nb_line );
181
182PRINTF("coucou 1\n");
183
184   sqt_barrier_wait( &barrier );
185
186   PRINTF("\n*** Starting life at cycle %d ***\n", 
187          giet_proctime() );
188   
189   for (i = 0; i < NB_ITERATION; i++)
190   {
191      compute_new_gen( base_line, nb_line );
192      grow_old_world( base_line, nb_line );
193      display_world( base_line, nb_line );
194
195      sqt_barrier_wait( &barrier );
196
197      PRINTF(" - iteration %d completed\n", i );
198   }
199
200   PRINTF("\n*** End of main at cycle %d ***\n", giet_proctime());
201
202   giet_exit("Completed");
203} // end main()
204
205// Local Variables:
206// tab-width: 3
207// c-basic-offset: 3
208// c-file-offsets:((innamespace . 0)(inline-open . 0))
209// indent-tabs-mode: nil
210// End:
211
212// vim: filetype=cpp:expandtab:shiftwidth=3:tabstop=3:softtabstop=3
213
214
215
Note: See TracBrowser for help on using the repository browser.