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

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

Introducing support for RAMDISK in giet_tsar

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       1   // 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
44    unsigned int * ioc_address = (unsigned int *) &seg_ioc_base;
45    unsigned int block_size    = ioc_address[BLOCK_DEVICE_BLOCK_SIZE];
46
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
56
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
63    PRINTF("\n *** Proc [%d,%d,0] enters main at cycle %d ***\n\n", 
64           x, y, _proctime());
65
66   //  parameters checking
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();
71   }
72   if ((nclusters != 1) && (nclusters != 2) && (nclusters != 4) && (nclusters != 8) &&
73         (nclusters != 16) && (nclusters != 32) && (nclusters != 64) && (nclusters != 128) &&
74         (nclusters != 256))
75   {
76      PRINTF("NB_CLUSTERS must be a power of 1 between 1 and 256\n");
77      _exit();
78   }
79
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;
84
85   PRINTF("NB_CLUSTERS     = %d\n", nclusters); 
86   PRINTF("NB_LOCAL_PROCS  = %d\n", NB_PROCS_MAX); 
87   PRINTF("NB_TASKS        = %d\n", ntasks);
88   PRINTF("NB_PIXELS       = %d\n", npixels);
89   PRINTF("BLOCK_SIZE      = %d\n", block_size);
90   PRINTF("NB_BLOCKS       = %d\n\n", nblocks);
91
92   PRINTF("*** Proc 0 in cluster [%d,%d] starts barrier init at cycle %d\n", 
93          x, y, _proctime());
94
95   //  barriers initialization
96   _barrier_init(0, ntasks);
97   _barrier_init(1, ntasks);
98   _barrier_init(2, ntasks);
99   _barrier_init(3, ntasks);
100
101   PRINTF("*** Proc [%d,%d,0] completes barrier init at cycle %d\n",
102          x, y, _proctime());
103
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
109
110      LOAD_START[cluster_id][lpid] = _proctime();
111
112      if (lpid == 0)
113      {
114         PRINTF("\n*** Proc [%d,%d,0] starts load for image %d at cycle %d\n",
115                x, y, image, _proctime() );
116
117         _ioc_read( ((image * nblocks) + ((nblocks * cluster_id) / nclusters)), 
118                    buf_in,
119                    (nblocks / nclusters),
120                    cluster_xy );
121
122         _ioc_completed();
123
124         PRINTF("*** Proc [%d,%d,0] completes load for image %d at cycle %d\n",
125                x, y, image, _proctime() );
126      }
127
128      LOAD_END[cluster_id][lpid] = _proctime();
129
130      _barrier_wait(0);
131
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
135
136      PRINTF("\n*** proc [%d,%d,0] starts transpose for image %d at cycle %d\n", 
137             x, y, image, _proctime());
138
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      {
156         PRINTF("    - processing line %d\n", l);
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 );
205         }
206      }
207
208      PRINTF("*** proc [%d,%d,0] complete transpose for image %d at cycle %d\n", 
209             x, y, image, _proctime() );
210
211      TRSP_END[cluster_id][lpid] = _proctime();
212
213      _barrier_wait(1);
214
215      // optional parallel display from local buf_out to frame buffer
216
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() );
221
222          DISP_START[cluster_id][lpid] = _proctime();
223
224          unsigned int npxt = npixels / ntasks;   // number of pixels per task
225          unsigned int buffer = (unsigned int)buf_out + npxt*lpid;
226
227          _fb_sync_write( npxt * task_id, buffer, npxt, cluster_xy );
228
229          PRINTF("*** Proc [%d,%d,0] completes display for image %d at cycle %d\n",
230                 x, y, image, _proctime() );
231
232          DISP_END[cluster_id][lpid] = _proctime();
233
234          _barrier_wait(2);
235      }
236
237      // checksum (done by processor 0 in each cluster)
238
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() );
243
244         unsigned int success = 1;
245         unsigned int start   = cluster_id * (NL / nclusters);
246         unsigned int stop    = start + (NL / nclusters);
247
248         for ( l = start ; l < stop ; l++ )
249         {
250            check_line_after[l] = 0;
251
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;
258
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
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            }
270
271            if ( check_line_before[l] != check_line_after[l] ) success = 0;
272         }
273
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      }
277
278      // instrumentation ( done by processor [0,0,0]
279
280      if ( (proc_id == 0) && INSTRUMENTATION_OK )
281      {
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;
295
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];
312            }
313         }
314
315         PRINTF(" - LOAD_START : min = %d / max = %d / med = %d / delta = %d\n",
316               min_load_start, max_load_start, (min_load_start+max_load_start)/2, 
317               max_load_start-min_load_start); 
318
319         PRINTF(" - LOAD_END   : min = %d / max = %d / med = %d / delta = %d\n",
320               min_load_ended, max_load_ended, (min_load_ended+max_load_ended)/2, 
321               max_load_ended-min_load_ended); 
322
323         PRINTF(" - TRSP_START : min = %d / max = %d / med = %d / delta = %d\n",
324               min_trsp_start, max_trsp_start, (min_trsp_start+max_trsp_start)/2, 
325               max_trsp_start-min_trsp_start); 
326
327         PRINTF(" - TRSP_END   : min = %d / max = %d / med = %d / delta = %d\n",
328               min_trsp_ended, max_trsp_ended, (min_trsp_ended+max_trsp_ended)/2, 
329               max_trsp_ended-min_trsp_ended); 
330
331         PRINTF(" - DISP_START : min = %d / max = %d / med = %d / delta = %d\n",
332               min_disp_start, max_disp_start, (min_disp_start+max_disp_start)/2, 
333               max_disp_start-min_disp_start); 
334
335         PRINTF(" - DISP_END   : min = %d / max = %d / med = %d / delta = %d\n",
336               min_disp_ended, max_disp_ended, (min_disp_ended+max_disp_ended)/2, 
337               max_disp_ended-min_disp_ended); 
338      }
339
340      image++;
341
342      _barrier_wait( 3 );
343   } // end while image     
344
345
346   _exit();
347
348} // end main()
349
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.