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

Last change on this file since 888 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
RevLine 
[244]1
[629]2#include "hard_config.h"
[158]3#include "stdio.h"
[244]4#include "limits.h"
5#include "../giet_tsar/block_device.h"
[158]6
[629]7#define NL              128
8#define NP              128
9#define NB_IMAGES       5
[631]10 
11// Only processor 0 in each cluster access TTY
[629]12#define PRINTF(...)      ({ if (lpid == 0) { _tty_printf(__VA_ARGS__); } })
[158]13
[744]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
[248]17
[631]18// tricks to read some addresses from ldscript
[629]19extern struct plaf seg_ioc_base;
20extern struct plaf seg_heap_base;
[158]21
[629]22// global variables stored in seg_data (cluster 0)
[158]23
[631]24// instrumentation counters (for each processor)
[629]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];
[158]31
[631]32// checksum variables (used by proc(0,0,0) only
[629]33unsigned check_line_before[NL];
34unsigned check_line_after[NL];
35
[158]36/////////////
[629]37void main()
38{
39    unsigned int image = 0;
[158]40
[629]41    unsigned int l;                                             // line index for loops
42    unsigned int p;                                             // pixel index for loops
[744]43    unsigned int block_size  = _ioc_get_blocksize();            // get IOC block size
[629]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
[158]53
[629]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
[631]60    PRINTF("\n *** Proc [%d,%d,0] enters main at cycle %d ***\n\n", 
[629]61           x, y, _proctime());
62
[244]63   //  parameters checking
[629]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();
[244]68   }
69   if ((nclusters != 1) && (nclusters != 2) && (nclusters != 4) && (nclusters != 8) &&
70         (nclusters != 16) && (nclusters != 32) && (nclusters != 64) && (nclusters != 128) &&
[629]71         (nclusters != 256))
72   {
[244]73      PRINTF("NB_CLUSTERS must be a power of 1 between 1 and 256\n");
[629]74      _exit();
[244]75   }
[158]76
[629]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;
[158]81
[244]82   PRINTF("NB_CLUSTERS     = %d\n", nclusters); 
[629]83   PRINTF("NB_LOCAL_PROCS  = %d\n", NB_PROCS_MAX); 
84   PRINTF("NB_TASKS        = %d\n", ntasks);
[244]85   PRINTF("NB_PIXELS       = %d\n", npixels);
86   PRINTF("BLOCK_SIZE      = %d\n", block_size);
87   PRINTF("NB_BLOCKS       = %d\n\n", nblocks);
[158]88
[629]89   PRINTF("*** Proc 0 in cluster [%d,%d] starts barrier init at cycle %d\n", 
90          x, y, _proctime());
[158]91
[244]92   //  barriers initialization
[629]93   _barrier_init(0, ntasks);
94   _barrier_init(1, ntasks);
95   _barrier_init(2, ntasks);
96   _barrier_init(3, ntasks);
[158]97
[631]98   PRINTF("*** Proc [%d,%d,0] completes barrier init at cycle %d\n",
[629]99          x, y, _proctime());
[171]100
[629]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
[171]106
[629]107      LOAD_START[cluster_id][lpid] = _proctime();
[158]108
[629]109      if (lpid == 0)
110      {
[631]111         PRINTF("\n*** Proc [%d,%d,0] starts load for image %d at cycle %d\n",
112                x, y, image, _proctime() );
113
[629]114         _ioc_read( ((image * nblocks) + ((nblocks * cluster_id) / nclusters)), 
115                    buf_in,
116                    (nblocks / nclusters),
117                    cluster_xy );
[158]118
[629]119         _ioc_completed();
120
[631]121         PRINTF("*** Proc [%d,%d,0] completes load for image %d at cycle %d\n",
[629]122                x, y, image, _proctime() );
[244]123      }
[158]124
[629]125      LOAD_END[cluster_id][lpid] = _proctime();
[158]126
[744]127
128      _tty_printf("*** Proc [%d,%d,%d] barrier wait (0)\n", x, y, lpid);
[629]129      _barrier_wait(0);
[158]130
[629]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
[158]134
[631]135      PRINTF("\n*** proc [%d,%d,0] starts transpose for image %d at cycle %d\n", 
[629]136             x, y, image, _proctime());
[158]137
[629]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      {
[244]155         PRINTF("    - processing line %d\n", l);
[629]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 );
[244]204         }
205      }
[158]206
[631]207      PRINTF("*** proc [%d,%d,0] complete transpose for image %d at cycle %d\n", 
[629]208             x, y, image, _proctime() );
[158]209
[629]210      TRSP_END[cluster_id][lpid] = _proctime();
[158]211
[629]212      _barrier_wait(1);
[158]213
[629]214      // optional parallel display from local buf_out to frame buffer
[158]215
[631]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() );
[629]220
[631]221          DISP_START[cluster_id][lpid] = _proctime();
[629]222
[631]223          unsigned int npxt = npixels / ntasks;   // number of pixels per task
224          unsigned int buffer = (unsigned int)buf_out + npxt*lpid;
[629]225
[631]226          _fb_sync_write( npxt * task_id, buffer, npxt, cluster_xy );
[629]227
[631]228          PRINTF("*** Proc [%d,%d,0] completes display for image %d at cycle %d\n",
229                 x, y, image, _proctime() );
[629]230
[631]231          DISP_END[cluster_id][lpid] = _proctime();
[629]232
[631]233          _barrier_wait(2);
234      }
[629]235
[631]236      // checksum (done by processor 0 in each cluster)
[629]237
[631]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() );
[158]242
[629]243         unsigned int success = 1;
[631]244         unsigned int start   = cluster_id * (NL / nclusters);
245         unsigned int stop    = start + (NL / nclusters);
[171]246
[631]247         for ( l = start ; l < stop ; l++ )
[629]248         {
249            check_line_after[l] = 0;
[171]250
[629]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;
[171]257
[629]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
[631]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            }
[629]269
270            if ( check_line_before[l] != check_line_after[l] ) success = 0;
271         }
272
[631]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      }
[629]276
[631]277      // instrumentation ( done by processor [0,0,0]
278
279      if ( (proc_id == 0) && INSTRUMENTATION_OK )
280      {
[244]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;
[171]294
[629]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];
[171]311            }
[244]312         }
[171]313
[244]314         PRINTF(" - LOAD_START : min = %d / max = %d / med = %d / delta = %d\n",
[629]315               min_load_start, max_load_start, (min_load_start+max_load_start)/2, 
316               max_load_start-min_load_start); 
317
[244]318         PRINTF(" - LOAD_END   : min = %d / max = %d / med = %d / delta = %d\n",
[629]319               min_load_ended, max_load_ended, (min_load_ended+max_load_ended)/2, 
320               max_load_ended-min_load_ended); 
[171]321
[244]322         PRINTF(" - TRSP_START : min = %d / max = %d / med = %d / delta = %d\n",
[629]323               min_trsp_start, max_trsp_start, (min_trsp_start+max_trsp_start)/2, 
324               max_trsp_start-min_trsp_start); 
325
[244]326         PRINTF(" - TRSP_END   : min = %d / max = %d / med = %d / delta = %d\n",
[629]327               min_trsp_ended, max_trsp_ended, (min_trsp_ended+max_trsp_ended)/2, 
328               max_trsp_ended-min_trsp_ended); 
[171]329
[244]330         PRINTF(" - DISP_START : min = %d / max = %d / med = %d / delta = %d\n",
[629]331               min_disp_start, max_disp_start, (min_disp_start+max_disp_start)/2, 
332               max_disp_start-min_disp_start); 
333
[244]334         PRINTF(" - DISP_END   : min = %d / max = %d / med = %d / delta = %d\n",
[629]335               min_disp_ended, max_disp_ended, (min_disp_ended+max_disp_ended)/2, 
336               max_disp_ended-min_disp_ended); 
[244]337      }
[171]338
[629]339      image++;
[244]340
[629]341      _barrier_wait( 3 );
342   } // end while image     
[244]343
[629]344
345   _exit();
346
[158]347} // end main()
348
[244]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.