source: trunk/platforms/tsarv4_generic_xbar/soft_filter/main.c @ 154

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

Introducing the tsarv4_generic_xbar platform

File size: 11.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      1512
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
18#define max(x,y) ((x) > (y) ? (x) : (y))
19#define min(x,y) ((x) < (y) ? (x) : (y))
20
21///////////////////////////////////////////
22// tricks to read parameters from ldscript
23///////////////////////////////////////////
24
25struct plaf;
26
27extern struct plaf seg_heap_base;
28extern struct plaf NB_PROCS;
29extern struct plaf NB_CLUSTERS;
30
31/////////////
32void main()
33{
34
35//////////////////////////////////
36// convolution kernel parameters
37// The content of this section is
38// Philips proprietary information.
39///////////////////////////////////
40
41    int vrange = 17;
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              = (unsigned int)&NB_PROCS;          // number of processors per cluster
93    int nclusters           = (unsigned int)&NB_CLUSTERS;       // number of clusters
94    int lid                 = pid%nprocs;                       // local processor id
95    int cid                 = pid/nprocs;                       // local processor 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 columns_per_task    = NP/ntasks;                        // number of columns per task
104    int columns_per_cluster = NP/nclusters;                     // number of columns per cluster
105
106    PRINTF("\n *** Processor %d entering main at cycle %d ***\n\n", pid, proctime());
107   
108    //////////////////////////
109    //  parameters checking
110    if( (nprocs != 1) && (nprocs != 2) && (nprocs != 4) )
111    {
112        PRINTF("NB_PROCS must be 1, 2 or 4\n");
113        while(1);
114    }
115    if( (nclusters !=  4) && (nclusters !=  8) && (nclusters != 16) && 
116        (nclusters != 32) && (nclusters != 64) && (nclusters !=128) && (nclusters != 256) )
117    {
118        PRINTF("NB_CLUSTERS must be a power of 2 between 4 and 256\n");
119        while(1);
120    }
121    if( pid >= ntasks )
122    {
123        PRINTF("processor id %d larger than NB_CLUSTERS*NB_PROCS\n", pid);
124        while(1);
125    }
126    if ( NL % nclusters != 0 )
127    {
128        PRINTF("NB_CLUSTERS must be a divider of NL");
129        while(1);
130    }
131    if( NP % nclusters != 0 )
132    {
133        PRINTF("NB_CLUSTERS must be a divider of NP");
134        while(1);
135    }
136
137    //////////////////////////////////////////////////////////////////
138    // Arrays of pointers on the shared, distributed buffers 
139    // containing the images (sized for the worst case : 256 clusters)
140    unsigned short*     A[256];
141    int*                B[256];
142    int*                C[256];
143    int*                D[256];
144   
145    // The shared, distributed buffers addresses are computed
146    // from the seg_heap_base value defined in the ldscript file
147    // and from the cluster increment = 4Gbytes/nclusters.
148    // These arrays of pointers are identical and
149    // replicated in the stack of each task
150    for( c=0 ; c<nclusters ; c++)
151    {
152        A[c] = (unsigned short*)(base + increment*c);
153        B[c] = (int*)(base + 4*NP*NL/nclusters + increment*c);
154        C[c] = (int*)(base + 8*NP*NL/nclusters + increment*c);
155        D[c] = (int*)(base + 12*NP*NL/nclusters + increment*c);
156    }
157
158    unsigned char* line_buf = (unsigned char*)(base + 2*NP*NL/nclusters + increment*c);
159   
160    PRINTF("NCLUSTERS = %d\n", nclusters); 
161    PRINTF("NPROCS    = %d\n\n", nprocs); 
162
163    PRINTF("*** starting barrier init at cycle %d ***\n", proctime());
164
165    //  barriers initialization
166    barrier_init(0, ntasks);
167    barrier_init(1, ntasks);
168    barrier_init(2, ntasks);
169
170    PRINTF("*** completing barrier init at cycle %d ***\n", proctime());
171
172    ////////////////////////////////////////////////////////
173    // pseudo parallel load from disk to A[c] buffers
174    // only task running on processor with (lid==0) does it
175    // nblocks/nclusters are loaded in each cluster
176
177    if ( lid == 0 )
178    {
179        delta = proctime() - date;
180        date  = date + delta;
181        PRINTF("\n *** Starting load at cycle %d (%d)\n", date, delta);
182
183        if( ioc_read(nblocks*cid/nclusters, 
184                     A[cid] , 
185                     nblocks/nclusters) )
186        {
187            PRINTF("echec ioc_read\n");
188            while(1);
189        }
190        if ( ioc_completed() )
191        {
192            PRINTF("echec ioc_completed\n");
193            while(1);
194        }
195
196        delta = proctime() - date;
197        date  = date + delta;
198        PRINTF(" *** Completing load at cycle %d (%d)\n", date, delta);
199    }
200
201    barrier_wait(0);
202
203    //////////////////////////////////////////////////////////
204    // parallel horizontal filter :
205    //  B <= transpose(FH(A))
206    //  D <= A - FH(A)
207    // each task computes (NL/ntasks) lines
208
209    delta = proctime() - date;
210    date  = date + delta;
211    PRINTF("\n *** starting horizontal filter at cycle %d (%d)\n", date, delta);
212
213    // l = line index in the cluster / p = pixel index
214    for ( l = lines_per_task*lid ; l < lines_per_task*(lid+1) ; l++)
215    {
216        // The image must be extended :
217        // if (p<0)     TA(cid,l,p) == TA(cid,l,0)
218        // if (p>NP-1)  TA(cid,l,p) == TA(cid,l,NL-1)
219        // We use the spécific values of the horizontal ep-filter for optimisation:
220        // sum(p) = sum(p-1) + TA[p+hrange] - TA[p-hrange-1]
221        // To minimize the number of tests, the loop on pixels is split in three domains
222
223        int sum = (hrange+2)*TA(cid,l,0);
224        for ( x = 1 ; x < hrange ; x++) sum = sum + TA(cid,l,x);
225
226        // first domain : from 0 to hrange
227        for ( p = 0 ; p < hrange+1 ; p++)
228        {
229            sum = sum + TA(cid,l,p+hrange) - TA(cid,l,0);
230            TB((p/columns_per_cluster),(p%columns_per_cluster),(cid*lines_per_cluster+l)) = sum/hnorm;
231            TD(cid,l,p) = TA(cid,l,p) - sum/hnorm;
232        }
233        // second domain : from (hrange+1) to (NP-hrange-1)
234        for ( p = hrange+1 ; p < NP-hrange ; p++)
235        {
236            sum = sum + TA(cid,l,p+hrange) - TA(cid,l,p-hrange-1);
237            TB((p/columns_per_cluster),(p%columns_per_cluster),(cid*lines_per_cluster+l)) = sum/hnorm;
238            TD(cid,l,p) = TA(cid,l,p) - sum/hnorm;
239        }
240        // third domain : from (NP-hrange) to (NP-1)
241        for ( p = NP-hrange ; p < NP ; p++)
242        {
243            sum = sum + TA(cid,l,NP-1) - TA(cid,l,p-hrange-1);
244            TB((p/columns_per_cluster),(p%columns_per_cluster),(cid*lines_per_cluster+l)) = sum/hnorm;
245            TD(cid,l,p) = TA(cid,l,p) - sum/hnorm;
246        }
247
248        PRINTF(" - line %d computed at cycle %d\n", l, proctime());
249    }
250
251    delta = proctime() - date;
252    date  = date + delta;
253    PRINTF(" *** completing horizontal filter at cycle %d (%d)\n", date, delta);
254
255    barrier_wait(1);
256
257    //////////////////////////////////////////////////////////
258    // parallel vertical filter :
259    //  C <= transpose(FV(B))
260    // each processor computes (NP/ntasks) columns
261
262    delta = proctime() - date;
263    date  = date + delta;
264    PRINTF("\n *** starting vertical filter at cycle %d (%d)\n", date, delta);
265
266    // l = line index / p = column index in the cluster
267    for ( p = columns_per_task*lid ; p < columns_per_task*(lid+1) ; p++)
268    {
269        unsigned int sum = 0;
270
271        // The image must be extended :
272        // if (l<0)     TB(cid,p,x) == TB(cid,p,0)
273        // if (l>NL-1)  TB(cid,p,x) == TB(cid,p,NL-1)
274        // We use the spécific values of the vertical ep-filter
275        // To minimize the number of tests, the NL lines are split in three domains
276
277        // first domain
278        for ( l = 0 ; l < vrange ; l++)
279        {
280            for ( x = 0 ; x < (2*vrange+1) ; x++ )
281            {
282                sum = sum + vf[x] * TB(cid,p,max(l-vrange+x,0));
283            }
284            TC((l/lines_per_cluster),(l%lines_per_cluster),(cid*columns_per_cluster+p)) = sum/vnorm;
285        }
286        // second domain
287        for ( l = vrange ; l < NL-vrange ; l++ )
288        {
289            sum = sum + TB(cid,p,l+4)
290                      + TB(cid,p,l+8)
291                      + TB(cid,p,l+11)
292                      + TB(cid,p,l+15)
293                      + TB(cid,p,l+17)
294                      - TB(cid,p,l-5)
295                      - TB(cid,p,l-9)
296                      - TB(cid,p,l-12)
297                      - TB(cid,p,l-16)
298                      - TB(cid,p,max(l-18,0));
299            TC((l/lines_per_cluster),(l%lines_per_cluster),(cid*columns_per_cluster+p)) = sum/vnorm;
300        }
301        // third domain
302        for ( l = NL-vrange ; l < NL ; l++ )
303        {
304            sum = sum + TB(cid,p,min(l+5,NL-1))
305                      + TB(cid,p,min(l+9,NL-1))
306                      + TB(cid,p,min(l+12,NL-1))
307                      + TB(cid,p,min(l+16,NL-1))
308                      + TB(cid,p,min(l+18,NL-1))
309                      - TB(cid,p,l-4)
310                      - TB(cid,p,l-8)
311                      - TB(cid,p,l-11)
312                      - TB(cid,p,l-15)
313                      - TB(cid,p,l-17);
314            TC((l/lines_per_cluster),(l%lines_per_cluster),(cid*columns_per_cluster+p)) = sum/vnorm;
315        }
316
317        PRINTF(" - column %d computed at cycle %d\n", p, proctime());
318    }
319
320    delta = proctime() - date;
321    date  = date + delta;
322    PRINTF(" *** completing vertical filter at cycle %d (%d)\n", date, delta);
323
324    barrier_wait(2);
325
326    ////////////////////////////////////////////////////////////////////////////
327    // final computation and parallel display using the distributed DMA
328    // D <= D + C
329    // Each processor use its private DMA channel to display
330    // the resulting image, line  per line (one byte per pixel).
331    // Eah processor computes & displays (NL/ntasks) lines.
332
333    delta = proctime() - date;
334    date  = date + delta;
335    PRINTF("\n *** final computation and display at cycle %d (%d)\n", date, delta);
336
337    for ( l = 0 ; l < lines_per_task ; l++)
338    {
339        for ( p = 0 ; p < NP ; p++)
340        {
341            TD(cid,l,p) = TD(cid,l,p) + TC(cid,l,p);
342            line_buf[p] = (unsigned char)(TD(cid,l,p));
343        }
344        int xxx = ( fb_write( NP*(cid*lines_per_cluster+lid*lines_per_task+l), line_buf, NP) );
345        if ( xxx )
346        {
347            PRINTF("echec fb_write = %d\n", xxx);
348            while(1);
349        }
350        if ( fb_completed() )
351        {
352            PRINTF("echec fb_completed\n");
353            while(1);
354        }
355        PRINTF(" - line %d displayed at cycle %d\n", l, proctime());
356    }
357
358    delta = proctime() - date;
359    date  = date + delta;
360    PRINTF(" *** completing display at cycle %d (%d)\n", date, delta);
361
362    while(1);
363
364} // end main()
365
Note: See TracBrowser for help on using the repository browser.