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

Last change on this file since 669 was 669, checked in by alain, 9 years ago

Introduce support for the "shared" argument in the giet_tty_alloc() system call,
and replace the giet_shr_printf() system call by giet_tty_printf().

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