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

Last change on this file since 312 was 248, checked in by meunier, 12 years ago

Updates in the soft_filter application (bug corrections, formatting, and adaptation to the architecture generic_mmu)

File size: 12.2 KB
RevLine 
[244]1
[158]2#include "stdio.h"
[244]3#include "limits.h"
4#include "../giet_tsar/block_device.h"
[158]5
[244]6#define NL              512
7#define NP              512
8#define NB_IMAGES       1
9#define NB_CLUSTER_MAX  256
[158]10
[248]11#define PRINTF(...)      ({ if (proc_id == 0) { tty_printf(__VA_ARGS__); } })
[158]12
[248]13//#define DISPLAY_ONLY
14
[158]15///////////////////////////////////////////
16// tricks to read parameters from ldscript
17///////////////////////////////////////////
18
19struct plaf;
20
[244]21extern struct plouf seg_ioc_base;
[158]22extern struct plaf seg_heap_base;
23extern struct plaf NB_PROCS;
24extern struct plaf NB_CLUSTERS;
25
26/////////////
[244]27void main(){
28   unsigned int frame = 0;
29   unsigned int date  = 0;
[158]30
[244]31   unsigned int c; // cluster index for loops
32   unsigned int l; // line index for loops
33   unsigned int p; // pixel index for loops
[158]34
[244]35   unsigned int proc_id       = procid();                      // processor id
36   unsigned int nlocal_procs  = (unsigned int) &NB_PROCS;      // number of processors per cluster
37   unsigned int nclusters     = (unsigned int) &NB_CLUSTERS;   // number of clusters
38   unsigned int local_id      = proc_id % nlocal_procs;        // local processor id
39   unsigned int cluster_id    = proc_id / nlocal_procs;        // cluster id
40   unsigned int base          = (unsigned int) &seg_heap_base; // base address for shared buffers
41   unsigned int increment     = 0x80000000 / nclusters * 2;    // cluster increment
42   unsigned int nglobal_procs = nclusters * nlocal_procs;      // number of tasks
43   unsigned int npixels       = NP * NL;                       // number of pixel per frame
44   
45   unsigned int * ioc_address = (unsigned int *) &seg_ioc_base;
46   unsigned int block_size    = ioc_address[BLOCK_DEVICE_BLOCK_SIZE];
47   unsigned int nblocks       = npixels / block_size;   // number of blocks per frame
[158]48
[244]49   PRINTF("\n *** Entering main at cycle %d ***\n\n", proctime());
[158]50
[244]51   //  parameters checking
52   if ((nlocal_procs != 1) && (nlocal_procs != 2) && (nlocal_procs != 4)){
53      PRINTF("NB_PROCS must be 1, 2 or 4\n");
54      exit(1);
55   }
56   if ((nclusters != 1) && (nclusters != 2) && (nclusters != 4) && (nclusters != 8) &&
57         (nclusters != 16) && (nclusters != 32) && (nclusters != 64) && (nclusters != 128) &&
58         (nclusters != 256)){
59      PRINTF("NB_CLUSTERS must be a power of 1 between 1 and 256\n");
60      exit(1);
61   }
62   if (nglobal_procs > 1024){
63      PRINTF("NB_PROCS * NB_CLUSTERS cannot be larger than 1024\n");
64      exit(1);
65   }
66   if (proc_id >= nglobal_procs){
67      PRINTF("processor id %d larger than NB_CLUSTERS*NB_PROCS\n", proc_id);
68      exit(1);
69   }
[158]70
[244]71   // Arrays of pointers on the shared, distributed buffers containing the frames
72   // These arrays are indexed by the cluster index (sized for the worst case : 256 clusters)
73   unsigned char * A[NB_CLUSTER_MAX];
74   unsigned char * B[NB_CLUSTER_MAX];
[158]75
[244]76   // Arrays of pointers on the instrumentation arrays
77   // These arrays are indexed by the cluster index (sized for the worst case : 256 clusters)
78   // each pointer points on the base adress of an array of NPROCS unsigned int
79   unsigned int * LOAD_START[NB_CLUSTER_MAX];
80   unsigned int * LOAD_END[NB_CLUSTER_MAX];
81   unsigned int * TRSP_START[NB_CLUSTER_MAX];
82   unsigned int * TRSP_END[NB_CLUSTER_MAX];
83   unsigned int * DISP_START[NB_CLUSTER_MAX];
84   unsigned int * DISP_END[NB_CLUSTER_MAX];
[158]85
[244]86   // shared buffers address definition
87   // from the seg_heap_base and increment depending on the cluster index
88   // These arrays of pointers are identical and replicated in the stack of each task
89   for (c = 0; c < nclusters; c++){
90      A[c]          = (unsigned char *) (base                                  + increment * c);
91      B[c]          = (unsigned char *) (base +     npixels                    + increment * c);
92      LOAD_START[c] = (unsigned int *)  (base + 2 * npixels                    + increment * c);
93      LOAD_END[c]   = (unsigned int *)  (base + 2 * npixels +     nlocal_procs + increment * c);
94      TRSP_START[c] = (unsigned int *)  (base + 2 * npixels + 2 * nlocal_procs + increment * c);
95      TRSP_END[c]   = (unsigned int *)  (base + 2 * npixels + 3 * nlocal_procs + increment * c);
96      DISP_START[c] = (unsigned int *)  (base + 2 * npixels + 4 * nlocal_procs + increment * c);
97      DISP_END[c]   = (unsigned int *)  (base + 2 * npixels + 5 * nlocal_procs + increment * c);
98   }
[158]99
[244]100   PRINTF("NB_CLUSTERS     = %d\n", nclusters); 
101   PRINTF("NB_LOCAL_PROCS  = %d\n", nlocal_procs); 
102   PRINTF("NB_GLOBAL_PROCS = %d\n", nglobal_procs);
103   PRINTF("NB_PIXELS       = %d\n", npixels);
104   PRINTF("BLOCK_SIZE      = %d\n", block_size);
105   PRINTF("NB_BLOCKS       = %d\n\n", nblocks);
[158]106
107
[248]108   PRINTF("*** Starting barrier init at cycle %d ***\n", proctime());
[158]109
[244]110   //  barriers initialization
111   barrier_init(0, nglobal_procs);
112   barrier_init(1, nglobal_procs);
113   barrier_init(2, nglobal_procs);
[158]114
[248]115   PRINTF("*** Completing barrier init at cycle %d ***\n", proctime());
[171]116
[244]117   // Main loop (on frames)
118   while (frame < NB_IMAGES){
119      // pseudo parallel load from disk to A[c] buffer : nblocks/nclusters blocks
120      // only task running on processor with (local_id == 0) does it
[171]121
[244]122      if (local_id == 0){
123         int p;
[158]124
[244]125         date = proctime();
126         PRINTF("\n*** Starting load for frame %d at cycle %d\n", frame, date);
127         
128         for (p = 0; p < nlocal_procs; p++){
129            LOAD_START[cluster_id][p] = date;
130         }
131         if (ioc_read(frame * nblocks + nblocks * cluster_id / nclusters, A[cluster_id], nblocks / nclusters)){
[248]132            PRINTF("echec ioc_read\n");
[244]133            exit();
134         }
135         if (ioc_completed()){
[248]136            PRINTF("echec ioc_completed\n");
[244]137            exit();
138         }
[158]139
[244]140         date = proctime();
141         PRINTF("*** Completing load for frame %d at cycle %d\n", frame, date);
142         for (p = 0; p < nlocal_procs; p++){
143            LOAD_END[cluster_id][p] = date;
144         }
145      }
[158]146
[244]147      barrier_wait(0);
[158]148
[244]149      // parallel transpose from A to B buffers
150      // each processor makes the transposition for (NL/nglobal_procs) lines
151      // (p,l) are the (x,y) pixel coordinates in the source frame
[158]152
[248]153#ifndef DISPLAY_ONLY
[244]154      date = proctime();
155      PRINTF("\n*** Starting transpose for frame %d at cycle %d\n", frame, date);
156      TRSP_START[cluster_id][local_id] = date;
[158]157
[244]158      unsigned int nlt   = NL / nglobal_procs; // Nombre de ligne à traiter par processeur
159      unsigned int first = proc_id * nlt;      // Index de la premiÚre ligne à traiter pour le proc courant (celui qui exécute le code)
160      unsigned int last  = first + nlt;        // Index de la derniÚre ligne
161      unsigned int nlines_clusters = NL / nclusters; // Nombre de lignes à traiter par cluster
162      unsigned int npix_clusters   = NP / nclusters; // Nombre de pixels par ligne à traiter par cluster
[158]163
[244]164      for (l = first; l < last; l++){
165         PRINTF("    - processing line %d\n", l);
166         for (p = 0; p < NP; p++){
167            unsigned int source_index   = (l % nlines_clusters) * NP + p;
168            unsigned int dest_cluster   = p / npix_clusters;
169            unsigned int dest_index     = (p % npix_clusters) * NL + l;
170            B[dest_cluster][dest_index] = A[cluster_id][source_index];
171         }
172      }
[158]173
[244]174      date = proctime();
175      PRINTF("*** Completing transpose for frame %d at cycle %d\n", frame, date);
176      TRSP_END[cluster_id][local_id] = date;
177      barrier_wait(1);
[248]178#endif
[158]179
[244]180      // parallel display from B[c] to frame buffer
181      // each processor uses its private dma to display NL*NP/nglobal_procs pixels
[158]182
[244]183      date = proctime();
184      PRINTF("\n*** Starting display for frame %d at cycle %d\n", frame, date);
185      DISP_START[cluster_id][local_id] = date;
[158]186
[244]187      unsigned int npxt = npixels / nglobal_procs;   // number of pixels per proc
[158]188
[248]189#ifndef DISPLAY_ONLY
[244]190      if (fb_write(npxt * proc_id, B[cluster_id] + npxt * local_id, npxt)){
[248]191         PRINTF("[%d]: echec fb_sync_write\n", proc_id);
[244]192         exit();
193      }
[248]194#else
195      if (fb_write(npxt * proc_id, A[cluster_id] + npxt * local_id, npxt)){
196         PRINTF("[%d]: echec fb_sync_write\n", proc_id);
197         exit();
198      }
199#endif
[158]200
[244]201      if (fb_completed()){
[248]202         PRINTF("[%d]: echec fb_completed\n", proc_id);
[244]203         exit();
204      }
[158]205
[244]206      date = proctime();
207      PRINTF("*** Completing display for frame %d at cycle %d\n", frame, date);
208      DISP_END[cluster_id][local_id] = date;
[171]209
[244]210      barrier_wait(2);
[171]211
[244]212      // Instrumentation (done by processor 0 in cluster 0)
213      if (local_id == 0){ 
214         date = proctime();
215         PRINTF("\n*** Starting Instrumentation for frame %d at cycle %d\n\n", frame, date);
[171]216
[244]217         int cc, pp;
218         unsigned int min_load_start = INT_MAX;
219         unsigned int max_load_start = 0;
220         unsigned int min_load_ended = INT_MAX;
221         unsigned int max_load_ended = 0;
222         unsigned int min_trsp_start = INT_MAX;
223         unsigned int max_trsp_start = 0;
224         unsigned int min_trsp_ended = INT_MAX;
225         unsigned int max_trsp_ended = 0;
226         unsigned int min_disp_start = INT_MAX;
227         unsigned int max_disp_start = 0;
228         unsigned int min_disp_ended = INT_MAX;
229         unsigned int max_disp_ended = 0;
[171]230
[244]231         for (cc = 0; cc < nclusters; cc++){
232            for (pp = 0; pp < nlocal_procs; pp++){
233               if (LOAD_START[cc][pp] < min_load_start){
234                  min_load_start = LOAD_START[cc][pp];
235               }
236               if (LOAD_START[cc][pp] > max_load_start){
237                  max_load_start = LOAD_START[cc][pp];
238               }
239               if (LOAD_END[cc][pp] < min_load_ended){
240                  min_load_ended = LOAD_END[cc][pp];
241               }
242               if (LOAD_END[cc][pp] > max_load_ended){
243                  max_load_ended = LOAD_END[cc][pp];
244               }
[171]245
[244]246               if (TRSP_START[cc][pp] < min_trsp_start){
247                  min_trsp_start = TRSP_START[cc][pp];
248               }
249               if (TRSP_START[cc][pp] > max_trsp_start){
250                  max_trsp_start = TRSP_START[cc][pp];
251               }
252               if (TRSP_END[cc][pp] < min_trsp_ended){
253                  min_trsp_ended = TRSP_END[cc][pp];
254               }
255               if (TRSP_END[cc][pp] > max_trsp_ended){
256                  max_trsp_ended = TRSP_END[cc][pp];
257               }
258
259               if (DISP_START[cc][pp] < min_disp_start){
260                  min_disp_start = DISP_START[cc][pp];
261               }
262               if (DISP_START[cc][pp] > max_disp_start){
263                  max_disp_start = DISP_START[cc][pp];
264               }
265               if (DISP_END[cc][pp] < min_disp_ended){
266                  min_disp_ended = DISP_END[cc][pp];
267               }
268               if (DISP_END[cc][pp] > max_disp_ended){
269                  max_disp_ended = DISP_END[cc][pp];
270               }
[171]271            }
[244]272         }
[171]273
[244]274         PRINTF(" - LOAD_START : min = %d / max = %d / med = %d / delta = %d\n",
275               min_load_start, max_load_start, (min_load_start+max_load_start)/2, max_load_start-min_load_start); 
276         PRINTF(" - LOAD_END   : min = %d / max = %d / med = %d / delta = %d\n",
277               min_load_ended, max_load_ended, (min_load_ended+max_load_ended)/2, max_load_ended-min_load_ended); 
[171]278
[244]279         PRINTF(" - TRSP_START : min = %d / max = %d / med = %d / delta = %d\n",
280               min_trsp_start, max_trsp_start, (min_trsp_start+max_trsp_start)/2, max_trsp_start-min_trsp_start); 
281         PRINTF(" - TRSP_END   : min = %d / max = %d / med = %d / delta = %d\n",
282               min_trsp_ended, max_trsp_ended, (min_trsp_ended+max_trsp_ended)/2, max_trsp_ended-min_trsp_ended); 
[171]283
[244]284         PRINTF(" - DISP_START : min = %d / max = %d / med = %d / delta = %d\n",
285               min_disp_start, max_disp_start, (min_disp_start+max_disp_start)/2, max_disp_start-min_disp_start); 
286         PRINTF(" - DISP_END   : min = %d / max = %d / med = %d / delta = %d\n",
287               min_disp_ended, max_disp_ended, (min_disp_ended+max_disp_ended)/2, max_disp_ended-min_disp_ended); 
[171]288
[244]289         PRINTF(" - BARRIER TRSP/DISP = %d\n", min_disp_start - max_trsp_ended);
290      }
291      frame++;
[171]292
[244]293   } // end while frame     
294
295   PRINTF("*** End of main ***\n");
296
297   while(1);
[158]298} // end main()
299
[244]300// Local Variables:
301// tab-width: 3
302// c-basic-offset: 3
303// c-file-offsets:((innamespace . 0)(inline-open . 0))
304// indent-tabs-mode: nil
305// End:
306
307// vim: filetype=cpp:expandtab:shiftwidth=3:tabstop=3:softtabstop=3
308
309
310
Note: See TracBrowser for help on using the repository browser.