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

Last change on this file since 670 was 631, checked in by alain, 11 years ago

Introducing support for RAMDISK in giet_tsar

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