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

Last change on this file since 629 was 629, checked in by alain, 10 years ago
  • Updatre the gier_tsar to support the vci_iopic component in the tsar_generic_leti plat-form.
  • Modify the soft_transpose_giet application to make optional the graphic display on frame buffer and to introduce a systematic auto-check
File size: 13.3 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#define PRINTF(...)      ({ if (lpid == 0) { _tty_printf(__VA_ARGS__); } })
12
13#define DISPLAY_OK
14
15// tricks to read parameters from ldscript
16extern struct plaf seg_ioc_base;
17extern struct plaf seg_heap_base;
18
19// global variables stored in seg_data (cluster 0)
20
21// instrumentation counters for each processor
22unsigned int LOAD_START[256][4];
23unsigned int LOAD_END  [256][4];
24unsigned int TRSP_START[256][4];
25unsigned int TRSP_END  [256][4];
26unsigned int DISP_START[256][4];
27unsigned int DISP_END  [256][4];
28
29// checksum variables
30unsigned check_line_before[NL];
31unsigned check_line_after[NL];
32
33/////////////
34void main()
35{
36    unsigned int image = 0;
37
38    unsigned int l;                                             // line index for loops
39    unsigned int p;                                             // pixel index for loops
40
41    unsigned int * ioc_address = (unsigned int *) &seg_ioc_base;
42    unsigned int block_size    = ioc_address[BLOCK_DEVICE_BLOCK_SIZE];
43
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 0 in cluster [%d,%d] 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 0 in cluster [%d,%d] 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         _ioc_read( ((image * nblocks) + ((nblocks * cluster_id) / nclusters)), 
112                    buf_in,
113                    (nblocks / nclusters),
114                    cluster_xy );
115
116         PRINTF("\n*** Proc 0 in cluster [%d,%d] starts load for image %d at cycle %d\n",
117                x, y, image, _proctime() );
118
119         _ioc_completed();
120
121         PRINTF("*** Proc 0 in cluster [%d,%d] 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      _barrier_wait(0);
128
129      // parallel transpose from buf_in to buf_out buffers
130      // each processor makes the transposition for (NL/ntasks) lines
131      // (p,l) are the pixel coordinates in the source image
132
133      PRINTF("\n*** proc 0 in cluster [%d,%d] starts transpose for image %d at cycle %d\n", 
134             x, y, image, _proctime());
135
136      TRSP_START[cluster_id][lpid] = _proctime();
137
138      unsigned int nlt   = NL / ntasks;                // number of lines per processor
139      unsigned int first = task_id * nlt;              // first line index
140      unsigned int last  = first + nlt;                // last line index
141      unsigned int nlines_clusters = NL / nclusters;   // number of lines per cluster
142      unsigned int npix_clusters   = NP / nclusters;   // number of pixels per cluster
143
144      unsigned int src_cluster;
145      unsigned int src_index;
146      unsigned int dst_cluster;
147      unsigned int dst_index;
148
149      unsigned int word;
150
151      for (l = first; l < last; l++)
152      {
153         PRINTF("    - processing line %d\n", l);
154
155         check_line_before[l] = 0;
156         
157         // in each iteration we read one word an write four bytes
158         for (p = 0 ; p < NP ; p = p+4)
159         {
160            // read one word, with extended address from local buffer
161            src_cluster = cluster_xy;
162            src_index   = (l % nlines_clusters) * NP + p;
163            word = _word_extended_read( src_cluster, 
164                                        (unsigned int)&buf_in[src_index] );
165
166            unsigned char byte0 = (unsigned char)( word      & 0x000000FF);
167            unsigned char byte1 = (unsigned char)((word>>8)  & 0x000000FF);
168            unsigned char byte2 = (unsigned char)((word>>16) & 0x000000FF);
169            unsigned char byte3 = (unsigned char)((word>>24) & 0x000000FF);
170
171            // compute checksum
172            check_line_before[l] = check_line_before[l] + byte0 + byte1 + byte2 + byte3;
173
174            // write four bytes with extended address to four remote buffers
175            dst_cluster = (((p / npix_clusters) / Y_SIZE) << Y_WIDTH) + 
176                           ((p / npix_clusters) % Y_SIZE);
177            dst_index   = (p % npix_clusters) * NL + l;
178            _byte_extended_write( dst_cluster, 
179                                  (unsigned int)&buf_out[dst_index], 
180                                  byte0 );
181
182            dst_cluster = ((((p+1) / npix_clusters) / Y_SIZE) << Y_WIDTH) + 
183                           (((p+1) / npix_clusters) % Y_SIZE);
184            dst_index   = ((p+1) % npix_clusters) * NL + l;
185            _byte_extended_write( dst_cluster, 
186                                  (unsigned int)&buf_out[dst_index], 
187                                  byte1 );
188
189            dst_cluster = ((((p+2) / npix_clusters) / Y_SIZE) << Y_WIDTH) + 
190                           (((p+2) / npix_clusters) % Y_SIZE);
191            dst_index   = ((p+2) % npix_clusters) * NL + l;
192            _byte_extended_write( dst_cluster, 
193                                  (unsigned int)&buf_out[dst_index], 
194                                  byte2 );
195
196            dst_cluster = ((((p+3) / npix_clusters) / Y_SIZE) << Y_WIDTH) + 
197                           (((p+3) / npix_clusters) % Y_SIZE);
198            dst_index   = ((p+3) % npix_clusters) * NL + l;
199            _byte_extended_write( dst_cluster, 
200                                  (unsigned int)&buf_out[dst_index], 
201                                  byte3 );
202         }
203      }
204
205      PRINTF("*** proc 0 in cluster [%d,%d] complete transpose for image %d at cycle %d\n", 
206             x, y, image, _proctime() );
207
208      TRSP_END[cluster_id][lpid] = _proctime();
209
210      _barrier_wait(1);
211
212      // optional parallel display from local buf_out to frame buffer
213
214#ifdef DISPLAY_OK
215
216      PRINTF("\n*** proc 0 in cluster [%d,%d] starts display for image %d at cycle %d\n", 
217             x, y, image, _proctime() );
218
219      DISP_START[cluster_id][lpid] = _proctime();
220
221      unsigned int npxt = npixels / ntasks;   // number of pixels per task
222      unsigned int buffer = (unsigned int)buf_out + npxt*lpid;
223
224      _fb_sync_write( npxt * task_id, buffer, npxt, cluster_xy );
225
226      PRINTF("*** Proc 0 in cluster [%d,%d] completes display for image %d at cycle %d\n",
227             x, y, image, _proctime() );
228
229      DISP_END[cluster_id][lpid] = _proctime();
230
231      _barrier_wait(2);
232
233#endif
234
235      // Instrumentation and checksum (done by processor 0 in cluster 0)
236      if (proc_id == 0)
237      { 
238         PRINTF("\n*** Proc [0,0,0] starts checks for image %d at cycle %d\n\n",
239                  image, _proctime() );
240
241         unsigned int success = 1;
242
243         for ( l = 0 ; l < NL ; l++ )
244         {
245            check_line_after[l] = 0;
246
247            for ( p = 0 ; p < NP ; p++ )
248            {
249               // read one byte in remote buffer
250               src_cluster = (((p / npix_clusters) / Y_SIZE) << Y_WIDTH) +
251                             ((p / npix_clusters) % Y_SIZE);
252               src_index   = (p % npix_clusters) * NL + l;
253
254               unsigned char byte = _byte_extended_read( src_cluster,
255                                                         (unsigned int)&buf_out[src_index] );
256
257               check_line_after[l] = check_line_after[l] + byte;
258            }
259
260            PRINTF(" - l = %d / before = %d / after = %d \n",
261                   l, check_line_before[l], check_line_after[l] );
262
263            if ( check_line_before[l] != check_line_after[l] ) success = 0;
264         }
265
266         if ( success ) PRINTF("\n*** proc [0,0,0] : CHECKSUM OK \n\n");
267         else           PRINTF("\n*** proc [0,0,0] : CHECKSUM KO \n\n");
268
269         int cc, pp;
270         unsigned int min_load_start = INT_MAX;
271         unsigned int max_load_start = 0;
272         unsigned int min_load_ended = INT_MAX;
273         unsigned int max_load_ended = 0;
274         unsigned int min_trsp_start = INT_MAX;
275         unsigned int max_trsp_start = 0;
276         unsigned int min_trsp_ended = INT_MAX;
277         unsigned int max_trsp_ended = 0;
278         unsigned int min_disp_start = INT_MAX;
279         unsigned int max_disp_start = 0;
280         unsigned int min_disp_ended = INT_MAX;
281         unsigned int max_disp_ended = 0;
282
283         for (cc = 0; cc < nclusters; cc++)
284         {
285            for (pp = 0; pp < NB_PROCS_MAX; pp++)
286            {
287               if (LOAD_START[cc][pp] < min_load_start)  min_load_start = LOAD_START[cc][pp];
288               if (LOAD_START[cc][pp] > max_load_start)  max_load_start = LOAD_START[cc][pp];
289               if (LOAD_END[cc][pp]   < min_load_ended)  min_load_ended = LOAD_END[cc][pp]; 
290               if (LOAD_END[cc][pp]   > max_load_ended)  max_load_ended = LOAD_END[cc][pp];
291               if (TRSP_START[cc][pp] < min_trsp_start)  min_trsp_start = TRSP_START[cc][pp];
292               if (TRSP_START[cc][pp] > max_trsp_start)  max_trsp_start = TRSP_START[cc][pp];
293               if (TRSP_END[cc][pp]   < min_trsp_ended)  min_trsp_ended = TRSP_END[cc][pp];
294               if (TRSP_END[cc][pp]   > max_trsp_ended)  max_trsp_ended = TRSP_END[cc][pp];
295               if (DISP_START[cc][pp] < min_disp_start)  min_disp_start = DISP_START[cc][pp];
296               if (DISP_START[cc][pp] > max_disp_start)  max_disp_start = DISP_START[cc][pp];
297               if (DISP_END[cc][pp]   < min_disp_ended)  min_disp_ended = DISP_END[cc][pp];
298               if (DISP_END[cc][pp]   > max_disp_ended)  max_disp_ended = DISP_END[cc][pp];
299            }
300         }
301
302         PRINTF(" - LOAD_START : min = %d / max = %d / med = %d / delta = %d\n",
303               min_load_start, max_load_start, (min_load_start+max_load_start)/2, 
304               max_load_start-min_load_start); 
305
306         PRINTF(" - LOAD_END   : min = %d / max = %d / med = %d / delta = %d\n",
307               min_load_ended, max_load_ended, (min_load_ended+max_load_ended)/2, 
308               max_load_ended-min_load_ended); 
309
310         PRINTF(" - TRSP_START : min = %d / max = %d / med = %d / delta = %d\n",
311               min_trsp_start, max_trsp_start, (min_trsp_start+max_trsp_start)/2, 
312               max_trsp_start-min_trsp_start); 
313
314         PRINTF(" - TRSP_END   : min = %d / max = %d / med = %d / delta = %d\n",
315               min_trsp_ended, max_trsp_ended, (min_trsp_ended+max_trsp_ended)/2, 
316               max_trsp_ended-min_trsp_ended); 
317
318         PRINTF(" - DISP_START : min = %d / max = %d / med = %d / delta = %d\n",
319               min_disp_start, max_disp_start, (min_disp_start+max_disp_start)/2, 
320               max_disp_start-min_disp_start); 
321
322         PRINTF(" - DISP_END   : min = %d / max = %d / med = %d / delta = %d\n",
323               min_disp_ended, max_disp_ended, (min_disp_ended+max_disp_ended)/2, 
324               max_disp_ended-min_disp_ended); 
325      }
326
327      image++;
328
329      _barrier_wait( 3 );
330   } // end while image     
331
332
333   _exit();
334
335} // end main()
336
337// Local Variables:
338// tab-width: 3
339// c-basic-offset: 3
340// c-file-offsets:((innamespace . 0)(inline-open . 0))
341// indent-tabs-mode: nil
342// End:
343
344// vim: filetype=cpp:expandtab:shiftwidth=3:tabstop=3:softtabstop=3
345
346
347
Note: See TracBrowser for help on using the repository browser.