source: trunk/softs/soft_filter_giet/main.c @ 162

Last change on this file since 162 was 162, checked in by alain, 13 years ago

fixing a bug in display...

File size: 13.2 KB
Line 
1#include "stdio.h"
2
3////////////////////////////////////
4// Image parameters
5
6#define PIXEL_SIZE      2
7#define NL              1024
8#define NP              1024
9#define BLOCK_SIZE      1024
10
11#define PRINTF          if(lid==0) tty_printf
12
13#define TA(c,l,p)  (A[c][((NP)*(l))+(p)])
14#define TB(c,p,l)  (B[c][((NL)*(p))+(l)])
15#define TC(c,l,p)  (C[c][((NP)*(l))+(p)])
16#define TD(c,l,p)  (D[c][((NP)*(l))+(p)])
17#define TZ(c,l,p)  (Z[c][((NP)*(l))+(p)])
18
19#define max(x,y) ((x) > (y) ? (x) : (y))
20#define min(x,y) ((x) < (y) ? (x) : (y))
21
22///////////////////////////////////////////
23// tricks to read parameters from ldscript
24///////////////////////////////////////////
25
26struct plaf;
27
28extern struct plaf seg_heap_base;
29extern struct plaf NB_PROCS;
30extern struct plaf NB_CLUSTERS;
31
32/////////////
33void main()
34{
35
36//////////////////////////////////
37// convolution kernel parameters
38// The content of this section is
39// Philips proprietary information.
40///////////////////////////////////
41
42    int vnorm  = 115;
43    int vf[35];
44    vf[0]  = 1;
45    vf[1]  = 1;
46    vf[2]  = 2;
47    vf[3]  = 2;
48    vf[4]  = 2;
49    vf[5]  = 2;
50    vf[6]  = 3;
51    vf[7]  = 3;
52    vf[8]  = 3;
53    vf[9]  = 4;
54    vf[10] = 4;
55    vf[11] = 4;
56    vf[12] = 4;
57    vf[13] = 5;
58    vf[14] = 5;
59    vf[15] = 5;
60    vf[16] = 5;
61    vf[17] = 5;
62    vf[18] = 5;
63    vf[19] = 5;
64    vf[20] = 5;
65    vf[21] = 5;
66    vf[22] = 4;
67    vf[23] = 4;
68    vf[24] = 4;
69    vf[25] = 4;
70    vf[26] = 3;
71    vf[27] = 3;
72    vf[28] = 3;
73    vf[29] = 2;
74    vf[30] = 2;
75    vf[31] = 2;
76    vf[32] = 2;
77    vf[33] = 1;
78    vf[34] = 1;
79
80    int hrange = 100;
81    int hnorm  = 201;
82
83    unsigned int date      = 0;
84    unsigned int delta     = 0;
85
86    int c;                                                      // cluster index for loops
87    int l;                                                      // line index for loops
88    int p;                                                      // pixel index for loops
89    int x;                                                      // filter index for loops
90
91    int pid                 = procid();                         // processor id
92    int nprocs              = (int)&NB_PROCS;                   // number of processors per cluster
93    int nclusters           = (int)&NB_CLUSTERS;                // number of clusters
94    int lid                 = pid%nprocs;                       // local task id
95    int cid                 = pid/nprocs;                       // cluster task id
96    int base                = (unsigned int)&seg_heap_base;     // base address for shared buffers
97    int increment           = (0x80000000 / nclusters) * 2;     // cluster increment
98    int ntasks              = nclusters * nprocs;               // number of tasks
99    int nblocks             = (NP*NL*PIXEL_SIZE)/BLOCK_SIZE;    // number of blocks per image
100
101    int lines_per_task      = NL/ntasks;                        // number of lines per task
102    int lines_per_cluster   = NL/nclusters;                     // number of lines per cluster
103    int pixels_per_task     = NP/ntasks;                        // number of columns per task
104    int pixels_per_cluster  = NP/nclusters;                     // number of columns per cluster
105
106    int first, last;
107
108    PRINTF("\n*** Processor %d entering main at cycle %d ***\n\n", pid, proctime());
109   
110    //////////////////////////
111    //  parameters checking
112    if( (nprocs != 1) && (nprocs != 2) && (nprocs != 4) )
113    {
114        PRINTF("NB_PROCS must be 1, 2 or 4\n");
115        while(1);
116    }
117    if( (nclusters !=  4) && (nclusters !=  8) && (nclusters != 16) && 
118        (nclusters != 32) && (nclusters != 64) && (nclusters !=128) && (nclusters != 256) )
119    {
120        PRINTF("NB_CLUSTERS must be a power of 2 between 4 and 256\n");
121        while(1);
122    }
123    if( pid >= ntasks )
124    {
125        PRINTF("processor id %d larger than NB_CLUSTERS*NB_PROCS\n", pid);
126        while(1);
127    }
128    if ( NL % nclusters != 0 )
129    {
130        PRINTF("NB_CLUSTERS must be a divider of NL");
131        while(1);
132    }
133    if( NP % nclusters != 0 )
134    {
135        PRINTF("NB_CLUSTERS must be a divider of NP");
136        while(1);
137    }
138
139    //////////////////////////////////////////////////////////////////
140    // Arrays of pointers on the shared, distributed buffers 
141    // containing the images (sized for the worst case : 256 clusters)
142    unsigned short*     A[256];
143    int*                B[256];
144    int*                C[256];
145    int*                D[256];
146    unsigned char*      Z[256];
147   
148    // The shared, distributed buffers addresses are computed
149    // from the seg_heap_base value defined in the ldscript file
150    // and from the cluster increment = 4Gbytes/nclusters.
151    // These arrays of pointers are identical and
152    // replicated in the stack of each task
153    for( c=0 ; c<nclusters ; c++)
154    {
155        A[c] = (unsigned short*)(base                           + increment*c);
156        Z[c] = (unsigned char*) (base + 2*NP*NL/nclusters       + increment*c);
157        B[c] = (int*)           (base + 4*NP*NL/nclusters       + increment*c);
158        C[c] = (int*)           (base + 8*NP*NL/nclusters       + increment*c);
159        D[c] = (int*)           (base + 12*NP*NL/nclusters      + increment*c);
160    }
161
162    PRINTF("NCLUSTERS = %d\n", nclusters); 
163    PRINTF("NPROCS    = %d\n\n", nprocs); 
164
165    PRINTF("*** Starting barrier init at cycle %d ***\n", proctime());
166
167    //  barriers initialization
168    barrier_init(0, ntasks);
169    barrier_init(1, ntasks);
170    barrier_init(2, ntasks);
171
172    PRINTF("*** Completing barrier init at cycle %d ***\n", proctime());
173
174    ////////////////////////////////////////////////////////
175    // pseudo parallel load from disk to A[c] buffers
176    // only task running on processor with (lid==0) does it
177    // nblocks/nclusters are loaded in each cluster
178
179    if ( lid == 0 )
180    {
181        delta = proctime() - date;
182        date  = date + delta;
183        PRINTF("\n*** Starting load at cycle %d (%d)\n", date, delta);
184
185        if( ioc_read(nblocks*cid/nclusters, 
186                     A[cid] , 
187                     nblocks/nclusters) )
188        {
189            PRINTF("echec ioc_read\n");
190            while(1);
191        }
192        if ( ioc_completed() )
193        {
194            PRINTF("echec ioc_completed\n");
195            while(1);
196        }
197
198        delta = proctime() - date;
199        date  = date + delta;
200        PRINTF("*** Completing load at cycle %d (%d)\n", date, delta);
201    }
202
203    barrier_wait(0);
204
205    //////////////////////////////////////////////////////////
206    // parallel horizontal filter :
207    // B <= transpose(FH(A))
208    // D <= A - FH(A)
209    // Each task computes (NL/ntasks) lines
210    // The image must be extended :
211    // if (z<0)         TA(cid,l,z) == TA(cid,l,0)
212    // if (z>NP-1)      TA(cid,l,z) == TA(cid,l,NP-1)
213
214    delta = proctime() - date;
215    date  = date + delta;
216    PRINTF("\n*** Starting horizontal filter at cycle %d (%d)\n", date, delta);
217
218    // l = absolute line index / p = absolute pixel index 
219    // first & last define which lines are handled by a given task(cid,lid)
220
221    first = (cid*nprocs + lid)*lines_per_task;
222    last  = first + lines_per_task;
223
224    for ( l=first ; l<last ; l++)
225    {
226        // src_c and src_l are the cluster index and the line index for A & D
227        int src_c = l/lines_per_cluster;
228        int src_l = l%lines_per_cluster;
229
230        // We use the spécific values of the horizontal ep-filter for optimisation:
231        // sum(p) = sum(p-1) + TA[p+hrange] - TA[p-hrange-1]
232        // To minimize the number of tests, the loop on pixels is split in three domains
233
234        int sum_p = (hrange+2)*TA(src_c, src_l, 0);
235        for ( x = 1 ; x < hrange ; x++) sum_p = sum_p + TA(src_c, src_l, x);
236
237        // first domain : from 0 to hrange
238        for ( p=0 ; p<hrange+1 ; p++)
239        {
240            // dst_c and dst_p are the cluster index and the pixel index for B
241            int dst_c = p/pixels_per_cluster;
242            int dst_p = p%pixels_per_cluster;
243            sum_p = sum_p + (int)TA(src_c, src_l, p+hrange) - (int)TA(src_c, src_l, 0);
244            TB(dst_c, dst_p, l) = sum_p/hnorm;
245            TD(src_c, src_l, p) = (int)TA(src_c, src_l, p) - sum_p/hnorm;
246        }
247        // second domain : from (hrange+1) to (NP-hrange-1)
248        for ( p = hrange+1 ; p < NP-hrange ; p++)
249        {
250            // dst_c and dst_p are the cluster index and the pixel index for B
251            int dst_c = p/pixels_per_cluster;
252            int dst_p = p%pixels_per_cluster;
253            sum_p = sum_p + (int)TA(src_c, src_l, p+hrange) - (int)TA(src_c, src_l, p-hrange-1);
254            TB(dst_c, dst_p, l) = sum_p/hnorm;
255            TD(src_c, src_l, p) = (int)TA(src_c, src_l, p) - sum_p/hnorm;
256        }
257        // third domain : from (NP-hrange) to (NP-1)
258        for ( p = NP-hrange ; p < NP ; p++)
259        {
260            // dst_c and dst_p are the cluster index and the pixel index for B
261            int dst_c = p/pixels_per_cluster;
262            int dst_p = p%pixels_per_cluster;
263            sum_p = sum_p + (int)TA(src_c, src_l, NP-1) - (int)TA(src_c, src_l, p-hrange-1);
264            TB(dst_c, dst_p, l) = sum_p/hnorm;
265            TD(src_c, src_l, p) = (int)TA(src_c, src_l, p) - sum_p/hnorm;
266        }
267
268        PRINTF(" - line %d computed at cycle %d\n", l, proctime());
269    }
270
271    delta = proctime() - date;
272    date  = date + delta;
273    PRINTF("*** Completing horizontal filter at cycle %d (%d)\n", date, delta);
274
275    barrier_wait(1);
276
277    //////////////////////////////////////////////////////////
278    // parallel vertical filter :
279    // C <= transpose(FV(B))
280    // Each task computes (NP/ntasks) columns
281    // The image must be extended :
282    // if (l<0)         TB(cid,p,x) == TB(cid,p,0)
283    // if (l>NL-1)      TB(cid,p,x) == TB(cid,p,NL-1)
284
285    delta = proctime() - date;
286    date  = date + delta;
287    PRINTF("\n*** starting vertical filter at cycle %d (%d)\n", date, delta);
288
289    // l = absolute line index / p = absolute pixel index
290    // first & last define which pixels are handled by a given task(cid,lid)
291
292    first = (cid*nprocs + lid)*pixels_per_task;
293    last  = first + pixels_per_task;
294
295    for ( p=first ; p<last ; p++)
296    {
297        // src_c and src_p are the cluster index and the pixel index for B
298        int src_c = p/pixels_per_cluster;
299        int src_p = p%pixels_per_cluster;
300
301        int sum_l;
302
303        // We use the specific values of the vertical ep-filter
304        // To minimize the number of tests, the NL lines are split in three domains
305
306        // first domain : explicit computation for the first 18 values
307        for ( l=0 ; l<18 ; l++)
308        {
309            // dst_c and dst_l are the cluster index and the line index for C
310            int dst_c = l/lines_per_cluster;
311            int dst_l = l%lines_per_cluster;
312
313            for ( x=0, sum_l=0 ; x<35 ; x++ )
314            {
315                sum_l = sum_l + vf[x] * TB(src_c, src_p, max(l-17+x,0) );
316            }
317            TC(dst_c, dst_l, p) = sum_l/vnorm;
318        }
319        // second domain
320        for ( l = 18 ; l < NL-17 ; l++ )
321        {
322            // dst_c and dst_l are the cluster index and the line index for C
323            int dst_c = l/lines_per_cluster;
324            int dst_l = l%lines_per_cluster;
325
326            sum_l = sum_l + TB(src_c, src_p, l+4)
327                          + TB(src_c, src_p, l+8)
328                          + TB(src_c, src_p, l+11)
329                          + TB(src_c, src_p, l+15)
330                          + TB(src_c, src_p, l+17)
331                          - TB(src_c, src_p, l-5)
332                          - TB(src_c, src_p, l-9)
333                          - TB(src_c, src_p, l-12)
334                          - TB(src_c, src_p, l-16)
335                          - TB(src_c, src_p, l-18);
336            TC(dst_c, dst_l, p) = sum_l/vnorm;
337        }
338        // third domain
339        for ( l = NL-17 ; l < NL ; l++ )
340        {
341            // dst_c and dst_l are the cluster index and the line index for C
342            int dst_c = l/lines_per_cluster;
343            int dst_l = l%lines_per_cluster;
344
345            sum_l = sum_l + TB(src_c, src_p, min(l+4,NL-1))
346                          + TB(src_c, src_p, min(l+8,NL-1))
347                          + TB(src_c, src_p, min(l+11,NL-1))
348                          + TB(src_c, src_p, min(l+15,NL-1))
349                          + TB(src_c, src_p, min(l+17,NL-1))
350                          - TB(src_c, src_p, l-5)
351                          - TB(src_c, src_p, l-9)
352                          - TB(src_c, src_p, l-12)
353                          - TB(src_c, src_p, l-16)
354                          - TB(src_c, src_p, l-18);
355            TC(dst_c, dst_l, p) = sum_l/vnorm;
356        }
357        PRINTF(" - column %d computed at cycle %d\n", p, proctime());
358    }
359
360    delta = proctime() - date;
361    date  = date + delta;
362    PRINTF("*** Completing vertical filter at cycle %d (%d)\n", date, delta);
363
364    barrier_wait(2);
365
366    ////////////////////////////////////////////////////////////////
367    // final computation and parallel display
368    // Z <= D + C
369    // Each processor use its private DMA channel to display
370    // the resulting image, line  per line (one byte per pixel).
371    // Eah processor computes & displays (NL/ntasks) lines.
372
373    delta = proctime() - date;
374    date  = date + delta;
375    PRINTF("\n*** Starting display at cycle %d (%d)\n", date, delta);
376
377    first = lid*lines_per_task;
378    last  = first + lines_per_task;
379
380    for ( l=first ; l<last ; l++)
381    {
382        for ( p=0 ; p<NP ; p++)
383        {
384           TZ(cid,l,p) = (unsigned char)(((TD(cid,l,p) + TC(cid,l,p))>>8) & 0xFF);
385        }
386        fb_write(NP*(cid*lines_per_cluster+l), &TZ(cid,l,0), NP);
387    }
388
389    delta = proctime() - date;
390    date  = date + delta;
391    PRINTF("*** Completing display at cycle %d (%d)\n", date, delta);
392
393    while(1);
394
395} // end main()
396
Note: See TracBrowser for help on using the repository browser.