- Timestamp:
- May 6, 2016, 3:06:29 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/applications/rosenfeld/src-par/mca_rosenfeld.c
r805 r821 12 12 #include <string.h> 13 13 #include <math.h> 14 #include <user_barrier.h> 15 #include <user_lock.h> 16 17 #ifdef CLI 14 #include <assert.h> 15 #if PARMERGE 16 #include <pthread.h> 17 #endif 18 18 19 #include "nrc_os_config.h" 20 #include "config.h" 19 21 #include "nrc.h" 22 23 #if TARGET_OS == GIETVM 24 #include <user_barrier.h> 25 #include <user_lock.h> 26 #include <giet_config.h> 27 #else 28 #include <stdbool.h> 20 29 #endif 30 21 31 22 32 #include "util.h" 23 33 #include "ecc_common.h" 24 25 34 #include "palette.h" 26 35 #include "bmpNR.h" 27 36 #include "clock.h" 28 37 #include "str_ext.h" 38 #include "ecc_features.h" 29 39 30 40 // ----------- … … 34 44 #include "mca.h" 35 45 36 extern giet_barrier_t main_barrier; 37 38 // ---------------------------------- 39 uint32 FindRoot(uint32 * T, uint32 e) 40 // ---------------------------------- 46 extern pthread_barrier_t main_barrier; 47 extern int display_features; 48 49 CLOCK_DEC; 50 51 52 // ----------------------------------------- 53 static uint32 FindRoot(uint32 * T, uint32 e) 54 // ----------------------------------------- 41 55 { 42 56 uint32 r; 43 57 58 assert(e != 0); 44 59 r = e; 45 60 while (T[r] < r) { 46 61 r = T[r]; 47 62 } 63 if (r == 0) { 64 printf("e = %d\n",e); 65 assert(0); 66 } 48 67 return r; 49 68 } 50 69 51 70 52 // --------------------------------------------------- 53 uint32 FindRoot_Dist(uint32 ** D, uint32 r, int shift)54 // --------------------------------------------------- 71 // ---------------------------------------------------------- 72 static uint32 FindRoot_Dist(uint32 ** D, uint32 r, int shift) 73 // ---------------------------------------------------------- 55 74 { 56 75 uint32 e; 57 76 uint32 e1; 58 77 uint32 e0; 78 79 assert(r != 0); 59 80 60 81 int mask = (1 << shift) - 1; 61 82 62 MCA_VERBOSE2(printf(" FindRoot_Dist(%d) (alpha = %d) \n", r, shift));83 MCA_VERBOSE2(printf("%s(%d, %d) \n", __func__, r, shift)); 63 84 do { 64 85 e = r; … … 66 87 e0 = r & mask; 67 88 r = D[e1][e0]; 68 MCA_VERBOSE2(printf(" FindRoot: D(%d) = D[%d,%d] = %d (alpha = %d)\n", e, e1, e0, r, shift));89 MCA_VERBOSE2(printf("%s: D(%d) = D[%d,%d] = %d (alpha = %d)\n", __func__, e, e1, e0, r, shift)); 69 90 } while (r < e); 70 MCA_VERBOSE2(printf("FindRoot_Dist = %d \n\n", r)); 91 MCA_VERBOSE2(printf("%s = %d \n\n", __func__, r)); 92 assert(r != 0); 71 93 return r; 72 94 } 73 95 74 96 75 // ----------------------------------------- 76 void 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 // ---------------------------------------------------------- 87 void SetRoot_Dist(uint32 ** D, uint32 e, uint32 r, int shift) 88 // ---------------------------------------------------------- 97 #if !FEATURES 98 // -------------------------------------------------------------------------------- 99 static void SetRoot_Rosenfeld_Dist(uint32 ** D, uint32 root, uint32 eps, int shift) 100 // -------------------------------------------------------------------------------- 89 101 { 90 102 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 // -------------------------------------------- 100 uint32 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 // ------------------------------------------------- 120 uint32 QuickUnion2(uint32 * T, uint32 e1, uint32 e2) 121 // ------------------------------------------------- 103 assert(root != 0 && eps != 0); 104 105 uint32 r1 = root >> shift; 106 uint32 r0 = root & mask; 107 108 D[r1][r0] = eps; 109 } 110 #endif // !FEATURES 111 112 113 #if FEATURES && !PARMERGE 114 // ---------------------------------------------------------------------------------------------------- 115 void SetRoot_Features_Rosenfeld_Dist(uint32 ** D, uint32 root, uint32 eps, int shift, RegionStats ** F) 116 // ---------------------------------------------------------------------------------------------------- 117 { 118 assert(root != 0 && eps != 0); 119 120 MCA_VERBOSE2(printf("F(%d) += F(%d)\n", eps, root)); 121 122 int mask = (1 << shift) - 1; 123 124 // SetRoot_Rosenfeld_Dist 125 uint32 r1 = root >> shift; 126 uint32 r0 = root & mask; 127 128 D[r1][r0] = eps; 129 130 uint32 e1 = eps >> shift; 131 uint32 e0 = eps & mask; 132 133 // version Dist de "RegionStats_Accumulate_Stats1_From_Index" 134 135 // F(eps) = F(eps) U F(root) 136 137 F[e1][e0].xmin = ui16min2(F[e1][e0].xmin, F[r1][r0].xmin); 138 F[e1][e0].xmax = ui16max2(F[e1][e0].xmax, F[r1][r0].xmax); 139 F[e1][e0].ymin = ui16min2(F[e1][e0].ymin, F[r1][r0].ymin); 140 F[e1][e0].ymax = ui16max2(F[e1][e0].ymax, F[r1][r0].ymax); 141 142 F[e1][e0].S += F[r1][r0].S; 143 F[e1][e0].Sx += F[r1][r0].Sx; 144 F[e1][e0].Sy += F[r1][r0].Sy; 145 } 146 #endif // FEATURES && !PARMERGE 147 148 149 #if FEATURES && PARMERGE 150 // ------------------------------------------------------------------------------------------------------------- 151 bool SetRoot_Parallel_Features_Rosenfeld_Dist(uint32 ** D, uint32 root, uint32 eps, int shift, RegionStats ** F) 152 // ------------------------------------------------------------------------------------------------------------- 153 { 154 assert(root != 0 && eps != 0); 155 156 MCA_VERBOSE2(printf("F(%d) += F(%d)\n", eps, root)); 157 158 int mask = (1 << shift) - 1; 159 160 // SetRoot_Rosenfeld_Dist 161 uint32 r1 = root >> shift; 162 uint32 r0 = root & mask; 163 164 uint32 e1 = eps >> shift; 165 uint32 e0 = eps & mask; 166 167 // Locking towards the root (first root, then eps) 168 pthread_spin_lock(&F[r1][r0].lock); 169 pthread_spin_lock(&F[e1][e0].lock); 170 // FIXME: merge these conditions later, when they both appear 171 if (D[e1][e0] != eps) { 172 // Someone change the root of epsilon, need to find the new root 173 printf("race cond 1\n"); 174 pthread_spin_unlock(&F[e1][e0].lock); 175 pthread_spin_unlock(&F[r1][r0].lock); 176 return false; 177 } 178 if (D[r1][r0] != root) { 179 // Someone change the root of epsilon, need to find the new root 180 printf("race cond 2\n"); 181 pthread_spin_unlock(&F[e1][e0].lock); 182 pthread_spin_unlock(&F[r1][r0].lock); 183 return false; 184 } 185 186 D[r1][r0] = eps; 187 188 // F(eps) = F(eps) U F(root) 189 F[e1][e0].xmin = ui16min2(F[e1][e0].xmin, F[r1][r0].xmin); 190 F[e1][e0].xmax = ui16max2(F[e1][e0].xmax, F[r1][r0].xmax); 191 F[e1][e0].ymin = ui16min2(F[e1][e0].ymin, F[r1][r0].ymin); 192 F[e1][e0].ymax = ui16max2(F[e1][e0].ymax, F[r1][r0].ymax); 193 194 F[e1][e0].S += F[r1][r0].S; 195 F[e1][e0].Sx += F[r1][r0].Sx; 196 F[e1][e0].Sy += F[r1][r0].Sy; 197 198 pthread_spin_unlock(&F[e1][e0].lock); 199 pthread_spin_unlock(&F[r1][r0].lock); 200 return true; 201 } 202 #endif // FEATURES && PARMERGE 203 204 205 206 #if FAST 207 // -------------------------------------------------------- 208 static uint32 QuickUnion2(uint32 * T, uint32 e1, uint32 e2) 209 // -------------------------------------------------------- 122 210 { 123 211 // 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 // -------------------------------------------- 143 uint32 use1_QU_Rosenfeld(uint32 e1, uint32 * T) 144 // -------------------------------------------- 145 { 146 return T[e1]; 147 } 148 149 150 // ------------------------------------------------------- 151 uint32 use2_QU_Rosenfeld(uint32 e1, uint32 e2, uint32 * T) 152 // ------------------------------------------------------- 212 uint32 r1 = FindRoot(T, e1); 213 uint32 r2 = FindRoot(T, e2); 214 215 assert(e1 != 0 && e2 != 0 && r1 != 0 && r2 != 0); 216 uint32 eps = ui32Min2(r1, r2); 217 218 if (r1 > eps) { 219 T[r1] = eps; // SetRoot sans besoin de remonter 220 } 221 if (r2 > eps) { 222 T[r2] = eps; // SetRoot sans besoin de remonter 223 } 224 assert(e1 != 0 && e2 != 0 && r1 != 0 && r2 != 0); 225 226 return eps; 227 } 228 #endif // FAST 229 230 231 #if FAST 232 // --------------------------------------------------- 233 static uint32 use1_QU_Rosenfeld(uint32 e1, uint32 * T) 234 // --------------------------------------------------- 235 { 236 return FindRoot(T, e1); 237 } 238 #endif // FAST 239 240 241 #if FAST 242 // -------------------------------------------------------------- 243 static uint32 use2_QU_Rosenfeld(uint32 e1, uint32 e2, uint32 * T) 244 // -------------------------------------------------------------- 153 245 { 154 246 return QuickUnion2(T, e1, e2); 155 247 } 156 157 158 // ---------------------------------------------------------------- 159 uint32 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 // ---------------------------------------------------------------- 168 void 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) { 248 #endif // FAST 249 250 251 #if FAST && !FEATURES 252 // --------------------------------------------------------------------------------------- 253 static void vuse2_Rosenfeld_Dist(uint32 ed, uint32 el, uint32 * T, uint32 ** D, int alpha) 254 // --------------------------------------------------------------------------------------- 255 { 256 uint32 rd = FindRoot_Dist(D, ed, alpha); 257 258 uint32 rl = T[el]; // car le premier acces est local 259 rl = FindRoot_Dist(D, rl, alpha); 260 261 assert(ed != 0 && el != 0 && rd != 0 && rl != 0); 262 if (rd == rl) { 179 263 return; // evite la backdoor 180 264 } 181 265 182 // forcement positifs car appel depuis optimizedBorder qui a fait un test183 if (a1 < a2) {184 e = a1;185 updateTable_Rosenfeld(T, a2, e);266 // forcement positifs car appel depuis optimizedBorder 267 // qui a fait un test 268 if (rd < rl) { 269 SetRoot_Rosenfeld_Dist(D, rl, rd, alpha); 186 270 } 187 271 else { 188 e = a2; 189 updateTable_Rosenfeld(T, a1, e); 190 } 191 } 192 193 194 // --------------------------------------------------------------------------- 195 void 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) { 272 SetRoot_Rosenfeld_Dist(D, rd, rl, alpha); 273 } 274 } 275 #endif // FAST && !FEATURES 276 277 278 #if FAST && !FEATURES 279 // ----------------------------------------------------------------------------------------------------- 280 static void vuse3_Rosenfeld_Dist(uint32 ed1, uint32 ed2, uint32 el3, uint32 * T, uint32 ** D, int alpha) 281 // ----------------------------------------------------------------------------------------------------- 282 { 283 uint32 r1 = FindRoot_Dist(D, ed1, alpha); 284 uint32 r2 = FindRoot_Dist(D, ed2, alpha); 285 286 // QM 287 //uint32 r3 = FindRoot(T, el3); // local - distant 288 uint32 r3 = T[el3]; // local - distant 289 r3 = FindRoot_Dist(D, r3, alpha); 290 291 assert(ed1 != 0 && ed2 != 0 && el3 != 0 && r1 != 0 && r2 != 0 && r3 != 0); 292 293 if (r1 == r2 && r2 == r3) { 208 294 return; 209 295 } 210 296 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 // ---------------------------------------------- 228 uint32 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 // ---------------------------------------------------------------------------------- 245 uint32 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); 297 uint32 eps = ui32Min3(r1, r2, r3); // forcement positifs car appel depuis optimizedBorder qui a fait un test 298 299 if (r1 > eps) { 300 SetRoot_Rosenfeld_Dist(D, r1, eps, alpha); 301 } 302 //r2 = T[r2]; // @QM est-ce indispensable s'il n'y a pas de features ? (cf. slow no features) 303 // comment est-on sur que r2 (ou r3) est local ??? 304 if (r2 > eps) { 305 SetRoot_Rosenfeld_Dist(D, r2, eps, alpha); 306 } 307 //r3 = T[r3]; 308 if (r3 > eps) { 309 SetRoot_Rosenfeld_Dist(D, r3, eps, alpha); 310 } 311 } 312 #endif // FAST && !FEATURES 313 314 315 #if FAST && FEATURES && !PARMERGE 316 // ----------------------------------------------------------------------------------------------------------- 317 void vuse2_Features_Rosenfeld_Dist(uint32 ed, uint32 el, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 318 // ----------------------------------------------------------------------------------------------------------- 319 { 320 assert(ed != 0 && el != 0); 321 322 uint32 rd = FindRoot_Dist(D, ed, alpha); 323 324 uint32 rl = T[el]; // car le premier acces est local 325 assert(rl != 0); 326 rl = FindRoot_Dist(D, rl, alpha); 327 328 assert(rd != 0 && rl != 0); 329 330 if (rd == rl) { 331 return; // evite la backdoor 332 } 333 334 // forcement positifs car appel depuis optimizedBorder 335 // qui a fait un test 336 if (rd < rl) { 337 SetRoot_Features_Rosenfeld_Dist(D, rl, rd, alpha, F); 254 338 } 255 339 else { 256 c = E[i - 1][j + 1]; 257 if (c) { 258 a = E[i - 1][j - 1]; 340 SetRoot_Features_Rosenfeld_Dist(D, rd, rl, alpha, F); 341 } 342 } 343 #endif // FAST && FEATURES && !PARMERGE 344 345 346 #if FAST && FEATURES && !PARMERGE 347 // ------------------------------------------------------------------------------------------------------------------------- 348 void vuse3_Features_Rosenfeld_Dist(uint32 ed1, uint32 ed2, uint32 el3, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 349 // ------------------------------------------------------------------------------------------------------------------------- 350 { 351 assert(ed1 != 0 && ed2 != 0 && el3 != 0); 352 353 uint32 r1 = FindRoot_Dist(D, ed1, alpha); 354 uint32 r2 = FindRoot_Dist(D, ed2, alpha); 355 356 //uint32 r3 = FindRoot(T, el3); // local - distant 357 uint32 r3 = T[el3]; // local - distant 358 assert(r3 != 0); 359 r3 = FindRoot_Dist(D, r3, alpha); 360 361 assert(r1 != 0 && r2 != 0 && r3 != 0); 362 363 if (r1 == r2 && r2 == r3) { 364 return; 365 } 366 367 uint32 eps = ui32Min3(r1, r2, r3); // forcement positifs car appel depuis optimizedBorder qui a fait un test 368 369 if (r1 > eps) { 370 SetRoot_Features_Rosenfeld_Dist(D, r1, eps, alpha, F); 371 } 372 //r2 = T[r2]; 373 if (r2 > eps && r2 != r1) { 374 SetRoot_Features_Rosenfeld_Dist(D, r2, eps, alpha, F); 375 } 376 //r3 = T[r3]; 377 if (r3 > eps && r3 != r2 && r3 != r1) { 378 SetRoot_Features_Rosenfeld_Dist(D, r3, eps, alpha, F); 379 } 380 } 381 #endif // FAST && FEATURES && !PARMERGE 382 383 384 #if FAST && FEATURES && PARMERGE 385 // -------------------------------------------------------------------------------------------------------------------- 386 void vuse2_Parallel_Features_Rosenfeld_Dist(uint32 ed, uint32 el, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 387 // -------------------------------------------------------------------------------------------------------------------- 388 { 389 bool ok; 390 assert(ed != 0 && el != 0); 391 uint32 rl = T[el]; // car le premier acces est local 392 assert(rl != 0); 393 394 uint32 rd; 395 396 do { 397 rd = FindRoot_Dist(D, ed, alpha); // no lock 398 rl = FindRoot_Dist(D, rl, alpha); 399 400 assert(rd != 0 && rl != 0); 401 402 if (rd == rl) { 403 return; // evite la backdoor 404 } 405 406 // forcement positifs car appel depuis optimizedBorder 407 // qui a fait un test 408 if (rd < rl) { 409 ok = SetRoot_Parallel_Features_Rosenfeld_Dist(D, rl, rd, alpha, F); 410 } 411 else { 412 ok = SetRoot_Parallel_Features_Rosenfeld_Dist(D, rd, rl, alpha, F); 413 } 414 } while (!ok); 415 } 416 #endif // FAST && FEATURES && PARMERGE 417 418 419 #if FAST && FEATURES && PARMERGE 420 // ---------------------------------------------------------------------------------------------------------------------------------- 421 void vuse3_Parallel_Features_Rosenfeld_Dist(uint32 ed1, uint32 ed2, uint32 el3, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 422 // ---------------------------------------------------------------------------------------------------------------------------------- 423 { 424 bool ok1, ok2, ok3; 425 assert(ed1 != 0 && ed2 != 0 && el3 != 0); 426 427 uint32 r1; 428 uint32 r2; 429 uint32 r3 = T[el3]; // local - distant 430 assert(r3 != 0); 431 432 do { 433 r1 = FindRoot_Dist(D, ed1, alpha); 434 r2 = FindRoot_Dist(D, ed2, alpha); 435 r3 = FindRoot_Dist(D, r3, alpha); 436 437 assert(r1 != 0 && r2 != 0 && r3 != 0); 438 439 if (r1 == r2 && r2 == r3) { 440 return; 441 } 442 443 uint32 eps = ui32Min3(r1, r2, r3); // forcement positifs car appel depuis optimizedBorder qui a fait un test 444 445 ok1 = true; 446 ok2 = true; 447 ok3 = true; 448 if (r1 > eps) { 449 ok1 = SetRoot_Parallel_Features_Rosenfeld_Dist(D, r1, eps, alpha, F); 450 } 451 if (r2 > eps && r2 != r1) { 452 ok2 = SetRoot_Parallel_Features_Rosenfeld_Dist(D, r2, eps, alpha, F); 453 } 454 if (r3 > eps && r3 != r2 && r3 != r1) { 455 ok3 = SetRoot_Parallel_Features_Rosenfeld_Dist(D, r3, eps, alpha, F); 456 } 457 } while (!(ok1 && ok2 && ok3)); 458 } 459 #endif // FAST && FEATURES && PARMERGE 460 461 462 463 464 #if FAST && !FEATURES 465 // ------------------------------------------------------------------------------------------------------ 466 static void optimizedBorder_Rosenfeld_Dist(uint32 ** E, int i, int j, uint32 * T, uint32 ** D, int alpha) 467 // ------------------------------------------------------------------------------------------------------ 468 { 469 uint32 a, b, c, x; 470 471 x = E[i][j]; 472 if (x) { 473 b = E[i - 1][j]; 474 if (b) { 475 vuse2_Rosenfeld_Dist(b, x, T, D, alpha); // dist, local 476 } 477 else { 478 c = E[i - 1][j + 1]; 479 if (c) { 480 a = E[i - 1][j - 1]; 481 if (a) { 482 vuse3_Rosenfeld_Dist(a, c, x, T, D, alpha); // dist, local 483 } 484 else { 485 vuse2_Rosenfeld_Dist(c, x, T, D, alpha); // dist, local 486 } 487 } 488 else { 489 a = E[i - 1][j - 1]; 490 if (a) { 491 vuse2_Rosenfeld_Dist(a, x, T, D, alpha); // dist, local 492 } 493 } 494 } 495 } 496 } 497 #endif // FAST && !FEATURES 498 499 500 #if FAST && !FEATURES 501 // --------------------------------------------------------------------------------------------------- 502 static void optimizedBorderLeft_Rosenfeld_Dist(uint32 ** E, int i, int j, uint32 * T, uint32 ** D, int alpha) 503 // --------------------------------------------------------------------------------------------------- 504 { 505 uint32 x = E[i][j]; 506 if (x) { 507 uint32 b = E[i - 1][j]; 508 if (b) { 509 vuse2_Rosenfeld_Dist(b, x, T, D, alpha); // dist, local 510 } 511 else { 512 uint32 c = E[i - 1][j + 1]; 513 if (c) { 514 vuse2_Rosenfeld_Dist(c, x, T, D, alpha); // dist, local 515 } 516 } 517 } 518 } 519 #endif // FAST && !FEATURES 520 521 522 #if FAST && !FEATURES 523 // ----------------------------------------------------------------------------------------------------------- 524 static void optimizedBorderRight_Rosenfeld_Dist(uint32 ** E, int i, int j, uint32 * T, uint32 ** D, int alpha) 525 // ----------------------------------------------------------------------------------------------------------- 526 { 527 // copie de optimizedBorder_Rosenfeld 528 // test d'existance de ex en local local 529 530 uint32 b = E[i - 1][j]; 531 uint32 x = E[i][j]; 532 533 if (x) { 534 if (b) { 535 vuse2_Rosenfeld_Dist(b, x, T, D, alpha); // dist, local 536 } 537 else { 538 uint32 a = E[i - 1][j - 1]; 259 539 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 // ------------------------------------------------------------------------------------------ 294 void 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 // ----------------------------------------------------------------------------------------------------------------- 332 void 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 // ------------------------------------------------------------------------------------------------------------------ 345 void 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 540 vuse2_Rosenfeld_Dist(a, x, T, D, alpha); // dist, local 541 } 542 } 543 } 544 } 545 #endif // FAST && !FEATURES 546 547 548 #if FAST && !FEATURES 549 // ------------------------------------------------------------------------------------------------------------------------ 550 static void borderMerging_Fast_Rosenfeld_Dist(uint8 **X, int i, int width, uint32 ** E, uint32 * T, uint32 ** D, int alpha) 551 // ------------------------------------------------------------------------------------------------------------------------ 552 { 553 // Prologue 554 optimizedBorderLeft_Rosenfeld_Dist(E, i, 0, T, D, alpha); 555 // Boucle principale 556 for (int j = 1; j < width - 1; j++) { 557 optimizedBorder_Rosenfeld_Dist(E, i, j, T, D, alpha); 558 } 559 // Epilogue 560 optimizedBorderRight_Rosenfeld_Dist(E, i, width - 1, T, D, alpha); 561 } 562 #endif // FAST && !FEATURES 563 564 565 #if SLOW && !FEATURES 566 // ------------------------------------------------------------------------------------------------------------------------- 567 static void borderMerging_Slow_Rosenfeld_Dist(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ** D, int alpha) 568 // ------------------------------------------------------------------------------------------------------------------------- 569 { 350 570 int j; 351 571 352 uint32 e; 353 572 uint32 eps; 354 573 uint32 e1, e2, e3, ex; 355 574 uint32 r1, r2, r3, rx; … … 358 577 // -- prologue -- 359 578 // -------------- 360 MCA_VERBOSE2(printf("[ borderMerging_Slow_Rosenfeld_Dist] i = %d\n", i));579 MCA_VERBOSE2(printf("[%s] i = %d\n", __func__, i)); 361 580 362 581 j = 0; … … 365 584 if (ex) { 366 585 367 MCA_VERBOSE2(printf("[ borderMerging_Slow_Rosenfeld_Dist] j = %d\n", j));586 MCA_VERBOSE2(printf("[%s] j = %d\n", __func__, j)); 368 587 369 588 e2 = E[i - 1][j]; 370 589 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 590 591 // test pour eviter acces distant 592 r2 = e2 ? FindRoot_Dist(D, e2, alpha) : 0; 593 r3 = e3 ? FindRoot_Dist(D, e3, alpha) : 0; 594 595 rx = T[ex]; 596 rx = FindRoot_Dist(D, rx, alpha); 597 376 598 MCA_VERBOSE2(printf("\n")); 377 599 MCA_VERBOSE2(printf("e2 = %4d -> %4d\n", e2, r2)); … … 379 601 MCA_VERBOSE2(printf("ex = %4d -> %4d\n", ex, rx)); 380 602 381 e = ui32MinNonNul3(r2, r3, rx);603 eps = ui32MinNonNul3(r2, r3, rx); 382 604 383 605 // 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 ));606 if (r2 > eps) { 607 SetRoot_Rosenfeld_Dist(D, r2, eps, alpha); 608 MCA_VERBOSE2(printf("D[%4d] <- %d\n", r2, eps)); 609 } 610 if (r3 > eps) { 611 SetRoot_Rosenfeld_Dist(D, r3, eps, alpha); 612 MCA_VERBOSE2(printf("D[%4d] <- %d\n", r3, eps)); 613 } 614 if (rx > eps) { 615 SetRoot_Rosenfeld_Dist(D, rx, eps, alpha); 616 MCA_VERBOSE2(printf("D[%4d] <- %d\n", rx, eps)); 395 617 } 396 618 MCA_VERBOSE2(printf("\n")); 397 // attention SetRoot fait un while inutile398 619 } 399 620 … … 408 629 // que le cas general (pour faire un code simple) 409 630 if (ex) { 410 MCA_VERBOSE2(printf("[ borderMerging_Slow_Rosenfeld_Dist] j = %d\n", j));631 MCA_VERBOSE2(printf("[%s] j = %d\n", __func__, j)); 411 632 412 633 e1 = E[i - 1][j - 1]; … … 414 635 e3 = E[i - 1][j + 1]; 415 636 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 637 // test pour eviter acces distant 638 r1 = e1 ? FindRoot_Dist(D, e1, alpha) : 0; 639 r2 = e2 ? FindRoot_Dist(D, e2, alpha) : 0; 640 r3 = e3 ? FindRoot_Dist(D, e3, alpha) : 0; 641 642 rx = T[ex]; 643 rx = FindRoot_Dist(D, rx, alpha); 644 421 645 MCA_VERBOSE2(printf("\n")); 422 646 MCA_VERBOSE2(printf("e1 = %4d -> %4d\n", e1, r1)); … … 425 649 MCA_VERBOSE2(printf("ex = %4d -> %4d\n", ex, rx)); 426 650 427 e = ui32MinNonNul4(r1, r2, r3, rx);651 eps = ui32MinNonNul4(r1, r2, r3, rx); 428 652 429 653 // 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)); 654 if (r1 > eps) { 655 SetRoot_Rosenfeld_Dist(D, r1, eps, alpha); 656 MCA_VERBOSE2(printf("D[%4d] <- %d\n", r1, eps)); 657 } 658 if (r2 > eps) { 659 SetRoot_Rosenfeld_Dist(D, r2, eps, alpha); 660 MCA_VERBOSE2(printf("D[%4d] <- %d\n", r2, eps)); 661 } 662 if (r3 > eps) { 663 SetRoot_Rosenfeld_Dist(D, r3, eps, alpha); 664 MCA_VERBOSE2(printf("D[%4d] <- %d\n", r3, eps)); 665 } 666 if (rx > eps) { 667 SetRoot_Rosenfeld_Dist(D, rx, eps, alpha); 668 MCA_VERBOSE2(printf("D[%4d] <- %d\n", rx, eps)); 447 669 } 448 670 MCA_VERBOSE2(printf("\n")); … … 460 682 if (ex) { 461 683 462 MCA_VERBOSE2(printf("[ borderMerging_Slow_Rosenfeld_Dist] j = %d\n", j));684 MCA_VERBOSE2(printf("[%s] j = %d\n", __func__, j)); 463 685 464 686 e1 = E[i - 1][j - 1]; 465 687 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 688 689 // test pour eviter acces distant 690 r1 = e1 ? FindRoot_Dist(D, e1, alpha) : 0; 691 r2 = e2 ? FindRoot_Dist(D, e2, alpha) : 0; 692 693 rx = T[ex]; 694 rx = FindRoot_Dist(D, rx, alpha); 695 471 696 MCA_VERBOSE2(printf("\n")); 472 697 MCA_VERBOSE2(printf("e1 = %4d -> %4d\n", e1, r1)); … … 474 699 MCA_VERBOSE2(printf("ex = %4d -> %4d\n", ex, rx)); 475 700 476 e = ui32MinNonNul3(r1, r2, rx);701 eps = ui32MinNonNul3(r1, r2, rx); 477 702 478 703 // 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 ));704 if (r1 > eps) { 705 SetRoot_Rosenfeld_Dist(D, r1, eps, alpha); 706 MCA_VERBOSE2(printf("D[%4d] <- %d\n", r1, eps)); 707 } 708 if (r2 > eps) { 709 SetRoot_Rosenfeld_Dist(D, r2, eps, alpha); 710 MCA_VERBOSE2(printf("D[%4d] <- %d\n", r2, eps)); 711 } 712 if (rx > eps) { 713 SetRoot_Rosenfeld_Dist(D, rx, eps, alpha); 714 MCA_VERBOSE2(printf("D[%4d] <- %d\n", rx, eps)); 490 715 } 491 716 MCA_VERBOSE2(printf("\n")); … … 493 718 return; 494 719 } 495 496 497 // ------------------------------------------------------------------------------------------------------------- 498 void borderMerging_Rosenfeld_Dist(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ** D, int alpha) 499 // ------------------------------------------------------------------------------------------------------------- 500 { 720 #endif // SLOW && !FEATURES 721 722 723 #if SLOW && FEATURES 724 // ---------------------------------------------------------------------------------------------------------------------------------------------------- 725 static void borderMerging_Slow_Features_Rosenfeld_Dist(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 726 // ---------------------------------------------------------------------------------------------------------------------------------------------------- 727 { 728 int j = 0; 729 730 uint32 eps; 731 732 uint32 e1, e2, e3, ex; 733 uint32 r1, r2, r3, rx; 734 735 // -------------- 736 // -- prologue -- 737 // -------------- 738 MCA_VERBOSE2(printf("[%s] i = %d\n", __func__, i)); 739 740 ex = E[i][j]; 741 742 if (ex) { 743 744 MCA_VERBOSE2(printf("[%s] j = %d\n", __func__, j)); 745 746 e2 = E[i - 1][j]; 747 e3 = E[i - 1][j + 1]; 748 749 if (e2 || e3) { 750 751 // test pour eviter acces distant 752 r2 = e2 ? FindRoot_Dist(D, e2, alpha) : 0; 753 r3 = e3 ? FindRoot_Dist(D, e3, alpha) : 0; 754 755 rx = T[ex]; 756 rx = FindRoot_Dist(D, rx, alpha); 757 758 eps = ui32MinNonNul3(r2, r3, rx); 759 760 MCA_VERBOSE2(printf("\n")); 761 MCA_VERBOSE2(printf("e2 = %5d -> r2 = %5d\n", e2, r2)); 762 MCA_VERBOSE2(printf("e3 = %5d -> r3 = %5d\n", e3, r3)); 763 MCA_VERBOSE2(printf("ex = %5d -> rx = %5d\n", ex, rx)); 764 MCA_VERBOSE2(printf("eps = %5d\n", eps)); 765 766 // Quick-Union 767 // @QM 768 if (r2 > eps) { 769 SetRoot_Features_Rosenfeld_Dist(D, r2, eps, alpha, F); 770 MCA_VERBOSE2(printf("D[%5d] <- %d\n", r2, eps)); 771 } 772 if (r3 > 0) { 773 r3 = FindRoot_Dist(D, r3, alpha); 774 } 775 // Pour le cas où r2 == r3, il ne faut pas ajouter deux fois les features 776 //if (r3 > eps && r3 != r2) { 777 if (r3 > eps) { 778 SetRoot_Features_Rosenfeld_Dist(D, r3, eps, alpha, F); 779 MCA_VERBOSE2(printf("D[%5d] <- %d\n", r3, eps)); 780 } 781 rx = FindRoot_Dist(D, rx, alpha); 782 //if (rx > eps && rx != r3 && rx != r2) { 783 if (rx > eps) { 784 SetRoot_Features_Rosenfeld_Dist(D, rx, eps, alpha, F); 785 MCA_VERBOSE2(printf("D[%5d] <- %d\n", rx, eps)); 786 } 787 MCA_VERBOSE2(printf("---------------------------\n")); 788 } 789 } 790 791 // ----------------------- 792 // -- boucle principale -- 793 // ----------------------- 794 795 for (j = 0 + 1; j < width - 1; j++) { 796 797 ex = E[i][j]; 798 799 if (ex) { 800 801 MCA_VERBOSE2(printf("[%s] j = %d\n", __func__, j)); 802 803 e1 = E[i - 1][j - 1]; 804 e2 = E[i - 1][j]; 805 e3 = E[i - 1][j + 1]; 806 807 if (e1 || e2 || e3) { 808 // test pour eviter un acces distant 809 r1 = e1 ? FindRoot_Dist(D, e1, alpha) : 0; 810 r2 = e2 ? FindRoot_Dist(D, e2, alpha) : 0; 811 r3 = e3 ? FindRoot_Dist(D, e3, alpha) : 0; 812 813 rx = T[ex]; 814 rx = FindRoot_Dist(D, rx, alpha); 815 816 eps = ui32MinNonNul4(r1, r2, r3, rx); 817 818 MCA_VERBOSE2(printf("\n")); 819 MCA_VERBOSE2(printf("e1 = %5d -> r1 = %5d\n", e1, r1)); 820 MCA_VERBOSE2(printf("e2 = %5d -> r2 = %5d\n", e2, r2)); 821 MCA_VERBOSE2(printf("e3 = %5d -> r3 = %5d\n", e3, r3)); 822 MCA_VERBOSE2(printf("ex = %5d -> rx = %5d\n", ex, rx)); 823 MCA_VERBOSE2(printf("eps = %5d\n", eps)); 824 825 // Quick-Union 826 // @QM 827 if (r1 > eps) { 828 SetRoot_Features_Rosenfeld_Dist(D, r1, eps, alpha, F); 829 MCA_VERBOSE2(printf("D[%5d] <- %d\n", r1, eps)); 830 } 831 if (r2 > 0) { 832 r2 = FindRoot_Dist(D, r2, alpha); 833 } 834 //if (r2 > eps && r2 != r1) { 835 if (r2 > eps) { 836 SetRoot_Features_Rosenfeld_Dist(D, r2, eps, alpha, F); 837 MCA_VERBOSE2(printf("D[%5d] <- %d\n", r2, eps)); 838 } 839 if (r3 > 0) { 840 r3 = FindRoot_Dist(D, r3, alpha); 841 } 842 //if (r3 > eps && r3 != r2 && r3 != r1) { 843 if (r3 > eps) { 844 SetRoot_Features_Rosenfeld_Dist(D, r3, eps, alpha, F); 845 MCA_VERBOSE2(printf("D[%5d] <- %d\n", r3, eps)); 846 } 847 rx = FindRoot_Dist(D, rx, alpha); 848 //if (rx > eps && rx != r3 && rx != r2 && rx != r1) { 849 if (rx > eps) { 850 SetRoot_Features_Rosenfeld_Dist(D, rx, eps, alpha, F); 851 MCA_VERBOSE2(printf("D[%5d] <- %d\n", rx, eps)); 852 } 853 MCA_VERBOSE2(puts("---------------------------\n")); 854 855 // attention SetRoot fait un while inutile 856 } 857 } 858 } 859 860 // -------------- 861 // -- epilogue -- 862 // -------------- 863 864 j = width - 1; 865 ex = E[i][j]; 866 867 if (ex) { 868 869 MCA_VERBOSE2(printf("[%s] j = %d\n", __func__, j)); 870 871 e1 = E[i - 1][j - 1]; 872 e2 = E[i - 1][j]; 873 874 if (e1 || e2) { 875 876 // test pour eviter acces distant 877 r1 = e1 ? FindRoot_Dist(D, e1, alpha) : 0; 878 r2 = e2 ? FindRoot_Dist(D, e2, alpha) : 0; 879 880 rx = T[ex]; 881 rx = FindRoot_Dist(D, rx, alpha); 882 883 eps = ui32MinNonNul3(r1, r2, rx); 884 885 MCA_VERBOSE2(printf("\n")); 886 MCA_VERBOSE2(printf("e1 = %5d -> r1 = %5d\n", e1, r1)); 887 MCA_VERBOSE2(printf("e2 = %5d -> r2 = %5d\n", e2, r2)); 888 MCA_VERBOSE2(printf("ex = %5d -> rx = %5d\n", ex, rx)); 889 MCA_VERBOSE2(printf("eps = %5d\n", eps)); 890 891 // Quick-Union 892 if (r1 > eps) { 893 SetRoot_Features_Rosenfeld_Dist(D, r1, eps, alpha, F); 894 MCA_VERBOSE2(printf("D[%5d] <- %d\n", r1, eps)); 895 } 896 if (r2 > 0) { 897 r2 = FindRoot_Dist(D, r2, alpha); 898 } 899 //if (r2 > eps && r2 != r1) { 900 if (r2 > eps) { 901 SetRoot_Features_Rosenfeld_Dist(D, r2, eps, alpha, F); 902 MCA_VERBOSE2(printf("D[%5d] <- %d\n", r2, eps)); 903 } 904 rx = FindRoot_Dist(D, rx, alpha); 905 //if (rx > eps && rx != r2 && rx != r1) { 906 if (rx > eps) { 907 SetRoot_Features_Rosenfeld_Dist(D, rx, eps, alpha, F); 908 MCA_VERBOSE2(printf("D[%5d] <- %d\n", rx, eps)); 909 } 910 MCA_VERBOSE2(printf("---------------------------\n")); 911 } 912 } 913 return; 914 } 915 #endif // SLOW && FEATURES 916 917 918 #if FAST && FEATURES && !PARMERGE 919 // -------------------------------------------------------------------------------------------------------------------------- 920 void optimizedBorder_Features_Rosenfeld_Dist(uint32 ** E, int i, int j, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 921 // -------------------------------------------------------------------------------------------------------------------------- 922 { 923 // copie de optimizedBorder_Rosenfeld 924 uint32 a, b, c, x; 925 926 x = E[i][j]; 927 928 if (x) { 929 b = E[i - 1][j]; 930 if (b) { 931 vuse2_Features_Rosenfeld_Dist(b, x, T, D, alpha, F); // dist, local 932 } 933 else { 934 c = E[i - 1][j + 1]; 935 if (c) { 936 a = E[i - 1][j - 1]; 937 if (a) { 938 vuse3_Features_Rosenfeld_Dist(a, c, x, T, D, alpha, F); // dist, local 939 } 940 else { 941 vuse2_Features_Rosenfeld_Dist(c, x, T, D, alpha, F); // dist, local 942 } 943 } 944 else { 945 a = E[i - 1][j - 1]; 946 if (a) { 947 vuse2_Features_Rosenfeld_Dist(a, x, T, D, alpha, F); // dist, local 948 } 949 } 950 } 951 } 952 } 953 #endif // FAST && FEATURES && !PARMERGE 954 955 956 #if FAST && FEATURES && !PARMERGE 957 // ------------------------------------------------------------------------------------------------------------------------------ 958 void optimizedBorderLeft_Features_Rosenfeld_Dist(uint32 ** E, int i, int j, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 959 // ------------------------------------------------------------------------------------------------------------------------------ 960 { 961 uint32 x = E[i][j]; 962 963 if (x) { 964 uint32 b = E[i - 1][j]; 965 if (b) { 966 vuse2_Features_Rosenfeld_Dist(b, x, T, D, alpha, F); // dist, local 967 } 968 else { 969 uint32 c = E[i - 1][j + 1]; 970 if (c) { 971 vuse2_Features_Rosenfeld_Dist(c, x, T, D, alpha, F); // dist, local 972 } 973 } 974 } 975 } 976 #endif // FAST && FEATURES && !PARMERGE 977 978 979 #if FAST && FEATURES && !PARMERGE 980 // ------------------------------------------------------------------------------------------------------------------------------- 981 void optimizedBorderRight_Features_Rosenfeld_Dist(uint32 ** E, int i, int j, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 982 // ------------------------------------------------------------------------------------------------------------------------------- 983 { 984 // copie de optimizedBorder_Rosenfeld 985 // test d'existance de ex en local local 986 987 uint32 x = E[i][j]; 988 989 if (x) { 990 uint32 b = E[i - 1][j]; 991 if (b) { 992 vuse2_Features_Rosenfeld_Dist(b, x, T, D, alpha, F); // dist, local 993 } 994 else { 995 uint32 a = E[i - 1][j - 1]; 996 if (a) { 997 vuse2_Features_Rosenfeld_Dist(a, x, T, D, alpha, F); // dist, local 998 } 999 } 1000 } 1001 } 1002 #endif // FAST && FEATURES && !PARMERGE 1003 1004 1005 #if FAST && FEATURES && PARMERGE 1006 // ----------------------------------------------------------------------------------------------------------------------------------- 1007 void optimizedBorder_Parallel_Features_Rosenfeld_Dist(uint32 ** E, int i, int j, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 1008 // ----------------------------------------------------------------------------------------------------------------------------------- 1009 { 1010 // copie de optimizedBorder_Rosenfeld 1011 uint32 a, b, c, x; 1012 1013 x = E[i][j]; 1014 1015 if (x) { 1016 b = E[i - 1][j]; 1017 if (b) { 1018 vuse2_Parallel_Features_Rosenfeld_Dist(b, x, T, D, alpha, F); // dist, local 1019 } 1020 else { 1021 c = E[i - 1][j + 1]; 1022 if (c) { 1023 a = E[i - 1][j - 1]; 1024 if (a) { 1025 vuse3_Parallel_Features_Rosenfeld_Dist(a, c, x, T, D, alpha, F); // dist, local 1026 } 1027 else { 1028 vuse2_Parallel_Features_Rosenfeld_Dist(c, x, T, D, alpha, F); // dist, local 1029 } 1030 } 1031 else { 1032 a = E[i - 1][j - 1]; 1033 if (a) { 1034 vuse2_Parallel_Features_Rosenfeld_Dist(a, x, T, D, alpha, F); // dist, local 1035 } 1036 } 1037 } 1038 } 1039 } 1040 #endif // FAST && FEATURES && PARMERGE 1041 1042 1043 #if FAST && FEATURES && PARMERGE 1044 // --------------------------------------------------------------------------------------------------------------------------------------- 1045 void optimizedBorderLeft_Parallel_Features_Rosenfeld_Dist(uint32 ** E, int i, int j, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 1046 // --------------------------------------------------------------------------------------------------------------------------------------- 1047 { 1048 uint32 x = E[i][j]; 1049 1050 if (x) { 1051 uint32 b = E[i - 1][j]; 1052 if (b) { 1053 vuse2_Parallel_Features_Rosenfeld_Dist(b, x, T, D, alpha, F); // dist, local 1054 } 1055 else { 1056 uint32 c = E[i - 1][j + 1]; 1057 if (c) { 1058 vuse2_Parallel_Features_Rosenfeld_Dist(c, x, T, D, alpha, F); // dist, local 1059 } 1060 } 1061 } 1062 } 1063 #endif // FAST && FEATURES && PARMERGE 1064 1065 1066 #if FAST && FEATURES && PARMERGE 1067 // ---------------------------------------------------------------------------------------------------------------------------------------- 1068 void optimizedBorderRight_Parallel_Features_Rosenfeld_Dist(uint32 ** E, int i, int j, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 1069 // ---------------------------------------------------------------------------------------------------------------------------------------- 1070 { 1071 // copie de optimizedBorder_Rosenfeld 1072 // test d'existance de ex en local local 1073 1074 uint32 x = E[i][j]; 1075 1076 if (x) { 1077 uint32 b = E[i - 1][j]; 1078 if (b) { 1079 vuse2_Parallel_Features_Rosenfeld_Dist(b, x, T, D, alpha, F); // dist, local 1080 } 1081 else { 1082 uint32 a = E[i - 1][j - 1]; 1083 if (a) { 1084 vuse2_Parallel_Features_Rosenfeld_Dist(a, x, T, D, alpha, F); // dist, local 1085 } 1086 } 1087 } 1088 } 1089 #endif // FAST && FEATURES && PARMERGE 1090 1091 1092 #if FAST && FEATURES 1093 // --------------------------------------------------------------------------------------------------------------------------------------------- 1094 void borderMerging_Fast_Features_Rosenfeld_Dist(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 1095 // --------------------------------------------------------------------------------------------------------------------------------------------- 1096 { 1097 MCA_VERBOSE2(printf("[%s]", __func__)); 1098 1099 #if PARMERGE 1100 optimizedBorderLeft_Parallel_Features_Rosenfeld_Dist(E, i, 0, T, D, alpha, F); 1101 #else 1102 optimizedBorderLeft_Features_Rosenfeld_Dist(E, i, 0, T, D, alpha, F); 1103 #endif 1104 1105 for (int j = 1; j < width - 1; j++) { 1106 #if PARMERGE 1107 optimizedBorder_Parallel_Features_Rosenfeld_Dist(E, i, j, T, D, alpha, F); 1108 #else 1109 optimizedBorder_Features_Rosenfeld_Dist(E, i, j, T, D, alpha, F); 1110 #endif 1111 } 1112 1113 #if PARMERGE 1114 optimizedBorderRight_Parallel_Features_Rosenfeld_Dist(E, i, width - 1, T, D, alpha, F); 1115 #else 1116 optimizedBorderRight_Features_Rosenfeld_Dist(E, i, width - 1, T, D, alpha, F); 1117 #endif 1118 } 1119 #endif // FAST && FEATURES 1120 1121 1122 #if !FEATURES 1123 // -------------------------------------------------------------------------------------------------------------------- 1124 static void borderMerging_Rosenfeld_Dist(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ** D, int alpha) 1125 // -------------------------------------------------------------------------------------------------------------------- 1126 { 1127 #if SLOW 501 1128 borderMerging_Slow_Rosenfeld_Dist(X, i, width, E, T, D, alpha); 502 } 503 504 505 // --------------------------------------------------------------------------------------------- 506 uint32 line0Labeling_Rosenfeld(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ne) 507 // --------------------------------------------------------------------------------------------- 1129 #elif FAST 1130 borderMerging_Fast_Rosenfeld_Dist(X, i, width, E, T, D, alpha); 1131 #else 1132 #error "Please define SLOW or FAST for the Rosenfeld version" 1133 #endif 1134 } 1135 #endif // !FEATURES 1136 1137 1138 #if FEATURES 1139 // ----------------------------------------------------------------------------------------------------------------------------------------------- 1140 static void borderMerging_Features_Rosenfeld_Dist(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 1141 // ----------------------------------------------------------------------------------------------------------------------------------------------- 1142 { 1143 #if SLOW 1144 borderMerging_Slow_Features_Rosenfeld_Dist(X, i, width, E, T, D, alpha, F); 1145 #elif FAST 1146 borderMerging_Fast_Features_Rosenfeld_Dist(X, i, width, E, T, D, alpha, F); 1147 #else 1148 #error "Please define SLOW or FAST for the Rosenfeld version" 1149 #endif 1150 } 1151 #endif // FEATURES 1152 1153 1154 // ---------------------------------------------------------------------------------------------------- 1155 static uint32 line0Labeling_Rosenfeld(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ne) 1156 // ---------------------------------------------------------------------------------------------------- 508 1157 { 509 1158 int j; … … 542 1191 543 1192 544 // ------------------------------------------------------------------------------------------------- 545 uint32 lineLabeling_Slow_Rosenfeld(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ne) 546 // ------------------------------------------------------------------------------------------------- 1193 #if SLOW 1194 // -------------------------------------------------------------------------------------------------------- 1195 static uint32 lineLabeling_Slow_Rosenfeld(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ne) 1196 // -------------------------------------------------------------------------------------------------------- 547 1197 { 548 1198 // version lineLabeling_Rosenfeld_UF_QU_8C avec Quick-Union … … 633 1283 634 1284 e = ui32MinNonNul4(r1, r2, r3, r4); 635 giet_pthread_assert(e != 0, "e = 0\n");636 1285 637 1286 // Quick-Union … … 707 1356 return ne; 708 1357 } 709 710 711 // ------------------------------------------------------------------------------------------------- 712 uint32 lineLabeling_Fast_Rosenfeld(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ne) 713 // ------------------------------------------------------------------------------------------------- 714 { 1358 #endif // SLOW 1359 1360 1361 #if FAST 1362 // --------------------------------------------------------------------------------------------- 1363 static uint32 optimizedAccessLeft_DT_Rosenfeld(uint32 ** E, int i, int j, uint32 * T, uint32 ne) 1364 // --------------------------------------------------------------------------------------------- 1365 { 1366 // Decision Tree 8-connexe avec Quick-Union 1367 uint32 b, c, e; 1368 1369 b = E[i - 1][j]; 1370 if (b) { 1371 e = use1_QU_Rosenfeld(b, T); 1372 } 1373 else { 1374 c = E[i - 1][j + 1]; 1375 if (c) { 1376 e = use1_QU_Rosenfeld(c, T); 1377 } 1378 else { 1379 e = ++ne; 1380 } 1381 } 1382 E[i][j] = e; 1383 return ne; 1384 } 1385 #endif // FAST 1386 1387 1388 #if FAST 1389 // ---------------------------------------------------------------------------------------------- 1390 static uint32 optimizedAccessRight_DT_Rosenfeld(uint32 ** E, int i, int j, uint32 * T, uint32 ne) 1391 // ---------------------------------------------------------------------------------------------- 1392 { 1393 // Decision Tree 8-connexe avec Quick-Union 1394 uint32 a, b, d, e; 1395 1396 b = E[i - 1][j]; 1397 if (b) { 1398 e = use1_QU_Rosenfeld(b, T); 1399 } 1400 else { 1401 a = E[i - 1][j - 1]; 1402 if (a) { 1403 e = use1_QU_Rosenfeld(a, T); 1404 } 1405 else { 1406 d = E[i][j - 1]; 1407 if (d) { 1408 e = use1_QU_Rosenfeld(d, T); 1409 } 1410 else { 1411 e = ++ne; 1412 } 1413 } 1414 } 1415 E[i][j] = e; 1416 return ne; 1417 } 1418 #endif // FAST 1419 1420 1421 #if FAST 1422 // ----------------------------------------------------------------------------------------- 1423 static uint32 optimizedAccess_DT_Rosenfeld(uint32 ** E, int i, int j, uint32 * T, uint32 ne) 1424 // ----------------------------------------------------------------------------------------- 1425 { 1426 // Decision Tree 8-connexe avec Quick-Union 1427 uint32 a, b, c, d, e; 1428 1429 b = E[i - 1][j]; 1430 if (b) { 1431 e = use1_QU_Rosenfeld(b, T); 1432 } 1433 else { 1434 c = E[i - 1][j + 1]; 1435 if (c) { 1436 a = E[i - 1][j - 1]; 1437 if (a) { 1438 e = use2_QU_Rosenfeld(a, c, T); 1439 } 1440 else { 1441 d = E[i][j - 1]; 1442 if (d) { 1443 e = use2_QU_Rosenfeld(c, d, T); 1444 } 1445 else { 1446 e = use1_QU_Rosenfeld(c, T); 1447 } 1448 } 1449 } 1450 else { 1451 a = E[i - 1][j - 1]; 1452 if (a) { 1453 e = use1_QU_Rosenfeld(a, T); 1454 } 1455 else { 1456 d = E[i][j - 1]; 1457 if (d) { 1458 e = use1_QU_Rosenfeld(d, T); 1459 } 1460 else { 1461 e = ++ne; 1462 } 1463 } 1464 } 1465 } 1466 E[i][j] = e; 1467 return ne; 1468 } 1469 #endif // FAST 1470 1471 1472 1473 #if FAST 1474 // -------------------------------------------------------------------------------------------------------- 1475 static uint32 lineLabeling_Fast_Rosenfeld(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ne) 1476 // -------------------------------------------------------------------------------------------------------- 1477 { 1478 uint8 x; 715 1479 // avec DT et QU 716 int j; 717 uint8 x; 718 719 for (j = 0; j < width; j++) { 720 x = X[i][j]; 1480 // Left Border 1481 x = X[i][0]; 1482 if (x) { 1483 ne = optimizedAccessLeft_DT_Rosenfeld(E, i, 0, T, ne); 1484 } 1485 else { 1486 E[i][0] = 0; 1487 } 1488 // Middle 1489 for (int j = 1; j < width - 1; j++) { 1490 uint8 x = X[i][j]; 721 1491 if (x) { 722 1492 ne = optimizedAccess_DT_Rosenfeld(E, i, j, T, ne); … … 726 1496 } 727 1497 } 1498 // Right Border 1499 x = X[i][width - 1]; 1500 if (x) { 1501 ne = optimizedAccessRight_DT_Rosenfeld(E, i, width - 1, T, ne); 1502 } 1503 else { 1504 E[i][width - 1] = 0; 1505 } 728 1506 return ne; 729 1507 } 730 731 732 // -------------------------------------------------------------------------------------------- 733 uint32 lineLabeling_Rosenfeld(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ne) 734 // -------------------------------------------------------------------------------------------- 735 { 1508 #endif // FAST 1509 1510 1511 // --------------------------------------------------------------------------------------------------- 1512 static uint32 lineLabeling_Rosenfeld(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ne) 1513 // --------------------------------------------------------------------------------------------------- 1514 { 1515 #if SLOW 736 1516 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 // ---------------------------------------------------------------- 742 uint32 countTable_Range_Rosenfeld(uint32 * T, uint32 e0, uint32 e1) 743 // ---------------------------------------------------------------- 1517 #elif FAST 1518 return lineLabeling_Fast_Rosenfeld(X, i, width, E, T, ne); 1519 #else 1520 #error "Please define SLOW or FAST for the Rosenfeld version" 1521 #endif 1522 } 1523 1524 1525 // ----------------------------------------------------------------------- 1526 static uint32 countTable_Range_Rosenfeld(uint32 * T, uint32 e0, uint32 e1) 1527 // ----------------------------------------------------------------------- 744 1528 { 745 1529 uint32 e; … … 755 1539 756 1540 757 // -------------------------------------------------------------- 758 void solveTable_Range_Rosenfeld(uint32 * T, uint32 e0, uint32 e1) 759 // -------------------------------------------------------------- 1541 #if !FEATURES 1542 // --------------------------------------------------------------------- 1543 static void solveTable_Range_Rosenfeld(uint32 * T, uint32 e0, uint32 e1) 1544 // --------------------------------------------------------------------- 760 1545 { 761 1546 uint32 e, r; … … 766 1551 T[e] = r; // racine de la classe d'equivalence 767 1552 } 768 } 769 } 770 771 1553 } 1554 } 1555 #endif // !FEATURES 1556 1557 1558 #if FEATURES 1559 // ---------------------------------------------------------------------------------------------------------- 1560 static void solveTable_solveFeatures_Range_Rosenfeld(uint32 * T, uint32 e0, uint32 e1, RegionStats * Stats) 1561 // ---------------------------------------------------------------------------------------------------------- 1562 { 1563 uint32 e, r; 1564 1565 for (e = e0; e <= e1; e++) { 1566 r = T[T[e]]; 1567 assert(r != 0); 1568 if (r < e) { 1569 T[e] = r; // racine de la classe d'equivalence 1570 RegionStats_Accumulate_Stats1_From_Index(Stats, r, e); 1571 } 1572 } 1573 } 1574 #endif // FEATURES 1575 1576 1577 #if !FEATURES 772 1578 // ------------------------------------- 773 1579 void MCA_Label_Rosenfeld_PAR1(MCA * mca) … … 775 1581 { 776 1582 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 1583 printf("*** %s ***\n", __func__); 1584 } 1585 1586 CLOCK_THREAD_START_STEP(mca->p, 0); 1587 782 1588 int i0 = mca->i0; 783 1589 int i1 = mca->i1; … … 795 1601 if (mca->p == 0) { 796 1602 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 1603 } 799 1604 else { … … 809 1614 810 1615 MCA_VERBOSE2(display_ui32matrix_positive(E, i0, i1, 0, width - 1, 5, "Ep"); printf("\n")); 811 if (mca->p == 0) { 1616 if (mca->p == 0) { 812 1617 MCA_VERBOSE2(display_ui32vector_number(T, e0, ne, "%5d", "Tp_avant")); 813 1618 } … … 815 1620 // fermeture transitive sans pack 816 1621 solveTable_Range_Rosenfeld(T, e0, ne); 817 nr = countTable_Range_Rosenfeld(T, e0, ne);818 1622 mca->ne = ne; // Plus grande etiquette de l'intervalle [e0..e1] 819 1623 1624 MCA_VERBOSE2(nr = countTable_Range_Rosenfeld(T, e0, ne)); 820 1625 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) { 1626 if (mca->p == 0) { 822 1627 MCA_VERBOSE2(display_ui32vector_number(T, e0, ne, "%5d", "Tp_apres")); 823 1628 } 824 } 825 826 1629 1630 CLOCK_THREAD_END_STEP(mca->p, 0); 1631 } 1632 #endif // !FEATURES 1633 1634 1635 #if !FEATURES 827 1636 // ------------------------------------- 828 1637 void MCA_Label_Rosenfeld_PYR2(MCA * mca) … … 830 1639 { 831 1640 // 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 } 1641 int p = mca->p; 1642 int nb_level = mca->nb_level; 840 1643 841 1644 if (mca->p == 0) { 842 MCA_VERBOSE1(printf("------------------------------\n")); 843 MCA_VERBOSE1(printf("-- MCA_Label_Rosenfeld_PYR2 --\n")); 844 MCA_VERBOSE1(printf("------------------------------\n")); 1645 printf("*** %s ***\n", __func__); 845 1646 } 846 1647 … … 862 1663 uint32 ** D = mca->D; 863 1664 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 1665 CLOCK_THREAD_START_STEP(p, 1); 1666 #if PYR_BARRIERS 1667 // Version optimisée qui fait faire un break aux processeurs qui n'ont plus 1668 // à faire de merge. 1669 // Implique de pré-calculer le nombre de threads à chaque barriÚre 1670 if (p != 0) { // thread 0 never has any merge to do 1671 int been_active = 0; 1672 for (int level = 0; level < nb_level; level++) { 1673 if ((p + (1 << level)) % (1 << (level + 1)) == 0) { 1674 borderMerging_Rosenfeld_Dist(X, i, width, E, T, D, alpha); // en (i) et (i-1) 1675 been_active = 1; 1676 } 1677 else if (been_active) { 1678 break; 1679 } 1680 pthread_barrier_wait(&mca->barriers[level]); 1681 } 1682 } 1683 pthread_barrier_wait(&main_barrier); 1684 #else 875 1685 for (int level = 1; level <= nb_level; level++) { 876 if (( mca->p + (1 << (level - 1))) % (1 << level) == 0) {1686 if ((p + (1 << (level - 1))) % (1 << level) == 0) { 877 1687 // thread actif 878 //MCA_VERBOSE1(printf("### level = %d - p = %d\n", level, mca->p));879 1688 borderMerging_Rosenfeld_Dist(X, i, width, E, T, D, alpha); // en (i) et (i-1) 880 1689 } 881 barrier_wait(&main_barrier); 882 } 1690 pthread_barrier_wait(&main_barrier); 1691 } 1692 #endif 1693 CLOCK_THREAD_END_STEP(p, 1); 883 1694 884 1695 … … 887 1698 // --------------------------------- 888 1699 1700 CLOCK_THREAD_START_STEP(p, 2); 889 1701 for (uint32 e = e0; e <= e1; e++) { 890 1702 uint32 r = T[e]; // acces local 891 1703 if (r < e) { 892 1704 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 } 1705 T[e] = r; // @QM était en dehors du "if" (je pense que déjà demandé) 1706 } 1707 MCA_VERBOSE2(printf("p%d : T[%d] <- %d\n", p, e, r)); 1708 } 1709 CLOCK_THREAD_END_STEP(p, 2); 1710 } 1711 #endif // !FEATURES 898 1712 899 1713 … … 904 1718 // input 905 1719 if (mca->p == 0) { 906 MCA_VERBOSE1(printf("------------------------------\n")); 907 MCA_VERBOSE1(printf("-- MCA_Label_Rosenfeld_PAR3 --\n")); 908 MCA_VERBOSE1(printf("------------------------------\n")); 1720 printf("*** %s ***\n", __func__); 909 1721 } 910 1722 … … 917 1729 uint32 * T = mca->T; 918 1730 1731 CLOCK_THREAD_START_STEP(mca->p, 3); 919 1732 for (int i = i0; i <= i1; i++) { 920 1733 for (int j = j0; j <= j1; j++) { … … 925 1738 } 926 1739 } 927 } 928 929 1740 CLOCK_THREAD_END_STEP(mca->p, 3); 1741 } 1742 1743 1744 #if FEATURES 1745 // ----------------------------------------------------- 1746 static void MCA_Label_Features_Rosenfeld_PAR1(MCA * mca) 1747 // ----------------------------------------------------- 1748 { 1749 if (mca->p == 0) { 1750 printf("*** %s ***\n", __func__); 1751 } 1752 1753 CLOCK_THREAD_START_STEP(mca->p, 0); 1754 1755 int i0 = mca->i0; 1756 int i1 = mca->i1; 1757 int width = mca->width; 1758 1759 uint32 e0 = mca->e0; 1760 uint32 e1 = mca->e1; 1761 uint32 ne = e0 - 1; 1762 uint32 nr = 0; 1763 1764 // local memory zones 1765 uint8 ** X = mca->X; 1766 uint32 ** E = mca->E; 1767 uint32 * T = mca->T; 1768 1769 RegionStats * stats = mca->stats; 1770 1771 // reset sous optimal (pour le moment = voir region32) 1772 if (mca->p == 0) { 1773 set_ui32vector_j(T, e0 - 1, e1); // car e0 = 1, on a besoin que T[0] = 0 pour FindRoot 1774 zero_RegionStatsVector(stats, e0 - 1, e1); 1775 } 1776 else { 1777 set_ui32vector_j(T, e0, e1); 1778 zero_RegionStatsVector(stats, e0, e1); 1779 } 1780 1781 if (mca->p == 0) { 1782 MCA_DISPLAY2(display_ui8matrix_positive(X, i0, i1, 0, width - 1, 5, "Xp"); printf("\n")); 1783 } 1784 1785 // ---------------------------- // 1786 // -- Etiquetage d'une bande -- // 1787 // ---------------------------- // 1788 1789 ne = line0Labeling_Rosenfeld(X, i0, width, E, T, ne); 1790 lineFeaturesComputation(E, i0, width, stats); 1791 1792 for (int i = i0 + 1; i <= i1; i++) { 1793 ne = lineLabeling_Rosenfeld(X, i, width, E, T, ne); // Slow or Fast 1794 lineFeaturesComputation(E, i, width, stats); 1795 } 1796 mca->ne = ne; //plus grande etiquette de l'intervalle [e0..e1] 1797 1798 if (mca->p == 0) { 1799 MCA_VERBOSE2(printf("ne = %d\n", ne)); 1800 MCA_DISPLAY2(display_ui32matrix_positive(E, i0, i1, 0, width - 1, 5, "Ep"); printf("\n")); 1801 MCA_DISPLAY2(display_ui32vector_number(T, e0, ne, "%5d", "Tp_avant")); 1802 } 1803 1804 // ------------------------------------------------------ // 1805 // -- Fermeture transitive sans pack de chaque table T -- // 1806 // ------------------------------------------------------ // 1807 1808 solveTable_solveFeatures_Range_Rosenfeld(T, e0, ne, stats); 1809 1810 if (mca->p == 0) { 1811 MCA_VERBOSE2(nr = countTable_Range_Rosenfeld(T, e0, ne); 1812 printf("p = %d : e = [%d..%d] -> ne = %d -> nr = %d\n", mca->p, e0, ne, (ne - e0 + 1), nr)); 1813 MCA_DISPLAY2(display_ui32vector_number(T, e0, ne, "%5d", "Tp_apres")); 1814 } 1815 CLOCK_THREAD_END_STEP(mca->p, 0); 1816 } 1817 #endif // FEATURES 1818 1819 1820 #if FEATURES && !PARMERGE 1821 // ----------------------------------------------------- 1822 static void MCA_Label_Features_Rosenfeld_PYR2(MCA * mca) 1823 // ----------------------------------------------------- 1824 { 1825 int p = mca->p; 1826 int nb_level = mca->nb_level; 1827 1828 if (mca->p == 0) { 1829 printf("*** %s ***\n", __func__); 1830 } 1831 1832 // ------------------------------ 1833 // -- pyramidal border merging -- 1834 // ------------------------------ 1835 1836 // local variables 1837 int i = mca->i0; 1838 int width = mca->width; 1839 int alpha = mca->alpha; 1840 uint32 e0 = mca->e0; 1841 uint32 e1 = mca->ne; 1842 1843 // local memory zones 1844 uint8 ** X = mca->X; 1845 uint32 ** E = mca->E; 1846 uint32 * T = mca->T; 1847 uint32 ** D = mca->D; 1848 RegionStats ** F = mca->F; 1849 1850 CLOCK_THREAD_START_STEP(p, 1); 1851 #if PYR_BARRIERS 1852 // Version optimisée qui fait faire un break aux processeurs qui n'ont plus 1853 // à faire de merge. 1854 // Implique de pré-calculer le nombre de threads à chaque barriÚre 1855 if (p != 0) { // thread 0 never has any merge to do 1856 int been_active = 0; 1857 for (int level = 0; level < nb_level; level++) { 1858 if ((p + (1 << level)) % (1 << (level + 1)) == 0) { 1859 borderMerging_Features_Rosenfeld_Dist(X, i, width, E, T, D, alpha, F); // (i) et (i-1) 1860 been_active = 1; 1861 } 1862 else if (been_active) { 1863 break; 1864 } 1865 pthread_barrier_wait(&mca->barriers[level]); 1866 } 1867 } 1868 pthread_barrier_wait(&main_barrier); 1869 #else 1870 for (int level = 1; level <= nb_level; level++) { 1871 if ((p + (1 << (level - 1))) % (1 << level) == 0) { 1872 // thread actif 1873 borderMerging_Features_Rosenfeld_Dist(X, i, width, E, T, D, alpha, F); // (i) et (i-1) 1874 } 1875 pthread_barrier_wait(&main_barrier); 1876 } 1877 #endif 1878 CLOCK_THREAD_END_STEP(p, 1); 1879 1880 1881 /** 1882 * To remove? 1883 // -- Affichage de debug 1884 if (mca->p == 0) { 1885 MCA_VERBOSE1(puts("-----------------------------")); 1886 MCA_VERBOSE1(puts("[PYR2]: avant pack sequentiel")); 1887 MCA_VERBOSE1(puts("-----------------------------")); 1888 1889 for (int p = 0; p < mca->np; p++) { 1890 1891 MCA* mca_par = mcas[p]; 1892 uint32 e0 = mca_par->e0; 1893 uint32 e1 = mca_par->ne; 1894 1895 uint32* T = mca_par->T; 1896 RegionStats* Stats = mca_par->Stats; 1897 1898 RegionStats_DisplayStats_Sparse(T, e0, e1, Stats, NULL); 1899 puts(""); 1900 } 1901 } 1902 */ 1903 1904 // --------------------------------- 1905 // -- parallel transitive closure -- 1906 // --------------------------------- 1907 // identique a la version sans Features 1908 1909 CLOCK_THREAD_START_STEP(p, 2); 1910 for (uint32 e = e0; e <= e1; e++) { 1911 uint32 r = T[e]; // acces local 1912 if (r < e) { 1913 r = FindRoot_Dist(D, e, alpha); // acces distant 1914 T[e] = r; 1915 } 1916 MCA_VERBOSE2(printf("p%d : T[%d] <- %d\n", p, e, r)); 1917 } 1918 CLOCK_THREAD_END_STEP(p, 2); 1919 1920 // To avoid uninitialized accesses 1921 CLOCK_THREAD_START_STEP(p, 3); 1922 CLOCK_THREAD_END_STEP(p, 3); 1923 } 1924 #endif // FEATURES && !PARMERGE 1925 1926 1927 #if FEATURES && PARMERGE 1928 // ----------------------------------------------------- 1929 static void MCA_Label_Features_Rosenfeld_PAR2(MCA * mca) 1930 // ----------------------------------------------------- 1931 { 1932 int p = mca->p; 1933 int nb_level = mca->nb_level; 1934 1935 if (mca->p == 0) { 1936 printf("*** %s ***\n", __func__); 1937 } 1938 1939 // ------------------------------ 1940 // -- parallel border merging -- 1941 // ------------------------------ 1942 1943 // local variables 1944 int i = mca->i0; 1945 int width = mca->width; 1946 int alpha = mca->alpha; 1947 uint32 e0 = mca->e0; 1948 uint32 e1 = mca->ne; 1949 1950 // local memory zones 1951 uint8 ** X = mca->X; 1952 uint32 ** E = mca->E; 1953 uint32 * T = mca->T; 1954 uint32 ** D = mca->D; 1955 RegionStats ** F = mca->F; 1956 1957 CLOCK_THREAD_START_STEP(p, 1); 1958 if (p != 0) { // thread 0 never has any merge to do 1959 borderMerging_Features_Rosenfeld_Dist(X, i, width, E, T, D, alpha, F); // (i) et (i-1) 1960 } 1961 pthread_barrier_wait(&main_barrier); 1962 CLOCK_THREAD_END_STEP(p, 1); 1963 1964 1965 // --------------------------------- 1966 // -- parallel transitive closure -- 1967 // --------------------------------- 1968 // identique a la version sans Features 1969 1970 CLOCK_THREAD_START_STEP(p, 2); 1971 for (uint32 e = e0; e <= e1; e++) { 1972 uint32 r = T[e]; // acces local 1973 if (r < e) { 1974 r = FindRoot_Dist(D, e, alpha); // acces distant 1975 T[e] = r; 1976 } 1977 MCA_VERBOSE2(printf("p%d : T[%d] <- %d\n", p, e, r)); 1978 } 1979 CLOCK_THREAD_END_STEP(p, 2); 1980 1981 // To avoid uninitialized accesses 1982 CLOCK_THREAD_START_STEP(p, 3); 1983 CLOCK_THREAD_END_STEP(p, 3); 1984 } 1985 #endif // FEATURES 1986 1987 1988 1989 1990 #if !FEATURES 930 1991 // ============================================================= 1992 #if TARGET_OS == GIETVM 931 1993 __attribute__((constructor)) void MCA_Label_Rosenfeld(MCA * mca) 1994 #else 1995 void MCA_Label_Rosenfeld(MCA * mca) 1996 #endif 932 1997 // ============================================================= 933 1998 { 1999 #if TARGET_OS == GIETVM 2000 unsigned int x, y, lpid; 2001 giet_proc_xyp(&x, &y, &lpid); 2002 // Mettre à jour mca->p en fonction de x, y, lpid 2003 // pour que les allocations faites par le main soient locales, 2004 // i.e. 2005 mca->p = (x * Y_SIZE + y) * NB_PROCS_MAX + lpid; 2006 // We have : 2007 // mca->p = 4 pour (x = 0, y = 1, lpid = 0) 2008 // mca->p = 5 pour (x = 0, y = 1, lpid = 1) 2009 MCA_VERBOSE2(printf("mca->p = %d pour (x = %d, y = %d, lpid = %d)\n", mca->p, x, y, lpid)); 2010 #endif 2011 2012 CLOCK_THREAD_START(mca->p); 2013 CLOCK_THREAD_COMPUTE_START(mca->p); 2014 934 2015 MCA_Scatter_ImageX(mca); 935 barrier_wait(&main_barrier);2016 pthread_barrier_wait(&main_barrier); 936 2017 937 2018 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); 2019 pthread_barrier_wait(&main_barrier); 2020 946 2021 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); 2022 pthread_barrier_wait(&main_barrier); 950 2023 951 2024 MCA_Label_Rosenfeld_PAR3(mca); 952 barrier_wait(&main_barrier);2025 pthread_barrier_wait(&main_barrier); 953 2026 954 2027 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 2028 pthread_barrier_wait(&main_barrier); 2029 2030 CLOCK_THREAD_COMPUTE_END(mca->p); 2031 CLOCK_THREAD_END(mca->p); 2032 2033 #if TARGET_OS == GIETVM 959 2034 if (mca->p != 0) { 960 giet_pthread_exit(NULL); 961 } 962 } 2035 exit(0); 2036 } 2037 #endif 2038 } 2039 #endif // !FEATURES 2040 2041 2042 #if FEATURES 2043 // ====================================================================== 2044 #if TARGET_OS == GIETVM 2045 __attribute__((constructor)) void * MCA_Label_Features_Rosenfeld(void * arg) 2046 #else 2047 void * MCA_Label_Features_Rosenfeld(void * arg) 2048 #endif 2049 // ====================================================================== 2050 { 2051 MCA * mca = (MCA *) arg; 2052 #if TARGET_OS == GIETVM 2053 unsigned int x, y, lpid; 2054 giet_proc_xyp(&x, &y, &lpid); 2055 // Mettre à jour mca->p en fonction de x, y, lpid 2056 // pour que les allocations faites par le main soient locales, 2057 // i.e. 2058 mca->p = (x * Y_SIZE + y) * NB_PROCS_MAX + lpid; 2059 // We have : 2060 // mca->p = 4 pour (x = 0, y = 1, lpid = 0) 2061 // mca->p = 5 pour (x = 0, y = 1, lpid = 1) 2062 MCA_VERBOSE2(printf("mca->p = %d pour (x = %d, y = %d, lpid = %d)\n", mca->p, x, y, lpid)); 2063 #endif 2064 2065 CLOCK_THREAD_START(mca->p); 2066 CLOCK_THREAD_COMPUTE_START(mca->p); 2067 2068 MCA_Scatter_ImageX(mca); 2069 pthread_barrier_wait(&main_barrier); 2070 2071 MCA_Label_Features_Rosenfeld_PAR1(mca); 2072 pthread_barrier_wait(&main_barrier); 2073 2074 #if PARMERGE 2075 MCA_Label_Features_Rosenfeld_PAR2(mca); 2076 #else 2077 MCA_Label_Features_Rosenfeld_PYR2(mca); 2078 #endif 2079 pthread_barrier_wait(&main_barrier); 2080 2081 MCA_Label_Rosenfeld_PAR3(mca); 2082 pthread_barrier_wait(&main_barrier); 2083 2084 MCA_Gather_ImageL(mca); 2085 pthread_barrier_wait(&main_barrier); 2086 2087 CLOCK_THREAD_COMPUTE_END(mca->p); 2088 2089 if (display_features) { 2090 if (mca->p == 0) { 2091 int i = 1; 2092 printf("[STATS]\n"); 2093 for (int p = 0; p < mca->np; p++) { 2094 MCA * mca_par = mca->mca->mcas[p]; 2095 uint32 e0 = mca_par->e0; 2096 uint32 ne = mca_par->ne - mca_par->e0; // number of elements 2097 uint32 * T = mca_par->T; 2098 RegionStats * stats = mca_par->stats; 2099 RegionStats_DisplayStats_Sparse(T, e0, e0 + ne, stats, NULL, &i); 2100 } 2101 printf("[/STATS]\n"); 2102 } 2103 } 2104 2105 CLOCK_THREAD_END(mca->p); 2106 2107 #if TARGET_OS == GIETVM 2108 if (mca->p != 0) { 2109 exit(0); 2110 } 2111 #endif 2112 2113 return NULL; 2114 } 2115 #endif // FEATURES 2116 963 2117 964 2118 // Local Variables:
Note: See TracChangeset
for help on using the changeset viewer.