source: soft/giet_vm/applications/convol/main.c @ 481

Last change on this file since 481 was 444, checked in by alain, 10 years ago

Introducing application "display"

File size: 26.5 KB
RevLine 
[334]1////////////////////////////////////////////////////////////////////////////////////////////
2// File   : main.c   (for convol application)
3// Date   : june 2014
4// author : Alain Greiner
[444]5////////////////////////////////////////////////////////////////////////////////////////////
6// This multi-threaded application application implements a 2D convolution product. 
7// The convolution kernel is [201]*[35] pixels, but it can be factored in two
8// independant line and column convolution products.
9// It can run on a multi-processors, multi-clusters architecture, with one thread
10// per processor. It uses the he following hardware parameters, that must be defined
11// in the hard_config.h file:
12// - X_SIZE       : number of clusters in a row
13// - Y_SIZE       : number of clusters in a column
14// - NB_PROCS_MAX : number of processors per cluster
15// - FBUF_X_SIZE  : number of pixels per line in frame buffer
16// - FBUF_Y_SIZE  : number of lines  in frame buffer
17//
18// The (1024 * 1024) pixels image is read from a file (2 bytes per pixel).
[334]19//
[444]20// - The number of clusters containing processors must be a power of 2.
21// - The number of processors per cluster must be a power of 2.
[334]22////////////////////////////////////////////////////////////////////////////////////////////
23
24#include "hard_config.h"
25#include "stdio.h"
[353]26#include "stdlib.h"
[334]27#include "barrier.h"
[384]28#include "malloc.h"
[334]29
[372]30#define USE_SBT_BARRIER            1
[353]31#define VERBOSE                    0
32#define SUPER_VERBOSE              0
[334]33
[353]34#define INITIAL_DISPLAY_ENABLE     0
[334]35#define FINAL_DISPLAY_ENABLE       1
36
[353]37#define NB_CLUSTERS                (X_SIZE * Y_SIZE)
[334]38#define PIXEL_SIZE                 2
39#define NL                         1024
40#define NP                         1024
41#define NB_PIXELS                  (NP * NL)
42#define FRAME_SIZE                 (NB_PIXELS * PIXEL_SIZE)
43
44#define TA(c,l,p)  (A[c][((NP) * (l)) + (p)])
45#define TB(c,p,l)  (B[c][((NL) * (p)) + (l)])
46#define TC(c,l,p)  (C[c][((NP) * (l)) + (p)])
47#define TD(c,l,p)  (D[c][((NP) * (l)) + (p)])
48#define TZ(c,l,p)  (Z[c][((NP) * (l)) + (p)])
49
50#define max(x,y) ((x) > (y) ? (x) : (y))
51#define min(x,y) ((x) < (y) ? (x) : (y))
52
[372]53// global instrumentation counters (cluster_id, lpid]
54
[353]55unsigned int START[NB_CLUSTERS][NB_PROCS_MAX];
56unsigned int H_BEG[NB_CLUSTERS][NB_PROCS_MAX];
57unsigned int H_END[NB_CLUSTERS][NB_PROCS_MAX];
58unsigned int V_BEG[NB_CLUSTERS][NB_PROCS_MAX];
59unsigned int V_END[NB_CLUSTERS][NB_PROCS_MAX];
60unsigned int D_BEG[NB_CLUSTERS][NB_PROCS_MAX];
61unsigned int D_END[NB_CLUSTERS][NB_PROCS_MAX];
[334]62
[372]63// global synchronization barrier
[334]64
[372]65#if USE_SBT_BARRIER
66giet_sbt_barrier_t  barrier;
67#else
68giet_barrier_t      barrier;
69#endif
[334]70
[372]71volatile unsigned int barrier_init_ok    = 0;
72volatile unsigned int load_image_ok      = 0;
73volatile unsigned int instrumentation_ok = 0;
[334]74
[372]75// global pointers on distributed buffers in all clusters
76unsigned short * GA[NB_CLUSTERS];
77int *            GB[NB_CLUSTERS];
78int *            GC[NB_CLUSTERS];
79int *            GD[NB_CLUSTERS];
80unsigned char *  GZ[NB_CLUSTERS];
81
[334]82///////////////////////////////////////////
83__attribute__ ((constructor)) void main()
84///////////////////////////////////////////
85{
86    //////////////////////////////////
87    // convolution kernel parameters
88    // The content of this section is
89    // Philips proprietary information.
90    ///////////////////////////////////
91
92    int   vnorm  = 115;
93    int   vf[35] = { 1, 1, 2, 2, 2,
94                     2, 3, 3, 3, 4,
95                     4, 4, 4, 5, 5,
96                     5, 5, 5, 5, 5,
97                     5, 5, 4, 4, 4,
98                     4, 3, 3, 3, 2,
99                     2, 2, 2, 1, 1 };
100
101    int hrange = 100;
102    int hnorm  = 201;
103
104    unsigned int date = 0;
105
106    int c; // cluster index for loops
107    int l; // line index for loops
108    int p; // pixel index for loops
109    int z; // vertical filter index for loops
110
[432]111    // processor identifiers
112    unsigned int x;                                           // x coordinate
113    unsigned int y;                                           // y coordinate
114    unsigned int lpid;                                        // local proc/task id
115    giet_proc_xyp( &x, &y, &lpid );
116
[353]117    int          file        = 0;                             // file descriptor
[334]118    unsigned int nprocs      = NB_PROCS_MAX;                  // procs per cluster
[362]119    unsigned int nclusters   = NB_CLUSTERS;                   // number of clusters
[334]120    unsigned int cluster_id  = (x * Y_SIZE) + y;              // continuous cluster index
121    unsigned int task_id     = (cluster_id * nprocs) + lpid;  // continuous task index
122    unsigned int ntasks      = nclusters * nprocs;            // number of tasks
123    unsigned int frame_size  = FRAME_SIZE;                    // total size (bytes)
124    unsigned int nblocks     = frame_size / 512;              // number of blocks per frame
125
126    unsigned int lines_per_task     = NL / ntasks;            // lines per task
127    unsigned int lines_per_cluster  = NL / nclusters;         // lines per cluster
128    unsigned int pixels_per_task    = NP / ntasks;            // columns per task
129    unsigned int pixels_per_cluster = NP / nclusters;         // columns per cluster
130
131    int first, last;
132
133    date = giet_proctime();
134    START[cluster_id][lpid] = date;
135
[353]136#if VERBOSE
137giet_shr_printf( "\n[CONVOL] task[%d,%d,%d] starts at cycle %d\n", x,y,lpid, date );
138#endif
139
[334]140     // parameters checking
141   
[444]142    if ( (NP != FBUF_X_SIZE) || (NL != FBUF_Y_SIZE) )
143    {
144        giet_exit("[TRANSPOSE ERROR] Frame buffer size does not fit image size");
145    }
[334]146    if ((nprocs != 1) && (nprocs != 2) && (nprocs != 4))
147        giet_exit( "[CONVOL ERROR] NB_PROCS_MAX must be 1, 2 or 4\n");
148
[402]149    if ((X_SIZE!=1) && (X_SIZE!=2) && (X_SIZE!=4) && (X_SIZE!=8) && (X_SIZE!=16))
150        giet_exit( "[CONVOL ERROR] X_SIZE must be 1, 2, 4, 8, 16\n");
[334]151       
[402]152    if ((Y_SIZE!=1) && (Y_SIZE!=2) && (Y_SIZE!=4) && (Y_SIZE!=8) && (Y_SIZE!=16))
153        giet_exit( "[CONVOL ERROR] Y_SIZE must be 1, 2, 4, 8, 16\n");
[334]154
155    if ( NL % nclusters != 0 )
156        giet_exit( "[CONVOL ERROR] NB_CLUSTERS must be a divider of NL");
157
158    if ( NP % nclusters != 0 )
159        giet_exit( "[CONVOL ERROR] NB_CLUSTERS must be a divider of NP");
160
[372]161   
[334]162    ///////////////////////////////////////////////////////////////////
[372]163    // task[0][0][0] makes barrier initialisation
[334]164    ///////////////////////////////////////////////////////////////////
[372]165   
[432]166    if ( (x==0) && (y==0) && (lpid==0) )
[372]167    {
[444]168        // parameters checking
169        if ( (NP != FBUF_X_SIZE) || (NL != FBUF_Y_SIZE) )
170            giet_exit("[TRANSPOSE ERROR] Frame buffer size does not fit image size");
171       
172        if ((nprocs != 1) && (nprocs != 2) && (nprocs != 4))
173            giet_exit( "[CONVOL ERROR] NB_PROCS_MAX must be 1, 2 or 4\n");
174
175        if ((X_SIZE!=1) && (X_SIZE!=2) && (X_SIZE!=4) && (X_SIZE!=8) && (X_SIZE!=16))
176            giet_exit( "[CONVOL ERROR] X_SIZE must be 1, 2, 4, 8, 16\n");
177       
178        if ((Y_SIZE!=1) && (Y_SIZE!=2) && (Y_SIZE!=4) && (Y_SIZE!=8) && (Y_SIZE!=16))
179            giet_exit( "[CONVOL ERROR] Y_SIZE must be 1, 2, 4, 8, 16\n");
180
181        if ( NL % nclusters != 0 )
182            giet_exit( "[CONVOL ERROR] NB_CLUSTERS must be a divider of NL");
183
184        if ( NP % nclusters != 0 )
185            giet_exit( "[CONVOL ERROR] NB_CLUSTERS must be a divider of NP");
186
187   
[372]188        giet_shr_printf("\n[CONVOL] task[0,0,0] starts barrier init at cycle %d\n" 
189                        "- NB_CLUSTERS     = %d\n"
[444]190                        "- NB_PROCS_MAX    = %d\n" 
[372]191                        "- NB_TASKS        = %d\n" 
192                        "- NB_BLOCKS       = %x\n",
[444]193                        giet_proctime(), nclusters, nprocs, ntasks, nblocks );
[372]194#if USE_SBT_BARRIER
195        sbt_barrier_init( &barrier, ntasks );
196#else
197        barrier_init( &barrier, ntasks );
198#endif
[334]199
[372]200        giet_shr_printf( "\n[CONVOL] task[0,0,0] completes barrier init at cycle %d\n",
201                         giet_proctime() );
202
203        barrier_init_ok = 1;
204    }
205    else 
206    {
207        while ( barrier_init_ok == 0 );
208    }
209
210    ///////////////////////////////////////////////////////////////////
211    // All task[x][y][0] allocate the global buffers in cluster(x,y)
212    // These buffers mut be sector-aligned.
213    ///////////////////////////////////////////////////////////////////
214    if ( lpid == 0 )
215    {
216
217#if VERBOSE
218giet_shr_printf( "\n[CONVOL] task[%d,%d,%d] enters malloc at cycle %d\n", x,y,lpid, date );
219#endif
220
[384]221        GA[cluster_id] = remote_malloc( (FRAME_SIZE/nclusters)   , x , y );
222        GB[cluster_id] = remote_malloc( (FRAME_SIZE/nclusters)*2 , x , y );
223        GC[cluster_id] = remote_malloc( (FRAME_SIZE/nclusters)*2 , x , y );
224        GD[cluster_id] = remote_malloc( (FRAME_SIZE/nclusters)*2 , x , y );
225        GZ[cluster_id] = remote_malloc( (FRAME_SIZE/nclusters)/2 , x , y );
[372]226       
227#if VERBOSE
228giet_shr_printf( "\n[CONVOL]  Shared Buffer Virtual Addresses in cluster(%d,%d)\n"
229                 "### GA = %x\n"
230                 "### GB = %x\n"               
231                 "### GC = %x\n"               
232                 "### GD = %x\n"               
233                 "### GZ = %x\n",
234                 x, y,
235                 GA[cluster_id],
236                 GB[cluster_id],
237                 GC[cluster_id],
238                 GD[cluster_id],
239                 GZ[cluster_id] );
240#endif
241    }
242
[377]243    ///////////////////////////////
244    #if USE_SBT_BARRIER
245    sbt_barrier_wait( &barrier );
246    #else
247    barrier_wait( &barrier );
248    #endif
[372]249
250    ///////////////////////////////////////////////////////////////////
251    // All tasks initialise in their private stack a copy of the
252    // arrays of pointers on the shared, distributed buffers.
253    ///////////////////////////////////////////////////////////////////
254
[353]255    unsigned short * A[NB_CLUSTERS];
256    int *            B[NB_CLUSTERS];
257    int *            C[NB_CLUSTERS];
258    int *            D[NB_CLUSTERS];
259    unsigned char *  Z[NB_CLUSTERS];
[334]260
261    for (c = 0; c < nclusters; c++)
262    {
[372]263        A[c] = GA[c];
264        B[c] = GB[c];
265        C[c] = GC[c];
266        D[c] = GD[c];
267        Z[c] = GZ[c];
[334]268    }
269
270    ///////////////////////////////////////////////////////////////////////////
[372]271    // task[0,0,0] open the file containing image, and load it from disk
272    // to all A[c] buffers (nblocks / nclusters loaded in each cluster).
[334]273    // Other tasks are waiting on the init_ok condition.
274    //////////////////////////////////////////////////////////////////////////
[432]275    if ( (x==0) && (y==0) && (lpid==0) )
[334]276    {
277        // open file
278        file = giet_fat_open("misc/philips_image.raw", 0 );
279        if ( file < 0 ) giet_exit( "[CONVOL ERROR] task[0,0,0] cannot open"
280                                   " file misc/philips_image.raw" );
281 
282        giet_shr_printf( "\n[CONVOL] task[0,0,0] open file misc/philips_image.raw"
283                         " at cycle %d\n", giet_proctime() );
284
[353]285        for ( c = 0 ; c < NB_CLUSTERS ; c++ )
[334]286        {
[353]287            giet_shr_printf( "\n[CONVOL] task[0,0,0] starts load "
288                             "for cluster %d at cycle %d\n", c, giet_proctime() );
289
[334]290            giet_fat_read( file,
291                           A[c],
292                           nblocks/nclusters,
293                           (nblocks/nclusters)*c );
294
[353]295            giet_shr_printf( "\n[CONVOL] task[0,0,0] completes load "
296                             "for cluster %d at cycle %d\n", c, giet_proctime() );
[334]297        }
[372]298        load_image_ok = 1;
[334]299    }
300    else
301    {
[372]302        while ( load_image_ok == 0 );
[334]303    }
304
305    /////////////////////////////////////////////////////////////////////////////
306    // Optionnal parallel display of the initial image stored in A[c] buffers.
307    // Eah task displays (NL/ntasks) lines. (one byte per pixel).
308    /////////////////////////////////////////////////////////////////////////////
309
310    if ( INITIAL_DISPLAY_ENABLE )
311    {
312
[353]313#if VERBOSE
314giet_shr_printf( "\n[CONVOL] task[%d,%d,%d] starts initial display"
315                 " at cycle %d\n",
316                 x, y, lpid, giet_proctime() );
317#endif
318
[334]319        unsigned int line;
320        unsigned int offset = lines_per_task * lpid;
321
322        for ( l = 0 ; l < lines_per_task ; l++ )
323        {
324            line = offset + l;
325
326            for ( p = 0 ; p < NP ; p++ )
327            {
328                TZ(cluster_id, line, p) = (unsigned char)(TA(cluster_id, line, p) >> 8);
329            }
330
[444]331            giet_fbf_sync_write( NP*(l + (task_id * lines_per_task) ), 
332                                 &TZ(cluster_id, line, 0), 
333                                 NP);
[334]334        }
335
[353]336#if VERBOSE
337giet_shr_printf( "\n[CONVOL] task[%d,%d,%d] completes initial display"
338                 " at cycle %d\n",
339                 x, y, lpid, giet_proctime() );
340#endif
[334]341
[377]342        ////////////////////////////
343        #if USE_SBT_BARRIER
[372]344        sbt_barrier_wait( &barrier );
[377]345        #else
[372]346        barrier_wait( &barrier );
[377]347        #endif
[334]348
349    }
350
351    ////////////////////////////////////////////////////////
352    // parallel horizontal filter :
353    // B <= transpose(FH(A))
354    // D <= A - FH(A)
355    // Each task computes (NL/ntasks) lines
356    // The image must be extended :
357    // if (z<0)    TA(cluster_id,l,z) == TA(cluster_id,l,0)
358    // if (z>NP-1) TA(cluster_id,l,z) == TA(cluster_id,l,NP-1)
359    ////////////////////////////////////////////////////////
360
361    date  = giet_proctime();
362    H_BEG[cluster_id][lpid] = date;
363
[353]364#if VERBOSE
365giet_shr_printf( "\n[CONVOL] task[%d,%d,%d] starts horizontal filter"
366                 " at cycle %d\n",
367                 x, y, lpid, date );
368#else
[432]369if ( (x==0) && (y==0) && (lpid==0) ) 
370giet_shr_printf( "\n[CONVOL] task[0,0,0] starts horizontal filter"
371                 " at cycle %d\n", date );
[353]372#endif
373
[334]374    // l = absolute line index / p = absolute pixel index 
375    // first & last define which lines are handled by a given task
376
377    first = task_id * lines_per_task;
378    last  = first + lines_per_task;
379
380    for (l = first; l < last; l++)
381    {
382        // src_c and src_l are the cluster index and the line index for A & D
383        int src_c = l / lines_per_cluster;
384        int src_l = l % lines_per_cluster;
385
386        // We use the specific values of the horizontal ep-filter for optimisation:
387        // sum(p) = sum(p-1) + TA[p+hrange] - TA[p-hrange-1]
388        // To minimize the number of tests, the loop on pixels is split in three domains
389
390        int sum_p = (hrange + 2) * TA(src_c, src_l, 0);
391        for (z = 1; z < hrange; z++)
392        {
393            sum_p = sum_p + TA(src_c, src_l, z);
394        }
395
396        // first domain : from 0 to hrange
397        for (p = 0; p < hrange + 1; p++)
398        {
399            // dst_c and dst_p are the cluster index and the pixel index for B
400            int dst_c = p / pixels_per_cluster;
401            int dst_p = p % pixels_per_cluster;
402            sum_p = sum_p + (int) TA(src_c, src_l, p + hrange) - (int) TA(src_c, src_l, 0);
403            TB(dst_c, dst_p, l) = sum_p / hnorm;
404            TD(src_c, src_l, p) = (int) TA(src_c, src_l, p) - sum_p / hnorm;
405        }
406        // second domain : from (hrange+1) to (NP-hrange-1)
407        for (p = hrange + 1; p < NP - hrange; p++)
408        {
409            // dst_c and dst_p are the cluster index and the pixel index for B
410            int dst_c = p / pixels_per_cluster;
411            int dst_p = p % pixels_per_cluster;
412            sum_p = sum_p + (int) TA(src_c, src_l, p + hrange) 
413                          - (int) TA(src_c, src_l, p - hrange - 1);
414            TB(dst_c, dst_p, l) = sum_p / hnorm;
415            TD(src_c, src_l, p) = (int) TA(src_c, src_l, p) - sum_p / hnorm;
416        }
417        // third domain : from (NP-hrange) to (NP-1)
418        for (p = NP - hrange; p < NP; p++)
419        {
420            // dst_c and dst_p are the cluster index and the pixel index for B
421            int dst_c = p / pixels_per_cluster;
422            int dst_p = p % pixels_per_cluster;
423            sum_p = sum_p + (int) TA(src_c, src_l, NP - 1) 
424                          - (int) TA(src_c, src_l, p - hrange - 1);
425            TB(dst_c, dst_p, l) = sum_p / hnorm;
426            TD(src_c, src_l, p) = (int) TA(src_c, src_l, p) - sum_p / hnorm;
427        }
428
[353]429#if SUPER_VERBOSE
430giet_shr_printf(" - line %d computed at cycle %d\n", l, giet_proctime() );
431#endif   
432
[334]433    }
434
435    date  = giet_proctime();
436    H_END[cluster_id][lpid] = date;
437
[353]438#if VERBOSE
439giet_shr_printf( "\n[CONVOL] task[%d,%d,%d] completes horizontal filter"
440                 " at cycle %d\n",
441                 x, y, lpid, date );
442#else
[432]443if ( (x==0) && (y==0) && (lpid==0) ) 
444giet_shr_printf( "\n[CONVOL] task[0,0,0] completes horizontal filter"
445                 " at cycle %d\n", date );
[353]446#endif
447
[377]448    /////////////////////////////
449    #if USE_SBT_BARRIER
450    sbt_barrier_wait( &barrier );
451    #else
452    barrier_wait( &barrier );
453    #endif
[334]454
[372]455
[353]456    ///////////////////////////////////////////////////////////////
[334]457    // parallel vertical filter :
458    // C <= transpose(FV(B))
459    // Each task computes (NP/ntasks) columns
460    // The image must be extended :
461    // if (l<0)    TB(cluster_id,p,l) == TB(cluster_id,p,0)
462    // if (l>NL-1)   TB(cluster_id,p,l) == TB(cluster_id,p,NL-1)
[353]463    ///////////////////////////////////////////////////////////////
[334]464
465    date  = giet_proctime();
466    V_BEG[cluster_id][lpid] = date;
467
[353]468#if VERBOSE
469giet_shr_printf( "\n[CONVOL] task[%d,%d,%d] starts vertical filter"
470                 " at cycle %d\n",
471                 x, y, lpid, date );
472#else
[432]473if ( (x==0) && (y==0) && (lpid==0) ) 
474giet_shr_printf( "\n[CONVOL] task[0,0,0] starts vertical filter"
475                 " at cycle %d\n", date );
[353]476#endif
477
[334]478    // l = absolute line index / p = absolute pixel index
479    // first & last define which pixels are handled by a given task
480
481    first = task_id * pixels_per_task;
482    last  = first + pixels_per_task;
483
484    for (p = first; p < last; p++)
485    {
486        // src_c and src_p are the cluster index and the pixel index for B
487        int src_c = p / pixels_per_cluster;
488        int src_p = p % pixels_per_cluster;
489
490        int sum_l;
491
492        // We use the specific values of the vertical ep-filter
493        // To minimize the number of tests, the NL lines are split in three domains
494
495        // first domain : explicit computation for the first 18 values
496        for (l = 0; l < 18; l++)
497        {
498            // dst_c and dst_l are the cluster index and the line index for C
499            int dst_c = l / lines_per_cluster;
500            int dst_l = l % lines_per_cluster;
501
502            for (z = 0, sum_l = 0; z < 35; z++)
503            {
504                sum_l = sum_l + vf[z] * TB(src_c, src_p, max(l - 17 + z,0) );
505            }
506            TC(dst_c, dst_l, p) = sum_l / vnorm;
507        }
508        // second domain
509        for (l = 18; l < NL - 17; l++)
510        {
511            // dst_c and dst_l are the cluster index and the line index for C
512            int dst_c = l / lines_per_cluster;
513            int dst_l = l % lines_per_cluster;
514
515            sum_l = sum_l + TB(src_c, src_p, l + 4)
516                  + TB(src_c, src_p, l + 8)
517                  + TB(src_c, src_p, l + 11)
518                  + TB(src_c, src_p, l + 15)
519                  + TB(src_c, src_p, l + 17)
520                  - TB(src_c, src_p, l - 5)
521                  - TB(src_c, src_p, l - 9)
522                  - TB(src_c, src_p, l - 12)
523                  - TB(src_c, src_p, l - 16)
524                  - TB(src_c, src_p, l - 18);
525
526            TC(dst_c, dst_l, p) = sum_l / vnorm;
527        }
528        // third domain
529        for (l = NL - 17; l < NL; l++)
530        {
531            // dst_c and dst_l are the cluster index and the line index for C
532            int dst_c = l / lines_per_cluster;
533            int dst_l = l % lines_per_cluster;
534
535            sum_l = sum_l + TB(src_c, src_p, min(l + 4, NL - 1))
536                  + TB(src_c, src_p, min(l + 8, NL - 1))
537                  + TB(src_c, src_p, min(l + 11, NL - 1))
538                  + TB(src_c, src_p, min(l + 15, NL - 1))
539                  + TB(src_c, src_p, min(l + 17, NL - 1))
540                  - TB(src_c, src_p, l - 5)
541                  - TB(src_c, src_p, l - 9)
542                  - TB(src_c, src_p, l - 12)
543                  - TB(src_c, src_p, l - 16)
544                  - TB(src_c, src_p, l - 18);
545
546            TC(dst_c, dst_l, p) = sum_l / vnorm;
547        }
548
[353]549#if SUPER_VERBOSE
550giet_shr_printf(" - column %d computed at cycle %d\n", p, giet_proctime());
551#endif
552
[334]553    }
554
555    date  = giet_proctime();
556    V_END[cluster_id][lpid] = date;
557
[353]558#if VERBOSE
559giet_shr_printf( "\n[CONVOL] task[%d,%d,%d] completes vertical filter"
560                 " at cycle %d\n",
561                 x, y, lpid, date );
562#else
[432]563if ( (x==0) && (y==0) && (lpid==0) ) 
564giet_shr_printf( "\n[CONVOL] task[0,0,0] completes vertical filter"
565                 " at cycle %d\n", date );
[353]566#endif
567
[377]568    ////////////////////////////
569    #if USE_SBT_BARRIER
570    sbt_barrier_wait( &barrier );
571    #else
572    barrier_wait( &barrier );
573    #endif
[334]574
575    ////////////////////////////////////////////////////////////////
576    // Optional parallel display of the final image Z <= D + C
577    // Eah task displays (NL/ntasks) lines. (one byte per pixel).
578    ////////////////////////////////////////////////////////////////
579
580    if ( FINAL_DISPLAY_ENABLE )
581    {
582        date  = giet_proctime();
583        D_BEG[cluster_id][lpid] = date;
584
[353]585#if VERBOSE
586giet_shr_printf( "\n[CONVOL] task[%d,%d,%d] starts final display"
587                 " at cycle %d\n",
588                 x, y, lpid, date);
589#else
[432]590if ( (x==0) && (y==0) && (lpid==0) ) 
591giet_shr_printf( "\n[CONVOL] task[0,0,0] starts final display"
592                 " at cycle %d\n", date );
[353]593#endif
594
[334]595        unsigned int line;
596        unsigned int offset = lines_per_task * lpid;
597
598        for ( l = 0 ; l < lines_per_task ; l++ )
599        {
600            line = offset + l;
601
602            for ( p = 0 ; p < NP ; p++ )
603            {
604                TZ(cluster_id, line, p) = 
605                   (unsigned char)( (TD(cluster_id, line, p) + 
606                                     TC(cluster_id, line, p) ) >> 8 );
607            }
608
[444]609            giet_fbf_sync_write( NP*(l + (task_id * lines_per_task) ), 
610                                 &TZ(cluster_id, line, 0), 
611                                 NP);
[334]612        }
613
614        date  = giet_proctime();
615        D_END[cluster_id][lpid] = date;
[353]616
617#if VERBOSE
618giet_shr_printf( "\n[CONVOL] task[%d,%d,%d] completes final display"
619                 " at cycle %d\n",
620                 x, y, lpid, date);
621#else
[432]622if ( (x==0) && (y==0) && (lpid==0) ) 
623giet_shr_printf( "\n[CONVOL] task[0,0,0] completes final display"
624                 " at cycle %d\n", date );
[353]625#endif
[334]626     
[377]627    //////////////////////////////
628    #if USE_SBT_BARRIER
629    sbt_barrier_wait( &barrier );
630    #else
631    barrier_wait( &barrier );
632    #endif
[372]633
[334]634    }
635
636    /////////////////////////////////////////////////////////
637    // Task[0,0,0] makes the instrumentation
638    /////////////////////////////////////////////////////////
639
[432]640    if ( (x==0) && (y==0) && (lpid==0) )
[334]641    {
642        date  = giet_proctime();
[353]643        giet_shr_printf("\n[CONVOL] task[0,0,0] starts instrumentation"
644                        " at cycle %d\n\n", date );
[334]645
646        int cc, pp;
647
648        unsigned int min_start = 0xFFFFFFFF;
649        unsigned int max_start = 0;
650
651        unsigned int min_h_beg = 0xFFFFFFFF;
652        unsigned int max_h_beg = 0;
653
654        unsigned int min_h_end = 0xFFFFFFFF;
655        unsigned int max_h_end = 0;
656
657        unsigned int min_v_beg = 0xFFFFFFFF;
658        unsigned int max_v_beg = 0;
659
660        unsigned int min_v_end = 0xFFFFFFFF;
661        unsigned int max_v_end = 0;
662
663        unsigned int min_d_beg = 0xFFFFFFFF;
664        unsigned int max_d_beg = 0;
665
666        unsigned int min_d_end = 0xFFFFFFFF;
667        unsigned int max_d_end = 0;
668
669        for (cc = 0; cc < nclusters; cc++)
670        {
671            for (pp = 0; pp < nprocs; pp++ )
672            {
673                if (START[cc][pp] < min_start) min_start = START[cc][pp];
674                if (START[cc][pp] > max_start) max_start = START[cc][pp];
675
676                if (H_BEG[cc][pp] < min_h_beg) min_h_beg = H_BEG[cc][pp];
677                if (H_BEG[cc][pp] > max_h_beg) max_h_beg = H_BEG[cc][pp];
678
679                if (H_END[cc][pp] < min_h_end) min_h_end = H_END[cc][pp];
680                if (H_END[cc][pp] > max_h_end) max_h_end = H_END[cc][pp];
681
682                if (V_BEG[cc][pp] < min_v_beg) min_v_beg = V_BEG[cc][pp];
683                if (V_BEG[cc][pp] > max_v_beg) max_v_beg = V_BEG[cc][pp];
684
685                if (V_END[cc][pp] < min_v_end) min_v_end = V_END[cc][pp];
686                if (V_END[cc][pp] > max_v_end) max_v_end = V_END[cc][pp];
687
688                if (D_BEG[cc][pp] < min_d_beg) min_d_beg = D_BEG[cc][pp];
689                if (D_BEG[cc][pp] > max_d_beg) max_d_beg = D_BEG[cc][pp];
690
691                if (D_END[cc][pp] < min_d_end) min_d_end = D_END[cc][pp];
692                if (D_END[cc][pp] > max_d_end) max_d_end = D_END[cc][pp];
693            }
694        }
695
696        giet_shr_printf(" - START : min = %d / max = %d / med = %d / delta = %d\n",
697               min_start, max_start, (min_start+max_start)/2, max_start-min_start);
698
699        giet_shr_printf(" - H_BEG : min = %d / max = %d / med = %d / delta = %d\n",
700               min_h_beg, max_h_beg, (min_h_beg+max_h_beg)/2, max_h_beg-min_h_beg);
701
[353]702        giet_shr_printf(" - H_END : min = %d / max = %d / med = %d / delta = %d\n",
[334]703               min_h_end, max_h_end, (min_h_end+max_h_end)/2, max_h_end-min_h_end);
704
705        giet_shr_printf(" - V_BEG : min = %d / max = %d / med = %d / delta = %d\n",
706               min_v_beg, max_v_beg, (min_v_beg+max_v_beg)/2, max_v_beg-min_v_beg);
707
[353]708        giet_shr_printf(" - V_END : min = %d / max = %d / med = %d / delta = %d\n",
[334]709               min_v_end, max_v_end, (min_v_end+max_v_end)/2, max_v_end-min_v_end);
710
711        giet_shr_printf(" - D_BEG : min = %d / max = %d / med = %d / delta = %d\n",
712               min_d_beg, max_d_beg, (min_d_beg+max_d_beg)/2, max_d_beg-min_d_beg);
713
[353]714        giet_shr_printf(" - D_END : min = %d / max = %d / med = %d / delta = %d\n",
[334]715               min_d_end, max_d_end, (min_d_end+max_d_end)/2, max_d_end-min_d_end);
716
717        giet_shr_printf( "\n General Scenario (Kcycles for each step)\n" );
[353]718        giet_shr_printf( " - BOOT OS           = %d\n", (min_start            )/1000 );
719        giet_shr_printf( " - LOAD IMAGE        = %d\n", (min_h_beg - min_start)/1000 );
720        giet_shr_printf( " - H_FILTER          = %d\n", (max_h_end - min_h_beg)/1000 );
721        giet_shr_printf( " - BARRIER HORI/VERT = %d\n", (min_v_beg - max_h_end)/1000 );
722        giet_shr_printf( " - V_FILTER          = %d\n", (max_v_end - min_v_beg)/1000 );
723        giet_shr_printf( " - BARRIER VERT/DISP = %d\n", (min_d_beg - max_v_end)/1000 );
724        giet_shr_printf( " - DISPLAY           = %d\n", (max_d_end - min_d_beg)/1000 );
[334]725
[372]726        instrumentation_ok = 1;
[334]727    }
728    else
729    {
[372]730        while ( instrumentation_ok == 0 );
[334]731    }
732
733    giet_exit( "completed");
734
735} // end main()
736
737// Local Variables:
738// tab-width: 3
739// c-basic-offset: 3
740// c-file-offsets:((innamespace . 0)(inline-open . 0))
741// indent-tabs-mode: nil
742// End:
743
744// vim: filetype=cpp:expandtab:shiftwidth=3:tabstop=3:softtabstop=3
745
746
Note: See TracBrowser for help on using the repository browser.