source: trunk/softs/soft_transpose_giet/main.c @ 986

Last change on this file since 986 was 744, checked in by cfuguet, 10 years ago

giet_tsar: using CLUSTER_IO constant in stdio functions

  • Erasing also extra end-of-line spaces
File size: 13.9 KB
Line 
1
2#include "hard_config.h"
3#include "stdio.h"
4#include "limits.h"
5#include "../giet_tsar/block_device.h"
6
7#define NL              128
8#define NP              128
9#define NB_IMAGES       5
10 
11// Only processor 0 in each cluster access TTY
12#define PRINTF(...)      ({ if (lpid == 0) { _tty_printf(__VA_ARGS__); } })
13
14#define DISPLAY_OK          1           // enable display on frame buffer when non zero
15#define CHECK_VERBOSE       !DISPLAY_OK // display a detailed check on TTY  when non zero
16#define INSTRUMENTATION_OK  0           // display statistcs on TTY when non zero
17
18// tricks to read some addresses from ldscript
19extern struct plaf seg_ioc_base;
20extern struct plaf seg_heap_base;
21
22// global variables stored in seg_data (cluster 0)
23
24// instrumentation counters (for each processor)
25unsigned int LOAD_START[256][4];
26unsigned int LOAD_END  [256][4];
27unsigned int TRSP_START[256][4];
28unsigned int TRSP_END  [256][4];
29unsigned int DISP_START[256][4];
30unsigned int DISP_END  [256][4];
31
32// checksum variables (used by proc(0,0,0) only
33unsigned check_line_before[NL];
34unsigned check_line_after[NL];
35
36/////////////
37void main()
38{
39    unsigned int image = 0;
40
41    unsigned int l;                                             // line index for loops
42    unsigned int p;                                             // pixel index for loops
43    unsigned int block_size  = _ioc_get_blocksize();            // get IOC block size
44    unsigned int proc_id     = _procid();                       // processor id
45    unsigned int nclusters   = X_SIZE*Y_SIZE;                   // number of clusters
46    unsigned int lpid        = proc_id % NB_PROCS_MAX;          // local processor id
47    unsigned int cluster_xy  = proc_id / NB_PROCS_MAX;          // cluster index (8 bits format)
48    unsigned int x           = cluster_xy >> Y_WIDTH;           // x coordinate
49    unsigned int y           = cluster_xy & ((1<<Y_WIDTH)-1);   // y coordinate
50    unsigned int ntasks      = nclusters * NB_PROCS_MAX;        // number of tasks
51    unsigned int npixels     = NP * NL;                         // number of pixel per image
52    unsigned int nblocks     = npixels / block_size;            // number of blocks per image
53
54    // task_id is a "continuous" index for the the task running on processor (x,y,lpid)
55    unsigned int task_id = (((x * Y_SIZE) + y) * NB_PROCS_MAX) + lpid;
56
57    // cluster_id is a "continuous" index for cluster(x,y)
58    unsigned int cluster_id  = (x * Y_SIZE) + y;               
59
60    PRINTF("\n *** Proc [%d,%d,0] enters main at cycle %d ***\n\n", 
61           x, y, _proctime());
62
63   //  parameters checking
64   if ((NB_PROCS_MAX != 1) && (NB_PROCS_MAX != 2) && (NB_PROCS_MAX != 4))
65   {
66      PRINTF("NB_PROCS_MAX must be 1, 2 or 4\n");
67      _exit();
68   }
69   if ((nclusters != 1) && (nclusters != 2) && (nclusters != 4) && (nclusters != 8) &&
70         (nclusters != 16) && (nclusters != 32) && (nclusters != 64) && (nclusters != 128) &&
71         (nclusters != 256))
72   {
73      PRINTF("NB_CLUSTERS must be a power of 1 between 1 and 256\n");
74      _exit();
75   }
76
77   // pointers on the distributed buffers containing the images,
78   // allocated in the heap segment: each buffer contains 256 Kbytes
79   unsigned char* buf_in  = (unsigned char*)&seg_heap_base;
80   unsigned char* buf_out = buf_in + 0x00100000;
81
82   PRINTF("NB_CLUSTERS     = %d\n", nclusters); 
83   PRINTF("NB_LOCAL_PROCS  = %d\n", NB_PROCS_MAX); 
84   PRINTF("NB_TASKS        = %d\n", ntasks);
85   PRINTF("NB_PIXELS       = %d\n", npixels);
86   PRINTF("BLOCK_SIZE      = %d\n", block_size);
87   PRINTF("NB_BLOCKS       = %d\n\n", nblocks);
88
89   PRINTF("*** Proc 0 in cluster [%d,%d] starts barrier init at cycle %d\n", 
90          x, y, _proctime());
91
92   //  barriers initialization
93   _barrier_init(0, ntasks);
94   _barrier_init(1, ntasks);
95   _barrier_init(2, ntasks);
96   _barrier_init(3, ntasks);
97
98   PRINTF("*** Proc [%d,%d,0] completes barrier init at cycle %d\n",
99          x, y, _proctime());
100
101   // Main loop (on images)
102   while (image < NB_IMAGES)
103   {
104      // pseudo parallel load from disk to buf_in buffer : nblocks/nclusters blocks
105      // only task running on processor with (lpid == 0) does it
106
107      LOAD_START[cluster_id][lpid] = _proctime();
108
109      if (lpid == 0)
110      {
111         PRINTF("\n*** Proc [%d,%d,0] starts load for image %d at cycle %d\n",
112                x, y, image, _proctime() );
113
114         _ioc_read( ((image * nblocks) + ((nblocks * cluster_id) / nclusters)), 
115                    buf_in,
116                    (nblocks / nclusters),
117                    cluster_xy );
118
119         _ioc_completed();
120
121         PRINTF("*** Proc [%d,%d,0] completes load for image %d at cycle %d\n",
122                x, y, image, _proctime() );
123      }
124
125      LOAD_END[cluster_id][lpid] = _proctime();
126
127
128      _tty_printf("*** Proc [%d,%d,%d] barrier wait (0)\n", x, y, lpid);
129      _barrier_wait(0);
130
131      // parallel transpose from buf_in to buf_out buffers
132      // each processor makes the transposition for (NL/ntasks) lines
133      // (p,l) are the pixel coordinates in the source image
134
135      PRINTF("\n*** proc [%d,%d,0] starts transpose for image %d at cycle %d\n", 
136             x, y, image, _proctime());
137
138      TRSP_START[cluster_id][lpid] = _proctime();
139
140      unsigned int nlt   = NL / ntasks;                // number of lines per processor
141      unsigned int first = task_id * nlt;              // first line index
142      unsigned int last  = first + nlt;                // last line index
143      unsigned int nlines_clusters = NL / nclusters;   // number of lines per cluster
144      unsigned int npix_clusters   = NP / nclusters;   // number of pixels per cluster
145
146      unsigned int src_cluster;
147      unsigned int src_index;
148      unsigned int dst_cluster;
149      unsigned int dst_index;
150
151      unsigned int word;
152
153      for (l = first; l < last; l++)
154      {
155         PRINTF("    - processing line %d\n", l);
156
157         check_line_before[l] = 0;
158         
159         // in each iteration we read one word an write four bytes
160         for (p = 0 ; p < NP ; p = p+4)
161         {
162            // read one word, with extended address from local buffer
163            src_cluster = cluster_xy;
164            src_index   = (l % nlines_clusters) * NP + p;
165            word = _word_extended_read( src_cluster, 
166                                        (unsigned int)&buf_in[src_index] );
167
168            unsigned char byte0 = (unsigned char)( word      & 0x000000FF);
169            unsigned char byte1 = (unsigned char)((word>>8)  & 0x000000FF);
170            unsigned char byte2 = (unsigned char)((word>>16) & 0x000000FF);
171            unsigned char byte3 = (unsigned char)((word>>24) & 0x000000FF);
172
173            // compute checksum
174            check_line_before[l] = check_line_before[l] + byte0 + byte1 + byte2 + byte3;
175
176            // write four bytes with extended address to four remote buffers
177            dst_cluster = (((p / npix_clusters) / Y_SIZE) << Y_WIDTH) + 
178                           ((p / npix_clusters) % Y_SIZE);
179            dst_index   = (p % npix_clusters) * NL + l;
180            _byte_extended_write( dst_cluster, 
181                                  (unsigned int)&buf_out[dst_index], 
182                                  byte0 );
183
184            dst_cluster = ((((p+1) / npix_clusters) / Y_SIZE) << Y_WIDTH) + 
185                           (((p+1) / npix_clusters) % Y_SIZE);
186            dst_index   = ((p+1) % npix_clusters) * NL + l;
187            _byte_extended_write( dst_cluster, 
188                                  (unsigned int)&buf_out[dst_index], 
189                                  byte1 );
190
191            dst_cluster = ((((p+2) / npix_clusters) / Y_SIZE) << Y_WIDTH) + 
192                           (((p+2) / npix_clusters) % Y_SIZE);
193            dst_index   = ((p+2) % npix_clusters) * NL + l;
194            _byte_extended_write( dst_cluster, 
195                                  (unsigned int)&buf_out[dst_index], 
196                                  byte2 );
197
198            dst_cluster = ((((p+3) / npix_clusters) / Y_SIZE) << Y_WIDTH) + 
199                           (((p+3) / npix_clusters) % Y_SIZE);
200            dst_index   = ((p+3) % npix_clusters) * NL + l;
201            _byte_extended_write( dst_cluster, 
202                                  (unsigned int)&buf_out[dst_index], 
203                                  byte3 );
204         }
205      }
206
207      PRINTF("*** proc [%d,%d,0] complete transpose for image %d at cycle %d\n", 
208             x, y, image, _proctime() );
209
210      TRSP_END[cluster_id][lpid] = _proctime();
211
212      _barrier_wait(1);
213
214      // optional parallel display from local buf_out to frame buffer
215
216      if ( DISPLAY_OK )
217      {
218          PRINTF("\n*** proc [%d,%d,0] starts display for image %d at cycle %d\n", 
219                 x, y, image, _proctime() );
220
221          DISP_START[cluster_id][lpid] = _proctime();
222
223          unsigned int npxt = npixels / ntasks;   // number of pixels per task
224          unsigned int buffer = (unsigned int)buf_out + npxt*lpid;
225
226          _fb_sync_write( npxt * task_id, buffer, npxt, cluster_xy );
227
228          PRINTF("*** Proc [%d,%d,0] completes display for image %d at cycle %d\n",
229                 x, y, image, _proctime() );
230
231          DISP_END[cluster_id][lpid] = _proctime();
232
233          _barrier_wait(2);
234      }
235
236      // checksum (done by processor 0 in each cluster)
237
238      if ( lpid == 0 )
239      {
240         PRINTF("\n*** Proc [%d,%d,0] starts checks for image %d at cycle %d\n\n",
241                x, y, image, _proctime() );
242
243         unsigned int success = 1;
244         unsigned int start   = cluster_id * (NL / nclusters);
245         unsigned int stop    = start + (NL / nclusters);
246
247         for ( l = start ; l < stop ; l++ )
248         {
249            check_line_after[l] = 0;
250
251            for ( p = 0 ; p < NP ; p++ )
252            {
253               // read one byte in remote buffer
254               src_cluster = (((p / npix_clusters) / Y_SIZE) << Y_WIDTH) +
255                             ((p / npix_clusters) % Y_SIZE);
256               src_index   = (p % npix_clusters) * NL + l;
257
258               unsigned char byte = _byte_extended_read( src_cluster,
259                                                         (unsigned int)&buf_out[src_index] );
260
261               check_line_after[l] = check_line_after[l] + byte;
262            }
263
264            if( CHECK_VERBOSE )
265            {
266                PRINTF(" - l = %d / before = %d / after = %d \n",
267                       l, check_line_before[l], check_line_after[l] );
268            }
269
270            if ( check_line_before[l] != check_line_after[l] ) success = 0;
271         }
272
273         if ( success ) PRINTF("\n*** proc [%d,%d,0] : CHECKSUM OK \n\n", x, y);
274         else           PRINTF("\n*** proc [%d,%d,0] : CHECKSUM KO \n\n", x, y);
275      }
276
277      // instrumentation ( done by processor [0,0,0]
278
279      if ( (proc_id == 0) && INSTRUMENTATION_OK )
280      {
281         int cc, pp;
282         unsigned int min_load_start = INT_MAX;
283         unsigned int max_load_start = 0;
284         unsigned int min_load_ended = INT_MAX;
285         unsigned int max_load_ended = 0;
286         unsigned int min_trsp_start = INT_MAX;
287         unsigned int max_trsp_start = 0;
288         unsigned int min_trsp_ended = INT_MAX;
289         unsigned int max_trsp_ended = 0;
290         unsigned int min_disp_start = INT_MAX;
291         unsigned int max_disp_start = 0;
292         unsigned int min_disp_ended = INT_MAX;
293         unsigned int max_disp_ended = 0;
294
295         for (cc = 0; cc < nclusters; cc++)
296         {
297            for (pp = 0; pp < NB_PROCS_MAX; pp++)
298            {
299               if (LOAD_START[cc][pp] < min_load_start)  min_load_start = LOAD_START[cc][pp];
300               if (LOAD_START[cc][pp] > max_load_start)  max_load_start = LOAD_START[cc][pp];
301               if (LOAD_END[cc][pp]   < min_load_ended)  min_load_ended = LOAD_END[cc][pp]; 
302               if (LOAD_END[cc][pp]   > max_load_ended)  max_load_ended = LOAD_END[cc][pp];
303               if (TRSP_START[cc][pp] < min_trsp_start)  min_trsp_start = TRSP_START[cc][pp];
304               if (TRSP_START[cc][pp] > max_trsp_start)  max_trsp_start = TRSP_START[cc][pp];
305               if (TRSP_END[cc][pp]   < min_trsp_ended)  min_trsp_ended = TRSP_END[cc][pp];
306               if (TRSP_END[cc][pp]   > max_trsp_ended)  max_trsp_ended = TRSP_END[cc][pp];
307               if (DISP_START[cc][pp] < min_disp_start)  min_disp_start = DISP_START[cc][pp];
308               if (DISP_START[cc][pp] > max_disp_start)  max_disp_start = DISP_START[cc][pp];
309               if (DISP_END[cc][pp]   < min_disp_ended)  min_disp_ended = DISP_END[cc][pp];
310               if (DISP_END[cc][pp]   > max_disp_ended)  max_disp_ended = DISP_END[cc][pp];
311            }
312         }
313
314         PRINTF(" - LOAD_START : min = %d / max = %d / med = %d / delta = %d\n",
315               min_load_start, max_load_start, (min_load_start+max_load_start)/2, 
316               max_load_start-min_load_start); 
317
318         PRINTF(" - LOAD_END   : min = %d / max = %d / med = %d / delta = %d\n",
319               min_load_ended, max_load_ended, (min_load_ended+max_load_ended)/2, 
320               max_load_ended-min_load_ended); 
321
322         PRINTF(" - TRSP_START : min = %d / max = %d / med = %d / delta = %d\n",
323               min_trsp_start, max_trsp_start, (min_trsp_start+max_trsp_start)/2, 
324               max_trsp_start-min_trsp_start); 
325
326         PRINTF(" - TRSP_END   : min = %d / max = %d / med = %d / delta = %d\n",
327               min_trsp_ended, max_trsp_ended, (min_trsp_ended+max_trsp_ended)/2, 
328               max_trsp_ended-min_trsp_ended); 
329
330         PRINTF(" - DISP_START : min = %d / max = %d / med = %d / delta = %d\n",
331               min_disp_start, max_disp_start, (min_disp_start+max_disp_start)/2, 
332               max_disp_start-min_disp_start); 
333
334         PRINTF(" - DISP_END   : min = %d / max = %d / med = %d / delta = %d\n",
335               min_disp_ended, max_disp_ended, (min_disp_ended+max_disp_ended)/2, 
336               max_disp_ended-min_disp_ended); 
337      }
338
339      image++;
340
341      _barrier_wait( 3 );
342   } // end while image     
343
344
345   _exit();
346
347} // end main()
348
349// Local Variables:
350// tab-width: 3
351// c-basic-offset: 3
352// c-file-offsets:((innamespace . 0)(inline-open . 0))
353// indent-tabs-mode: nil
354// End:
355
356// vim: filetype=cpp:expandtab:shiftwidth=3:tabstop=3:softtabstop=3
357
358
359
Note: See TracBrowser for help on using the repository browser.