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

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

Introducing the three sub-directories in the softs directory:

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