source: soft/giet_vm/applications/rosenfeld/src-par/mca_rosenfeld.c @ 805

Last change on this file since 805 was 805, checked in by meunier, 8 years ago
  • Adding the parallel version of rosenfeld
File size: 27.2 KB
Line 
1/* ----------------------- */
2/* --- mca_rosenfeld.c --- */
3/* ----------------------- */
4
5/*
6 * Copyright (c) 2016 Lionel Lacassagne, LIP6, UPMC, CNRS
7 * Init  : 2016/03/03
8 */
9
10#include <stdio.h>
11#include <stdlib.h>
12#include <string.h>
13#include <math.h>
14#include <user_barrier.h>
15#include <user_lock.h>
16
17#ifdef CLI
18#include "nrc_os_config.h"
19#include "nrc.h"
20#endif
21
22#include "util.h"
23#include "ecc_common.h"
24
25#include "palette.h"
26#include "bmpNR.h"
27
28#include "str_ext.h"
29
30// -----------
31// -- local --
32// -----------
33
34#include "mca.h"
35
36extern giet_barrier_t main_barrier;
37
38// ----------------------------------
39uint32 FindRoot(uint32 * T, uint32 e)
40// ----------------------------------
41{
42    uint32 r;
43   
44    r = e;
45    while (T[r] < r) {
46        r = T[r];
47    }
48    return r;
49}
50
51
52// ---------------------------------------------------
53uint32 FindRoot_Dist(uint32 ** D, uint32 r, int shift)
54// ---------------------------------------------------
55{
56    uint32 e;
57    uint32 e1;
58    uint32 e0;
59   
60    int mask = (1 << shift) - 1;
61   
62    MCA_VERBOSE2(printf("FindRoot_Dist(%d) (alpha = %d) \n", r, shift));
63    do {
64        e  = r;
65        e1 = r >> shift;
66        e0 = r & mask;
67        r = D[e1][e0];
68        MCA_VERBOSE2(printf("FindRoot: D(%d) = D[%d,%d] = %d (alpha = %d)\n", e, e1, e0, r, shift));
69    } while (r < e);
70    MCA_VERBOSE2(printf("FindRoot_Dist = %d \n\n", r));
71    return r;
72}
73
74
75// -----------------------------------------
76void SetRoot(uint32 * T, uint32 e, uint32 r)
77// -----------------------------------------
78{
79    while (T[e] < e) {
80        e = T[e];
81    }
82    T[e] = r;
83}
84
85
86// ----------------------------------------------------------
87void SetRoot_Dist(uint32 ** D, uint32 e, uint32 r, int shift)
88// ----------------------------------------------------------
89{
90    int mask = (1 << shift) - 1;
91   
92    uint32 e1 = e >> shift;
93    uint32 e0 = e & mask;
94   
95    D[e1][e0] = r;
96}
97
98
99// --------------------------------------------
100uint32 Union0(uint32 * T, uint32 ei, uint32 ej)
101// --------------------------------------------
102{
103    // version de la publication
104    // @QM : faut-il tester le cas == 0 ici aussi ?
105    uint32 ri, rj;
106    ri = (ei == 0) ? 0 : FindRoot(T, ei);
107    if (ei != ej) {
108        rj = (ej == 0) ? 0 : FindRoot(T, ej);
109        if (ri > rj) {
110            ri = rj;
111        }
112        SetRoot(T, ej, ri);
113    }
114    SetRoot(T, ei, ri);
115    return ri;
116}
117
118
119// -------------------------------------------------
120uint32 QuickUnion2(uint32 * T, uint32 e1, uint32 e2)
121// -------------------------------------------------
122{
123    // version QU de Union2
124    uint32 r1, r2, r;
125   
126    r1 = (e1 == 0) ? 0 : FindRoot(T, e1);
127    r2 = (e2 == 0) ? 0 : FindRoot(T, e2);
128   
129    r = ui32Min2(r1, r2);
130   
131    if (r1 != r) {
132        T[r1] = r; // SetRoot
133    }
134    if (r2 != r) {
135        T[r2] = r; // SetRoot
136    }
137   
138    return r;
139}
140
141
142// --------------------------------------------
143uint32 use1_QU_Rosenfeld(uint32 e1, uint32 * T)
144// --------------------------------------------
145{
146    return T[e1];
147}
148
149
150// -------------------------------------------------------
151uint32 use2_QU_Rosenfeld(uint32 e1, uint32 e2, uint32 * T)
152// -------------------------------------------------------
153{
154    return QuickUnion2(T, e1, e2);
155}
156
157
158// ----------------------------------------------------------------
159uint32 updateTable_Rosenfeld(uint32 * T, uint32 e, uint32 epsilon)
160// ----------------------------------------------------------------
161{
162    // notations e == v, epsilon == u avec v > u (v forcement different de u)
163    return Union0(T, e, epsilon); // original
164}
165
166
167// ----------------------------------------------------------------
168void vuse2_Rosenfeld(uint32 e1, uint32 e2, uint32 * T, uint32 ** D)
169// ----------------------------------------------------------------
170{
171    uint32 e;
172    uint32 a1;
173    uint32 a2;
174   
175    a1 = (e1 == 0) ? 0 : FindRoot(T, e1);
176    a2 = (e2 == 0) ? 0 : FindRoot(T, e2);
177   
178    if (a1 == a2) {
179        return; // evite la backdoor
180    }
181   
182    // forcement positifs car appel depuis optimizedBorder qui a fait un test
183    if (a1 < a2) {
184        e = a1;
185        updateTable_Rosenfeld(T, a2, e);
186    }
187    else {
188        e = a2;
189        updateTable_Rosenfeld(T, a1, e);
190    }
191}
192
193
194// ---------------------------------------------------------------------------
195void vuse3_Rosenfeld(uint32 e1, uint32 e2, uint32 e3, uint32 * T, uint32 ** D)
196// ---------------------------------------------------------------------------
197{
198    uint32 e;
199    uint32 a1;
200    uint32 a2;
201    uint32 a3;
202   
203    a1 = (e1 == 0) ? 0 : FindRoot(T, e1);
204    a2 = (e2 == 0) ? 0 : FindRoot(T, e2);
205    a3 = (e3 == 0) ? 0 : FindRoot(T, e3);
206   
207    if (a1 == a2 && a2 == a3) {
208        return;
209    }
210   
211    e = ui32Min3(a1, a2, a3);  // forcement positifs car appel depuis optimizedBorder qui a fait un test
212   
213    if (a1 > e) {
214        updateTable_Rosenfeld(T, a1, e);
215    }
216    a2 = T[a2];
217    if (a2 > e) {
218        updateTable_Rosenfeld(T, a2, e);
219    }
220    a3 = T[a3];
221    if (a3 > e) {
222        updateTable_Rosenfeld(T, a3, e);
223    }
224}
225
226
227// ----------------------------------------------
228uint32 solveTable_Rosenfeld(uint32 * T, uint32 ne)
229// ----------------------------------------------
230{
231    // equivalent a Flatten
232    // fermeture transitive sans pack
233    // (presence de trous dans les numeros d'etiquettes)
234   
235    uint32 e;
236   
237    for (e = 1; e <= ne; e++) {   
238        T[e] = T[T[e]];
239    }
240    return ne;
241}
242
243
244// ----------------------------------------------------------------------------------
245uint32 optimizedAccess_DT_Rosenfeld(uint32 ** E, int i, int j, uint32 * T, uint32 ne)
246// ----------------------------------------------------------------------------------
247{
248    // Decision Tree 8-connexe avec Quick-Union
249    uint32 a, b, c, d, e;
250   
251    b = E[i - 1][j];
252    if (b) {
253        e = use1_QU_Rosenfeld(b, T);
254    }
255    else {
256        c = E[i - 1][j + 1];
257        if (c) {
258            a = E[i - 1][j - 1];
259            if (a) {
260                e = use2_QU_Rosenfeld(a, c, T);
261            }
262            else {
263                d = E[i][j - 1];
264                if (d) {
265                    e = use2_QU_Rosenfeld(c, d, T);
266                }
267                else {
268                    e = use1_QU_Rosenfeld(c, T);
269                }
270            }
271        }
272        else {
273            a = E[i - 1][j - 1];
274            if (a) {
275                e = use1_QU_Rosenfeld(a, T);
276            }
277            else {
278                d = E[i][j - 1];
279                if (d) {
280                    e = use1_QU_Rosenfeld(d, T);
281                }
282                else {
283                    e = ++ne;
284                }
285            }
286        }
287    }
288    E[i][j] = e;
289    return ne;
290}
291
292
293// ------------------------------------------------------------------------------------------
294void optimizedBorder_Rosenfeld(uint32 ** E, int i, int j, uint32 * T, uint32 ** D, int alpha)
295// ------------------------------------------------------------------------------------------
296{
297    // copie de optimizedBorder_Rosenfeld
298    uint32 a, b, c, x;
299   
300    b = E[i - 1][j];
301    x = E[i][j];
302   
303    if (b) {
304        //printf("%d = %d\n", b, x);
305        vuse2_Rosenfeld(b, x, T, D);
306    }
307    else {
308        c = E[i - 1][j + 1];
309        if (c) {
310            a = E[i - 1][j - 1];
311            if (a) {
312                //printf("%d = %d = %d\n", a, c, x);
313                vuse3_Rosenfeld(a, c, x, T, D);
314            }
315            else {
316                //printf("%d = %d\n", c, x);
317                vuse2_Rosenfeld(c, x, T, D);
318            }
319        }
320        else {
321            a = E[i - 1][j - 1];
322            if (a) {
323                //printf("%d = %d\n", a, x);
324                vuse2_Rosenfeld(a, x, T, D);
325            }
326        }
327    }
328}
329
330
331// -----------------------------------------------------------------------------------------------------------------
332void borderMerging_Fast_Rosenfeld_Dist(uint8 **X, int i, int width, uint32 ** E, uint32 * T, uint32 ** D, int alpha)
333// -----------------------------------------------------------------------------------------------------------------
334{
335    for (int j = 0; j < width; j++) {
336        if (X[i][j])  {
337            optimizedBorder_Rosenfeld(E, i, j, T, D, alpha);
338        }
339    }
340    return;
341}
342
343
344// ------------------------------------------------------------------------------------------------------------------
345void borderMerging_Slow_Rosenfeld_Dist(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ** D, int alpha)
346// ------------------------------------------------------------------------------------------------------------------
347{
348    // copie de borderMerging_Rosenfeld_UF_Fast2_8C
349   
350    int j;
351   
352    uint32 e;
353   
354    uint32 e1, e2, e3, ex;
355    uint32 r1, r2, r3, rx;
356   
357    // --------------
358    // -- prologue --
359    // --------------
360    MCA_VERBOSE2(printf("[borderMerging_Slow_Rosenfeld_Dist] i = %d\n", i));
361   
362    j = 0;
363    ex = E[i][j];
364   
365    if (ex) {
366       
367        MCA_VERBOSE2(printf("[borderMerging_Slow_Rosenfeld_Dist] j = %d\n", j));
368       
369        e2 = E[i - 1][j];
370        e3 = E[i - 1][j + 1];
371       
372        r2 = FindRoot_Dist(D, e2, alpha);
373        r3 = FindRoot_Dist(D, e3, alpha);
374        rx = FindRoot(T, ex); // we already tested that ex != 0
375       
376        MCA_VERBOSE2(printf("\n"));
377        MCA_VERBOSE2(printf("e2 = %4d -> %4d\n", e2, r2));
378        MCA_VERBOSE2(printf("e3 = %4d -> %4d\n", e3, r3));
379        MCA_VERBOSE2(printf("ex = %4d -> %4d\n", ex, rx));
380       
381        e = ui32MinNonNul3(r2, r3, rx);
382       
383        // Quick-Union
384        if (r2 > e) {
385            SetRoot_Dist(D, r2, e, alpha);
386            MCA_VERBOSE2(printf("D[%4d] <- %d\n", r2, e));
387        }
388        if (r3 > e) {
389            SetRoot_Dist(D, r3, e, alpha);
390            MCA_VERBOSE2(printf("D[%4d] <- %d\n", r3, e));
391        }
392        if (rx > e) {
393            SetRoot(T, rx, e);
394            MCA_VERBOSE2(printf("D[%4d] <- %d\n", rx, e));
395        }
396        MCA_VERBOSE2(printf("\n"));
397        // attention SetRoot fait un while inutile
398    }
399   
400    // -----------------------
401    // -- boucle principale --
402    // -----------------------
403   
404    for (j = 0 + 1; j < width - 1; j++) {
405   
406        ex = E[i][j];
407       
408        // que le cas general (pour faire un code simple)
409        if (ex) {
410            MCA_VERBOSE2(printf("[borderMerging_Slow_Rosenfeld_Dist] j = %d\n", j));
411           
412            e1 = E[i - 1][j - 1];
413            e2 = E[i - 1][j];
414            e3 = E[i - 1][j + 1];
415       
416            r1 = FindRoot_Dist(D, e1, alpha);
417            r2 = FindRoot_Dist(D, e2, alpha);
418            r3 = FindRoot_Dist(D, e3, alpha);
419            rx = FindRoot(T, ex); // we already tested that ex != 0
420       
421            MCA_VERBOSE2(printf("\n"));
422            MCA_VERBOSE2(printf("e1 = %4d -> %4d\n", e1, r1));
423            MCA_VERBOSE2(printf("e2 = %4d -> %4d\n", e2, r2));
424            MCA_VERBOSE2(printf("e3 = %4d -> %4d\n", e3, r3));
425            MCA_VERBOSE2(printf("ex = %4d -> %4d\n", ex, rx));
426           
427            e = ui32MinNonNul4(r1, r2, r3, rx);
428           
429            // Quick-Union
430            if (r1 > e) {
431                SetRoot_Dist(D, r1, e, alpha);
432                MCA_VERBOSE2(printf("D[%4d] <- %d\n", r1, e));
433            }
434            if (r2 > e) {
435                SetRoot_Dist(D, r2, e, alpha);
436                MCA_VERBOSE2(printf("D[%4d] <- %d\n", r2, e));
437            }
438            if (r3 > e) {
439                SetRoot_Dist(D, r3, e, alpha);
440                MCA_VERBOSE2(printf("D[%4d] <- %d\n", r3, e));
441            }
442            if (rx > e) {
443                // @QM pourquoi pas T[e] = rx; ?
444                //SetRoot(T, rx, e);
445                T[e] = rx;
446                MCA_VERBOSE2(printf("D[%4d] <- %d\n", rx, e));
447            }
448            MCA_VERBOSE2(printf("\n"));
449            // attention SetRoot fait un while inutile
450        }
451    }
452   
453    // --------------
454    // -- epilogue --
455    // --------------
456   
457    j = width - 1;
458    ex = E[i][j];
459   
460    if (ex) {
461       
462        MCA_VERBOSE2(printf("[borderMerging_Slow_Rosenfeld_Dist] j = %d\n", j));
463       
464        e1 = E[i - 1][j - 1];
465        e2 = E[i - 1][j];
466       
467        r1 = FindRoot_Dist(D, e1, alpha);
468        r2 = FindRoot_Dist(D, e2, alpha);
469        rx = FindRoot(T, ex); // we already tested that ex != 0
470       
471        MCA_VERBOSE2(printf("\n"));
472        MCA_VERBOSE2(printf("e1 = %4d -> %4d\n", e1, r1));
473        MCA_VERBOSE2(printf("e2 = %4d -> %4d\n", e2, r2));
474        MCA_VERBOSE2(printf("ex = %4d -> %4d\n", ex, rx));
475       
476        e = ui32MinNonNul3(r1, r2, rx);
477       
478        // Quick-Union
479        if (r1 > e) {
480            SetRoot_Dist(D, r1, e, alpha);
481            MCA_VERBOSE2(printf("D[%4d] <- %d\n", r1, e));
482        }
483        if (r2 > e) {
484            SetRoot_Dist(D, r2, e, alpha);
485            MCA_VERBOSE2(printf("D[%4d] <- %d\n", r2, e));
486        }
487        if (rx > e) {
488            SetRoot(T, rx, e);
489            MCA_VERBOSE2(printf("D[%4d] <- %d\n", rx, e));
490        }
491        MCA_VERBOSE2(printf("\n"));
492    }
493    return;
494}
495
496
497// -------------------------------------------------------------------------------------------------------------
498void borderMerging_Rosenfeld_Dist(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ** D, int alpha)
499// -------------------------------------------------------------------------------------------------------------
500{
501    borderMerging_Slow_Rosenfeld_Dist(X, i, width, E, T, D, alpha);
502}
503
504
505// ---------------------------------------------------------------------------------------------
506uint32 line0Labeling_Rosenfeld(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ne)
507// ---------------------------------------------------------------------------------------------
508{
509    int j;
510    uint8 x;
511    uint32 e4;
512    uint32 r4;
513   
514    // prologue : j = 0
515    x = X[i][0];
516    if (x) {
517        E[i][0] = ++ne;
518    }
519    else {
520        E[i][0] = 0;
521    }
522   
523    // boucle et epilogue j = [1..width-1]
524    for (j = 1; j <= width - 1; j++) {
525        x = X[i][j];
526        if (x)  {
527            e4 = E[i][j - 1];
528           
529            if (e4 == 0) {
530                E[i][j] = ++ne;
531            }
532            else {
533                E[i][j] = e4;
534            }
535        }
536        else {
537            E[i][j] = 0;
538        }
539    }
540    return ne;
541}
542
543
544// -------------------------------------------------------------------------------------------------
545uint32 lineLabeling_Slow_Rosenfeld(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ne)
546// -------------------------------------------------------------------------------------------------
547{
548    // version lineLabeling_Rosenfeld_UF_QU_8C avec Quick-Union
549   
550    int j;
551   
552    uint8 x;
553    uint32 e;
554    uint32 e1, e2, e3, e4;
555    uint32 r1, r2, r3, r4;
556   
557    // --------------
558    // -- prologue --
559    // --------------
560   
561    j = 0;
562    x = X[i][j];
563   
564    if (x) {
565       
566        e2 = E[i - 1][j];
567        e3 = E[i - 1][j + 1];
568       
569        // nouvel element
570        if (e2 == 0 && e3 == 0) {
571            e = ++ne;
572            E[i][j] = e;
573        }
574        else {
575            // etiquettes identiques
576            if (e2 == e3) {
577                e = e2;
578                E[i][j] = e; 
579            }
580            else {   
581                // cas general
582                r2 = (e2 == 0) ? 0 : FindRoot(T, e2);
583                r3 = (e3 == 0) ? 0 : FindRoot(T, e3);
584               
585                e = ui32MinNonNul2(r2, r3);
586               
587                // Quick-Union
588                if (r2 > e) {
589                    T[r2] = e;
590                }
591                if (r3 > e) {
592                    T[r3] = e;
593                }
594                E[i][j] = e;
595            }
596        }
597    }
598    else {
599        E[i][j] = 0;
600    } // x
601   
602    // -----------------------
603    // -- boucle principale --
604    // -----------------------
605   
606    for (j = 0 + 1; j < width - 1; j++) {
607       
608        x = X[i][j];
609       
610        if (x)  {
611            e1 = E[i - 1][j - 1];
612            e2 = E[i - 1][j];
613            e3 = E[i - 1][j + 1];
614            e4 = E[i][j - 1];
615           
616            // nouvel element
617            if (e1 == 0 && e2 == 0 && e3 == 0 && e4 == 0) {
618                e = ++ne;
619                E[i][j] = e;
620            }
621            else {
622                // etiquettes identiques
623                if (e1 == e2 && e1 == e3 && e1 == e4) {
624                    e = e1;
625                    E[i][j] = e;
626                }
627                else {
628                    // cas general
629                    r1 = (e1 == 0) ? 0 : FindRoot(T, e1);
630                    r2 = (e2 == 0) ? 0 : FindRoot(T, e2);
631                    r3 = (e3 == 0) ? 0 : FindRoot(T, e3);
632                    r4 = (e4 == 0) ? 0 : FindRoot(T, e4);
633                   
634                    e = ui32MinNonNul4(r1, r2, r3, r4);
635                    giet_pthread_assert(e != 0, "e = 0\n");
636                   
637                    // Quick-Union
638                    if (r1 > e) {
639                        T[r1] = e;
640                    }
641                    if (r2 > e) {
642                        T[r2] = e;
643                    }
644                    if (r3 > e) {
645                        T[r3] = e;
646                    }
647                    if (r4 > e) {
648                        T[r4] = e;
649                    }
650                    E[i][j] = e;
651                }
652            }
653        }
654        else {
655            E[i][j] = 0;
656        } // x
657    } // j
658   
659    // --------------
660    // -- epilogue --
661    // --------------
662    j = width - 1;
663    x = X[i][j];
664   
665    if (x) {
666        e1 = E[i - 1][j - 1];
667        e2 = E[i - 1][j];
668        e4 = E[i][j - 1];
669       
670        // nouvel element
671        if (e1 == 0 && e2 == 0 && e4 == 0) {
672            e = ++ne;
673            E[i][j] = e;
674        }
675        else {
676            // etiquettes identiques
677            if (e1 == e2 && e1 == e4) {
678                e = e1;
679                E[i][j] = e;
680            }
681            else {
682                // cas general
683                r1 = (e1 == 0) ? 0 : FindRoot(T, e1);
684                r2 = (e2 == 0) ? 0 : FindRoot(T, e2);
685                r4 = (e4 == 0) ? 0 : FindRoot(T, e4);
686               
687                e = ui32MinNonNul3(r1, r2, r4);
688               
689                // Quick-Union
690                if (r1 > e) {
691                    T[r1] = e;
692                }
693                if (r2 > e) {
694                    T[r2] = e;
695                }
696                if (r4 > e) {
697                    T[r4] = e;
698                }
699                E[i][j] = e;
700            }
701        }
702    }
703    else {
704        E[i][j] = 0;
705    } // x
706   
707    return ne;
708}
709
710
711// -------------------------------------------------------------------------------------------------
712uint32 lineLabeling_Fast_Rosenfeld(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ne)
713// -------------------------------------------------------------------------------------------------
714{
715    // avec DT et QU
716    int j;
717    uint8 x;
718   
719    for (j = 0; j < width; j++) {
720        x = X[i][j];
721        if (x) {
722            ne = optimizedAccess_DT_Rosenfeld(E, i, j, T, ne);
723        }
724        else {
725            E[i][j] = 0;
726        }
727    }
728    return ne;
729}
730
731
732// --------------------------------------------------------------------------------------------
733uint32 lineLabeling_Rosenfeld(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ne)
734// --------------------------------------------------------------------------------------------
735{
736    return lineLabeling_Slow_Rosenfeld(X, i, width, E, T, ne);
737    //return lineLabeling_Fast_Rosenfeld(X, i, width, E, T, ne);
738}
739
740
741// ----------------------------------------------------------------
742uint32 countTable_Range_Rosenfeld(uint32 * T, uint32 e0, uint32 e1)
743// ----------------------------------------------------------------
744{
745    uint32 e;
746    uint32 nr = 0; // nombre de racines = de composantes connexes
747   
748    for (e = e0; e <= e1; e++) {
749        if (e == T[e]) {
750            nr += 1;
751        }
752    }
753    return nr;
754}
755
756
757// --------------------------------------------------------------
758void solveTable_Range_Rosenfeld(uint32 * T, uint32 e0, uint32 e1)
759// --------------------------------------------------------------
760{
761    uint32 e, r;
762   
763    for (e = e0; e <= e1; e++) {
764        r = T[T[e]];
765        if (r < e) {
766            T[e] = r; // racine de la classe d'equivalence
767        }
768    }   
769}
770
771
772// -------------------------------------
773void MCA_Label_Rosenfeld_PAR1(MCA * mca)
774// -------------------------------------
775{
776    if (mca->p == 0) { 
777        MCA_VERBOSE1(printf("------------------------------\n"));
778        MCA_VERBOSE1(printf("-- MCA_Label_Rosenfeld_PAR1 --\n"));
779        MCA_VERBOSE1(printf("------------------------------\n"));
780    }
781   
782    int i0 = mca->i0;
783    int i1 = mca->i1;
784    int width = mca->width; 
785    uint32 e0 = mca->e0;
786    uint32 e1 = mca->e1;
787    uint32 ne = e0 - 1;
788    uint32 nr = 0;
789
790    // local memory zones
791    uint8 **  X = mca->X;
792    uint32 ** E = mca->E;
793    uint32 *  T = mca->T;
794
795    if (mca->p == 0) {
796        set_ui32vector_j(T, e0 - 1, e1); // car e0 = 1, on a besoin que T[0] = 0 pour FindRoot
797        // @QM : maintenant que c'est testé partout, en a-t-on encore besoin ? A priori non (a tester)
798    }
799    else {
800        set_ui32vector_j(T, e0, e1);
801    }
802
803    MCA_VERBOSE2(display_ui8matrix_positive(X, i0, i1, 0, width - 1, 5, "Xp"); printf("\n"));
804
805    ne = line0Labeling_Rosenfeld(X, i0, width, E, T, ne);
806    for (int i = i0 + 1; i <= i1; i++) {
807        ne = lineLabeling_Rosenfeld(X, i, width, E, T, ne);
808    }
809
810    MCA_VERBOSE2(display_ui32matrix_positive(E, i0, i1, 0, width - 1, 5, "Ep"); printf("\n"));
811    if (mca->p == 0) { 
812        MCA_VERBOSE2(display_ui32vector_number(T, e0, ne, "%5d", "Tp_avant"));
813    }
814
815    // fermeture transitive sans pack
816    solveTable_Range_Rosenfeld(T, e0, ne);
817    nr = countTable_Range_Rosenfeld(T, e0, ne);
818    mca->ne = ne; // Plus grande etiquette de l'intervalle [e0..e1]
819
820    MCA_VERBOSE2(printf("p = %d : e = [%d..%d] -> ne = %d -> nr = %d\n", mca->p, e0, ne, (ne - e0 + 1), nr));
821    if (mca->p == 0) { 
822        MCA_VERBOSE2(display_ui32vector_number(T, e0, ne, "%5d", "Tp_apres"));
823    }
824}
825
826
827// -------------------------------------
828void MCA_Label_Rosenfeld_PYR2(MCA * mca)
829// -------------------------------------
830{
831    // input
832    int np = mca->mca->np;
833   
834    // variables
835    int n = np;
836    int nb_level = i32log2(np);
837    if ((1 << nb_level) < np) {
838        nb_level++; // correction pour traiter n non puissance de 2
839    }
840
841    if (mca->p == 0) {
842        MCA_VERBOSE1(printf("------------------------------\n"));
843        MCA_VERBOSE1(printf("-- MCA_Label_Rosenfeld_PYR2 --\n"));
844        MCA_VERBOSE1(printf("------------------------------\n"));
845    }
846   
847    // ------------------------------
848    // -- pyramidal border merging --
849    // ------------------------------
850   
851    // local variables
852    int i = mca->i0;
853    int width = mca->width;
854    int alpha = mca->alpha;
855    uint32 e0 = mca->e0;
856    uint32 e1 = mca->ne;
857
858    // local memory zones
859    uint8 **  X = mca->X;
860    uint32 ** E = mca->E;
861    uint32 *  T = mca->T;
862    uint32 ** D = mca->D;
863
864    // @QM
865    // en fait, c'est compliqué.
866    // On pourrait optimiser en faisant faire un "break" aux procs qui n'ont plus jamais
867    // à faire d'itération, mais le problÚme est alors qu'il faut utiliser des barriÚres avec
868    // un nombre de procs à attendre différent à chaque fois, et qu'il faut les
869    // initialiser => il faut précalculer toutes ces valeurs et avoir une alloc dynamique
870    // du nombre de barriÚres.
871    // De plus, le problÚme est décuplé si le nombre de lignes n'est pas une puissance de 2, car
872    // dans ce cas certains threads ne doivent rien faire à une itération courante i,
873    // mais doivent être actifs à i + 1 => encore plus dur de calculer le nombre
874    // de threads à attendre à chaque barriÚre + surtout savoir s'il faut break ou continue
875    for (int level = 1; level <= nb_level; level++) {
876        if ((mca->p + (1 << (level - 1))) % (1 << level) == 0) {
877            // thread actif
878            //MCA_VERBOSE1(printf("### level = %d - p = %d\n", level, mca->p));
879            borderMerging_Rosenfeld_Dist(X, i, width, E, T, D, alpha);  // en (i) et (i-1)
880        }
881        barrier_wait(&main_barrier);
882    }
883   
884
885    // ---------------------------------
886    // -- parallel transitive closure --
887    // ---------------------------------
888   
889    for (uint32 e = e0; e <= e1; e++) {
890        uint32 r = T[e]; // acces local
891        if (r < e) {
892            r = FindRoot_Dist(D, e, alpha); // acces distant
893        }
894        T[e] = r;
895        MCA_VERBOSE2(printf("p%d : T[%d] <- %d\n", mca->p, e, r));
896    }
897}
898
899
900// -------------------------------------
901void MCA_Label_Rosenfeld_PAR3(MCA * mca)
902// -------------------------------------
903{
904    // input
905    if (mca->p == 0) {
906        MCA_VERBOSE1(printf("------------------------------\n"));
907        MCA_VERBOSE1(printf("-- MCA_Label_Rosenfeld_PAR3 --\n"));
908        MCA_VERBOSE1(printf("------------------------------\n"));
909    }
910   
911    int i0 = mca->i0;
912    int i1 = mca->i1;
913    int j0 = 0;
914    int j1 = mca->width - 1;
915
916    uint32 ** E = mca->E;
917    uint32 * T = mca->T;
918
919    for (int i = i0; i <= i1; i++) {
920        for (int j = j0; j <= j1; j++) {
921            uint32 e = E[i][j];
922            if (e != 0) {
923                E[i][j] = T[e];
924            }
925        }
926    }
927}
928
929
930// =============================================================
931__attribute__((constructor)) void MCA_Label_Rosenfeld(MCA * mca)
932// =============================================================
933{
934    MCA_Scatter_ImageX(mca);
935    barrier_wait(&main_barrier);
936
937    MCA_Label_Rosenfeld_PAR1(mca);
938    barrier_wait(&main_barrier);
939   
940    //MCA_Gather_ImageL(mca);
941    //barrier_wait(&main_barrier);
942    //MCA_VERBOSE2(display_ui32matrix_positive(mca->E, mca->i0, mca->i1, 0, mca->width - 1, 5, "E2"));
943    //barrier_wait(&main_barrier);
944   
945    //MCA_Label_Rosenfeld_SEQ2(mca);
946    MCA_Label_Rosenfeld_PYR2(mca);
947    barrier_wait(&main_barrier);
948    //MCA_VERBOSE2(display_ui32matrix_positive(mca->E, mca->i0, mca->i1, 0, mca->width - 1, 5, "EPYR"));
949    //barrier_wait(&main_barrier);
950   
951    MCA_Label_Rosenfeld_PAR3(mca);
952    barrier_wait(&main_barrier);
953
954    MCA_Gather_ImageL(mca);
955    barrier_wait(&main_barrier);
956    //MCA_VERBOSE2(display_ui32matrix_positive(mca->E, mca->i0, mca->i1, 0, mca->width - 1, 5, "E3"));
957    //barrier_wait(&main_barrier);
958   
959    if (mca->p != 0) {
960        giet_pthread_exit(NULL);
961    }
962}
963
964// Local Variables:
965// tab-width: 4
966// c-basic-offset: 4
967// c-file-offsets:((innamespace . 0)(inline-open . 0))
968// indent-tabs-mode: nil
969// End:
970
971// vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4
972
Note: See TracBrowser for help on using the repository browser.