Changeset 822 for soft/giet_vm/applications/rosenfeld/src-par
- Timestamp:
- Jun 1, 2016, 10:25:43 AM (8 years ago)
- Location:
- soft/giet_vm/applications/rosenfeld/src-par
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/applications/rosenfeld/src-par/mca.c
r821 r822 42 42 { 43 43 printf("MCA ERROR: %s\n", msg); 44 printf("now exiting to system...\n");45 44 exit(1); 46 45 } … … 164 163 MCA * mca_par; 165 164 166 printf("*** %s ***\n", __func__);167 MCA_VERBOSE 1(printf(" height = %d\n", height));168 MCA_VERBOSE 1(printf(" width = %d\n", width));165 MCA_VERBOSE1(printf("*** %s ***\n", __func__)); 166 MCA_VERBOSE2(printf(" height = %d\n", height)); 167 MCA_VERBOSE2(printf(" width = %d\n", width)); 169 168 170 169 // array of pointers to mca workers … … 179 178 height_mod = height % np; 180 179 181 MCA_VERBOSE 1(printf(" height_par = %d x %d + %d\n", height_par, np, height_mod));182 MCA_VERBOSE 1(printf(" ========================\n"));180 MCA_VERBOSE2(printf(" height_par = %d x %d + %d\n", height_par, np, height_mod)); 181 MCA_VERBOSE2(printf(" ========================\n")); 183 182 184 183 i1_par_previous = 0; … … 186 185 // puissance de 2 de chaque bande 187 186 ne_par = height_par * width + 1; 188 MCA_VERBOSE 1(printf(" ne_par = %d\n", ne_par));187 MCA_VERBOSE2(printf(" ne_par = %d\n", ne_par)); 189 188 pw2 = i32log2(ne_par); 190 189 if (ne_par > (1 << pw2)) { … … 192 191 } 193 192 nemax_par = 1 << pw2; 194 195 MCA_VERBOSE1(printf(" nemax_par = %d\n", nemax_par)); 193 mca->alpha = pw2; 194 195 MCA_VERBOSE2(printf(" nemax_par = %d\n", nemax_par)); 196 196 197 197 nb_level = i32log2(np); … … 230 230 // -- constructor -- // 231 231 // ----------------- // 232 MCA_VERBOSE 2(printf("-- p = %d ----------------\n", p));232 MCA_VERBOSE3(printf("-- p = %d ----------------\n", p)); 233 233 234 234 // alloc of mca workers into array of pointers … … 245 245 x = (p / NB_PROCS_MAX) / Y_SIZE; 246 246 y = (p / NB_PROCS_MAX) % Y_SIZE; 247 MCA_VERBOSE 2(printf("p = %d (x = %d, y = %d)\n", p, x, y));247 MCA_VERBOSE3(printf("p = %d (x = %d, y = %d)\n", p, x, y)); 248 248 #endif 249 249 … … 268 268 i1_par_previous = i1_par; 269 269 270 MCA_VERBOSE 2(printf("i0_par = %d\n", i0_par));271 MCA_VERBOSE 2(printf("i1_par = %d\n", i1_par));270 MCA_VERBOSE3(printf("i0_par = %d\n", i0_par)); 271 MCA_VERBOSE3(printf("i1_par = %d\n", i1_par)); 272 272 273 273 // etiquettes … … 281 281 } 282 282 283 MCA_VERBOSE 2(printf("e0_par = %d\n", e0_par));284 MCA_VERBOSE 2(printf("e1_par = %d\n", e1_par));283 MCA_VERBOSE3(printf("e0_par = %d\n", e0_par)); 284 MCA_VERBOSE3(printf("e1_par = %d\n", e1_par)); 285 285 286 286 mca_par->width = width; … … 313 313 if (p == 0) { 314 314 mca_par->T = remote_ui32vector(e0_par - 1, e1_par, x, y); // car e0 = 1, on a besoin que T[0] = 0 pour FindRoot 315 #if FEATURES316 315 mca_par->stats = remote_RegionStatsVector(e0_par - 1, e1_par, x, y); 317 #endif318 316 } 319 317 else { 320 318 mca_par->T = remote_ui32vector(e0_par, e1_par, x, y); 321 #if FEATURES322 319 mca_par->stats = remote_RegionStatsVector(e0_par, e1_par, x, y); 323 #endif324 320 } 325 321 326 322 mca_par->D = (uint32 **) remote_vvector(0, np - 1, x, y); 327 #if FEATURES328 323 mca_par->F = (RegionStats **) remote_vvector(0, np - 1, x, y); 329 #endif330 324 #else // !GIETVM 331 325 mca_par->X = ui8matrix (i0_par, i1_par, 0, width - 1); … … 334 328 if (p == 0) { 335 329 mca_par->T = ui32vector(e0_par - 1, e1_par); // car e0 = 1, on a besoin que T[0] = 0 pour FindRoot 336 #if FEATURES337 330 mca_par->stats = RegionStatsVector(e0_par - 1, e1_par); 338 339 #endif340 331 } 341 332 else { 342 333 mca_par->T = ui32vector(e0_par, e1_par); 343 #if FEATURES344 334 mca_par->stats = RegionStatsVector(e0_par, e1_par); 345 #endif346 335 } 347 336 348 337 mca_par->D = (uint32 **) vvector(0, np - 1); 349 #if FEATURES350 338 mca_par->F = (RegionStats **) vvector(0, np - 1); 351 #endif352 339 #endif 353 MCA_VERBOSE 2(printf("X = %p\n", mca_par->X));354 MCA_VERBOSE 2(printf("E = %p\n", mca_par->E));355 MCA_VERBOSE 2(printf("T = %p\n", mca_par->T));356 MCA_VERBOSE 2(printf("D = %p\n", mca_par->D));340 MCA_VERBOSE3(printf("X = %p\n", mca_par->X)); 341 MCA_VERBOSE3(printf("E = %p\n", mca_par->E)); 342 MCA_VERBOSE3(printf("T = %p\n", mca_par->T)); 343 MCA_VERBOSE3(printf("D = %p\n", mca_par->D)); 357 344 } // p 358 345 … … 365 352 uint32 e1 = mca_par->e1; 366 353 367 MCA_VERBOSE 2(printf("p = %d T[%d..%d]\n", p, e0, e1));354 MCA_VERBOSE3(printf("p = %d T[%d..%d]\n", p, e0, e1)); 368 355 if (p == 0) { 369 356 set_ui32vector_j(T, e0 - 1, e1); // car e0 = 1, on a besoin que T[0] = 0 pour FindRoot … … 372 359 set_ui32vector_j(T, e0, e1); 373 360 } 374 MCA_VERBOSE 2(printf("\n"));375 } 376 377 MCA_VERBOSE 2(printf("display des tables d'EQ\n"));361 MCA_VERBOSE3(printf("\n")); 362 } 363 364 MCA_VERBOSE3(printf("display des tables d'EQ\n")); 378 365 for (int p = 0; p < np; p++) { 379 366 MCA * mca_par = mcas[p]; … … 383 370 uint32 e1 = mca_par->e1; 384 371 385 MCA_VERBOSE 2(printf("p = %d T[%d..%d]\n", p, e0, e1));386 if (p == 0) { 387 MCA_VERBOSE 2(display_ui32vector_number(T, e0 - 1, e0 + 10, "%5d", "T"));388 } 389 else { 390 MCA_VERBOSE 2(display_ui32vector_number(T, e0, e0 + 10, "%5d", "T"));391 } 392 MCA_VERBOSE 2(printf("\n"));372 MCA_VERBOSE3(printf("p = %d T[%d..%d]\n", p, e0, e1)); 373 if (p == 0) { 374 MCA_VERBOSE3(display_ui32vector_number(T, e0 - 1, e0 + 10, "%5d", "T")); 375 } 376 else { 377 MCA_VERBOSE3(display_ui32vector_number(T, e0, e0 + 10, "%5d", "T")); 378 } 379 MCA_VERBOSE3(printf("\n")); 393 380 } 394 381 //exit(-1); … … 399 386 400 387 // table d'indirection distribuee D 401 MCA_VERBOSE 2(printf("nemax_par = %d\n", nemax_par));388 MCA_VERBOSE3(printf("nemax_par = %d\n", nemax_par)); 402 389 for (int p = 0; p < np; p++) { 403 390 MCA * mca_p = mcas[p]; … … 409 396 uint32 * T = mca_k->T; 410 397 D[k] = T + k * nemax_par; // il faut soustraire le "MSB" 411 #if FEATURES412 398 RegionStats * stat = mca_k->stats; 413 399 F[k] = stat + k * nemax_par; // il faut soustraire le "MSB" 414 #endif415 400 } // k 416 401 } // p 417 402 418 MCA_VERBOSE 2(printf("table d'indirection distribuee D\n"));419 420 for (int p = 0; p < np; p++) { 421 MCA_VERBOSE 2(printf("== p = %d ==========\n", p));403 MCA_VERBOSE3(printf("table d'indirection distribuee D\n")); 404 405 for (int p = 0; p < np; p++) { 406 MCA_VERBOSE3(printf("== p = %d ==========\n", p)); 422 407 423 408 MCA * mca_p = mcas[p]; … … 430 415 uint32 e0 = mca_k->e0; 431 416 uint32 e1 = mca_k->e1; 432 MCA_VERBOSE2(display_ui32vector_number(T, e0, e0 + 9, "%5d", "T")); 433 MCA_VERBOSE2(display_ui32vector(D[k], 0, 9, "%5d", "D\n")); 434 } 435 MCA_VERBOSE2(printf("\n")); 436 } 437 438 /**/ 439 //exit(-1); 440 441 //printf("[MCA_Initialize] positionnement des pointeurs de lignes (i0-1) et (i1+1)"); 442 443 for (int p = 0; p < np; p++) { 444 445 //printf(" --p = %d ------------------\n", p); 446 // cas general 447 417 MCA_VERBOSE3(display_ui32vector_number(T, e0, e0 + 9, "%5d", "T")); 418 MCA_VERBOSE3(display_ui32vector(D[k], 0, 9, "%5d", "D\n")); 419 } 420 MCA_VERBOSE3(printf("\n")); 421 } 422 423 for (int p = 0; p < np; p++) { 448 424 if (p > 0) { 449 425 //printf("i0_(%d) = %d i1_{%d} = %d\n", p, mcas[p]->i0, p-1, mcas[p-1]->i1); … … 476 452 (void) mca_par; 477 453 478 printf("*** MCA_Display_Parameters ***\n");479 480 MCA_VERBOSE 1(printf(" height = %d\n", mca->height));481 MCA_VERBOSE 1(printf(" width = %d\n", mca->width));482 MCA_VERBOSE 1(printf(" np = %d\n", mca->np));454 MCA_VERBOSE1(printf("*** MCA_Display_Parameters ***\n")); 455 456 MCA_VERBOSE2(printf(" height = %d\n", mca->height)); 457 MCA_VERBOSE2(printf(" width = %d\n", mca->width)); 458 MCA_VERBOSE2(printf(" np = %d\n", mca->np)); 483 459 484 460 for (int p = 0; p < np; p++) { 485 461 mca_par = mcas[p]; 486 462 487 MCA_VERBOSE 2(printf("Display MCA[%d]\n", p));488 MCA_VERBOSE 2(printf("p = %d\n", mca_par->p));489 MCA_VERBOSE 2(printf("i0 = %8d i1 = %8d\n", mca_par->i0, mca_par->i1));490 MCA_VERBOSE 2(printf("j0 = %8d j1 = %8d\n", mca_par->j0, mca_par->j1));491 MCA_VERBOSE 2(printf("e0 = %8d e1 = %8d\n", mca_par->e0, mca_par->e1));463 MCA_VERBOSE3(printf("Display MCA[%d]\n", p)); 464 MCA_VERBOSE3(printf("p = %d\n", mca_par->p)); 465 MCA_VERBOSE3(printf("i0 = %8d i1 = %8d\n", mca_par->i0, mca_par->i1)); 466 MCA_VERBOSE3(printf("j0 = %8d j1 = %8d\n", mca_par->j0, mca_par->j1)); 467 MCA_VERBOSE3(printf("e0 = %8d e1 = %8d\n", mca_par->e0, mca_par->e1)); 492 468 } 493 469 } … … 507 483 uint32 e0, e1; 508 484 509 printf("*** MCA_Finalize ***\n");485 MCA_VERBOSE1(printf("*** MCA_Finalize ***\n")); 510 486 511 487 #if PYR_BARRIERS … … 532 508 if (p == 0) { 533 509 free_ui32vector(mca_par->T, e0 - 1, e1); // car e0 = 1, on a besoin que T[0] = 0 pour FindRoot 534 #if FEATURES535 510 free_RegionStatsVector(mca_par->stats, e0 - 1, e1); 536 #endif537 511 } 538 512 else { 539 513 free_ui32vector(mca_par->T, e0, e1); 540 #if FEATURES541 514 free_RegionStatsVector(mca_par->stats, e0, e1); 542 #endif543 515 } 544 516 545 517 free_vvector((void **) mca_par->D, 0, np - 1); 546 #if FEATURES547 518 free_vvector((void **) mca_par->F, 0, np - 1); 548 #endif549 519 free(mca_par); 550 520 } … … 564 534 565 535 if (mca->p == 0) { 566 printf("*** MCA_Scatter_ImageX ***\n");536 MCA_VERBOSE1(printf("*** MCA_Scatter_ImageX ***\n")); 567 537 } 568 538 … … 593 563 594 564 if (mca->p == 0) { 595 printf("*** MCA_Gather_ImageL ***\n");565 MCA_VERBOSE1(printf("*** MCA_Gather_ImageL ***\n")); 596 566 } 597 567 -
soft/giet_vm/applications/rosenfeld/src-par/mca_main.c
r821 r822 126 126 127 127 128 // QM : The cost of this function is horrible129 // but it is only for testing purpose130 128 // Renumbers object in a contiguous way, for an image which has already 131 129 // been processed with several threads 132 // ------------------------------------------------------------------ --133 static void renumber_image( uint32 ** E, int i0, int i1, int j0, int j1)134 // ------------------------------------------------------------------ --135 { 136 int size = 10;137 int idx = 1; // next label to give, first invalid index in the equiv table138 uint32 * equiv = malloc(sizeof(uint32) * size);139 equiv[0] = 0; // unused 140 int found;141 142 for (int i = i0; i <= i1; i++) {143 for (int j = j0; j <= j1; j++) {144 if (E[i][j] != 0) {145 found = 0;146 for (int k = 1; k < idx; k++) {147 if (equiv[k] == E[i][j]) {148 E[i][j] = k;149 found = 1;150 break;151 }152 }153 if (found == 0) {154 equiv[idx] = E[i][j];155 E[i][j] = idx;156 idx += 1;157 if (idx == size) {158 size = size * 2;159 equiv = realloc(equiv, sizeof(uint32) * size);160 }161 }130 // ------------------------------------------------------------------ 131 static void renumber_image(MCA * mca, int i0, int i1, int j0, int j1) 132 // ------------------------------------------------------------------ 133 { 134 int32_t na = 0; 135 uint32_t ** E = mca->E; 136 uint32_t ** D = mca->mcas[0]->D; 137 138 uint32_t shift = mca->alpha; 139 uint32_t mask = (1 << shift) - 1; 140 141 for (int32_t p = 0; p < mca->np; p++) { 142 MCA * mca_par = mca->mcas[p]; 143 uint32 * T = mca_par->T; 144 for (uint32_t e = mca_par->e0; e <= mca_par->ne; e++) { 145 if (T[e] != e) { 146 // FindRoot_Dist 147 uint32_t r = T[e]; 148 uint32_t a = e; 149 do { 150 uint32_t e1 = r >> shift; 151 uint32_t e0 = r & mask; 152 a = r; 153 r = D[e1][e0]; 154 } while (r < a); 155 T[e] = r; 156 } 157 else { 158 na += 1; 159 T[e] = na; 162 160 } 163 161 } 164 162 } 165 free(equiv); 163 164 for (int32_t i = i0; i <= i1; i++) { 165 for (int32_t j = j0; j <= j1; j++) { 166 if (E[i][j] != 0) { 167 uint32_t e0 = E[i][j] & mask; 168 uint32_t e1 = E[i][j] >> shift; 169 E[i][j] = D[e1][e0]; 170 } 171 } 172 } 166 173 } 167 174 … … 203 210 204 211 display_ui8matrix_positive(mca->X, i0, i1, j0, j1, 5, "X0"); 205 #if FEATURES206 for (int i = 1; i < num_threads; i++) {207 pthread_create(&thread_table[i], NULL, MCA_Label_Features_Rosenfeld, (void *) mca->mcas[i]);208 }209 MCA_Label_Features_Rosenfeld(mca->mcas[0]);210 #else211 212 for (int i = 1; i < num_threads; i++) { 212 213 pthread_create(&thread_table[i], NULL, MCA_Label_Rosenfeld, (void *) mca->mcas[i]); 213 214 } 215 214 216 MCA_Label_Rosenfeld(mca->mcas[0]); 215 #endif 217 216 218 for (int i = 1; i < num_threads; i++) { 217 219 pthread_join(thread_table[i], NULL); … … 221 223 222 224 // -- free -- 223 printf("Finalize\n");225 MCA_VERBOSE1(printf("Finalize\n")); 224 226 MCA_Finalize(mca); 225 227 226 printf("Free_matrix\n");228 MCA_VERBOSE1(printf("Free_matrix\n")); 227 229 free_ui8matrix (X0, i0, i1, j0, j1); 228 230 free_ui32matrix(E, i0, i1, j0, j1); … … 249 251 Palette_18ColorsBW(palette); 250 252 251 printf("Loading file %s... ", infile);253 MCA_VERBOSE1(printf("Loading file %s... ", infile)); 252 254 X = LoadPGM_ui8matrix(infile, &i0, &i1, &j0, &j1); 253 printf("done.\n");254 255 printf("Allocating memory... ");255 MCA_VERBOSE1(printf("done.\n")); 256 257 MCA_VERBOSE1(printf("Allocating memory... ")); 256 258 height = i1 - i0 + 1; 257 259 width = j1 - j0 + 1; … … 265 267 // pre-traitements 266 268 binarisation_ui8matrix(X, i0, i1, j0, j1, 20, 1, X); // pour le traitement 267 printf("done.\n");268 269 printf("Allocating and initializing MCA... \n");269 MCA_VERBOSE1(printf("done.\n")); 270 271 MCA_VERBOSE1(printf("Allocating and initializing MCA... \n")); 270 272 mca = MCA_pConstructor_Empty(); 271 273 … … 279 281 MCA_Initialize(mca); 280 282 MCA_Display_Parameters(mca); 281 printf("End of MCA allocation and initialization.\n");283 MCA_VERBOSE1(printf("End of MCA allocation and initialization.\n")); 282 284 283 285 CLOCK_APP_CREATE; 284 #if FEATURES285 for (int i = 1; i < num_threads; i++) {286 pthread_create(&thread_table[i], NULL, MCA_Label_Features_Rosenfeld, (void *) mca->mcas[i]);287 }288 MCA_Label_Features_Rosenfeld(mca->mcas[0]);289 #else290 286 for (int i = 1; i < num_threads; i++) { 291 287 pthread_create(&thread_table[i], NULL, MCA_Label_Rosenfeld, (void *) mca->mcas[i]); 292 288 } 289 293 290 MCA_Label_Rosenfeld(mca->mcas[0]); 294 #endif 291 295 292 for (int i = 1; i < num_threads; i++) { 296 293 pthread_join(thread_table[i], NULL); … … 300 297 if (generate_output_image) { 301 298 #if TARGET_OS != GIETVM 302 renumber_image(mca ->E, i0, i1, j0, j1);299 renumber_image(mca, i0, i1, j0, j1); 303 300 #else 304 301 printf("Warning: the output image has not been renumbered, it cannot be used as a comparison with the reference\n"); 305 302 #endif 306 303 mod_ui32matrix_ui8matrix(mca->E, i0, i1, j0, j1, E8); 307 printf("Saving file %s for verification... ", outfile);304 MCA_VERBOSE1(printf("Saving file %s for verification... ", outfile)); 308 305 SaveBMP2_ui8matrix(E8, width, height, palette, outfile); 309 printf("done.\n");306 MCA_VERBOSE1(printf("done.\n")); 310 307 } 311 308 312 309 MCA_Finalize(mca); 313 printf("Deallocating memory...");310 MCA_VERBOSE1(printf("Deallocating memory...")); 314 311 free_ui8matrix (X, i0, i1, j0, j1); 315 312 free_ui8matrix (E8, i0, i1, j0, j1); 316 313 free_ui32matrix(E, i0, i1, j0, j1); 317 printf("done.\n");314 MCA_VERBOSE1(printf("done.\n")); 318 315 } 319 316 … … 353 350 int num_threads = DEFAULT_NTHREADS; 354 351 355 printf("*** Starting application Rosenfeld ***\n");352 MCA_VERBOSE1(printf("*** Starting application Rosenfeld ***\n")); 356 353 357 354 #if TARGET_OS != GIETVM // @QM I think the giet has some random (uninitialized) values for argc and argv … … 410 407 } 411 408 412 printf("Parameters:\n");413 printf("- Number of threads: %d\n", num_threads);414 printf("- Input file: %s\n", infile);415 printf("- Output file: %s\n", outfile);409 MCA_VERBOSE1(printf("Parameters:\n")); 410 MCA_VERBOSE1(printf("- Number of threads: %d\n", num_threads)); 411 MCA_VERBOSE1(printf("- Input file: %s\n", infile)); 412 MCA_VERBOSE1(printf("- Output file: %s\n", outfile)); 416 413 #if FAST 417 printf("- Using decision trees (fast): yes\n");414 MCA_VERBOSE1(printf("- Using decision trees (fast): yes\n")); 418 415 #elif SLOW 419 printf("- Using decision trees (fast): no\n");416 MCA_VERBOSE1(printf("- Using decision trees (fast): no\n")); 420 417 #endif 421 418 #if FEATURES 422 printf("- Computing features: yes\n"); 423 #else 424 printf("- Computing features: no\n"); 419 MCA_VERBOSE1(printf("- Computing features: yes\n")); 420 #else 421 MCA_VERBOSE1(printf("- Computing features: no\n")); 422 #endif 423 #if PARMERGE 424 MCA_VERBOSE1(printf("- Parallel Merge: yes\n")); 425 #else 426 MCA_VERBOSE1(printf("- Parallel Merge: no\n")); 427 #endif 428 #if ARSP 429 MCA_VERBOSE1(printf("- Optimization ARemSP: yes\n")); 430 #else 431 MCA_VERBOSE1(printf("- Optimization ARemSP: no\n")); 432 #endif 433 #if PYR_BARRIERS 434 MCA_VERBOSE1(printf("- Pyramidal Barriers: yes\n")); 435 #else 436 MCA_VERBOSE1(printf("- Pyramidal Barriers: no\n")); 425 437 #endif 426 438 … … 428 440 #if TARGET_OS == GIETVM 429 441 giet_tty_alloc(1); 430 printf("Initializing heaps... ");442 MCA_VERBOSE1(printf("Initializing heaps... ")); 431 443 for (int i = 0; i < X_SIZE; i++) { 432 444 for (int j = 0; j < X_SIZE; j++) { … … 434 446 } 435 447 } 436 printf("done.\n");448 MCA_VERBOSE1(printf("done.\n")); 437 449 #endif 438 450 … … 443 455 } 444 456 457 // Local Variables: 458 // tab-width: 4 459 // c-basic-offset: 4 460 // c-file-offsets:((innamespace . 0)(inline-open . 0)) 461 // indent-tabs-mode: nil 462 // End: 463 464 // vim: filetype=cpp:expandtab:shiftwidth=4:tabstop=4:softtabstop=4 465 -
soft/giet_vm/applications/rosenfeld/src-par/mca_rosenfeld.c
r821 r822 61 61 r = T[r]; 62 62 } 63 if (r == 0) { 64 printf("e = %d\n",e); 65 assert(0); 66 } 63 64 assert(r != 0); 67 65 return r; 68 66 } … … 81 79 int mask = (1 << shift) - 1; 82 80 83 MCA_VERBOSE 2(printf("%s(%d, %d) \n", __func__, r, shift));81 MCA_VERBOSE3(printf("%s(%d, %d) \n", __func__, r, shift)); 84 82 do { 85 83 e = r; … … 87 85 e0 = r & mask; 88 86 r = D[e1][e0]; 89 MCA_VERBOSE 2(printf("%s: D(%d) = D[%d,%d] = %d (alpha = %d)\n", __func__, e, e1, e0, r, shift));87 MCA_VERBOSE3(printf("%s: D(%d) = D[%d,%d] = %d (alpha = %d)\n", __func__, e, e1, e0, r, shift)); 90 88 } while (r < e); 91 MCA_VERBOSE 2(printf("%s = %d \n\n", __func__, r));89 MCA_VERBOSE3(printf("%s = %d \n\n", __func__, r)); 92 90 assert(r != 0); 93 91 return r; … … 112 110 113 111 #if FEATURES && !PARMERGE 114 // ---------------------------------------------------------------------------------------------------- 115 void SetRoot_Features_Rosenfeld_Dist(uint32 ** D, uint32 root, uint32 eps, int shift, RegionStats ** F)116 // ---------------------------------------------------------------------------------------------------- 112 // ----------------------------------------------------------------------------------------------------------- 113 static void SetRoot_Features_Rosenfeld_Dist(uint32 ** D, uint32 root, uint32 eps, int shift, RegionStats ** F) 114 // ----------------------------------------------------------------------------------------------------------- 117 115 { 118 116 assert(root != 0 && eps != 0); 119 117 120 MCA_VERBOSE 2(printf("F(%d) += F(%d)\n", eps, root));118 MCA_VERBOSE3(printf("F(%d) += F(%d)\n", eps, root)); 121 119 122 120 int mask = (1 << shift) - 1; 123 121 124 // SetRoot_Rosenfeld_Dist125 122 uint32 r1 = root >> shift; 126 123 uint32 r0 = root & mask; … … 148 145 149 146 #if FEATURES && PARMERGE 150 // ------------------------------------------------------------------------------------------------------------- 151 bool SetRoot_Parallel_Features_Rosenfeld_Dist(uint32 ** D, uint32 root, uint32 eps, int shift, RegionStats ** F)152 // ------------------------------------------------------------------------------------------------------------- 147 // -------------------------------------------------------------------------------------------------------------------- 148 static bool SetRoot_Parallel_Features_Rosenfeld_Dist(uint32 ** D, uint32 root, uint32 eps, int shift, RegionStats ** F) 149 // -------------------------------------------------------------------------------------------------------------------- 153 150 { 154 151 assert(root != 0 && eps != 0); 155 152 156 MCA_VERBOSE 2(printf("F(%d) += F(%d)\n", eps, root));153 MCA_VERBOSE3(printf("F(%d) += F(%d)\n", eps, root)); 157 154 158 155 int mask = (1 << shift) - 1; 159 156 160 // SetRoot_Rosenfeld_Dist161 157 uint32 r1 = root >> shift; 162 158 uint32 r0 = root & mask; … … 177 173 } 178 174 if (D[r1][r0] != root) { 179 // Someone change the root of epsilon, need to find the new root175 // Someone change the root of "root", need to find the new root 180 176 printf("race cond 2\n"); 181 177 pthread_spin_unlock(&F[e1][e0].lock); … … 249 245 250 246 251 #if FAST && !FEATURES 247 #if FAST && !FEATURES && !PARMERGE && !ARSP 252 248 // --------------------------------------------------------------------------------------- 253 249 static void vuse2_Rosenfeld_Dist(uint32 ed, uint32 el, uint32 * T, uint32 ** D, int alpha) … … 273 269 } 274 270 } 275 #endif // FAST && !FEATURES 276 277 278 #if FAST && !FEATURES 271 272 // FAST && !FEATURES && !PARMERGE && !ARSP 273 279 274 // ----------------------------------------------------------------------------------------------------- 280 275 static void vuse3_Rosenfeld_Dist(uint32 ed1, uint32 ed2, uint32 el3, uint32 * T, uint32 ** D, int alpha) … … 284 279 uint32 r2 = FindRoot_Dist(D, ed2, alpha); 285 280 286 // QM287 //uint32 r3 = FindRoot(T, el3); // local - distant288 281 uint32 r3 = T[el3]; // local - distant 289 282 r3 = FindRoot_Dist(D, r3, alpha); … … 297 290 uint32 eps = ui32Min3(r1, r2, r3); // forcement positifs car appel depuis optimizedBorder qui a fait un test 298 291 292 // On ne fait pas le test car on peut faire le SetRoot plusieurs fois sur le même élément (on n'accumule pas de stats) 299 293 if (r1 > eps) { 300 294 SetRoot_Rosenfeld_Dist(D, r1, eps, alpha); 301 295 } 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 296 if (r2 > eps) { 305 297 SetRoot_Rosenfeld_Dist(D, r2, eps, alpha); 306 298 } 307 //r3 = T[r3];308 299 if (r3 > eps) { 309 300 SetRoot_Rosenfeld_Dist(D, r3, eps, alpha); 310 301 } 311 302 } 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 // ----------------------------------------------------------------------------------------------------------- 303 #endif // FAST && !FEATURES && !PARMERGE && !ARSP 304 305 306 #if FAST && FEATURES && !PARMERGE && !ARSP 307 // ------------------------------------------------------------------------------------------------------------------ 308 static void vuse2_Features_Rosenfeld_Dist(uint32 ed, uint32 el, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 309 // ------------------------------------------------------------------------------------------------------------------ 319 310 { 320 311 assert(ed != 0 && el != 0); … … 341 332 } 342 333 } 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 // ------------------------------------------------------------------------------------------------------------------------- 334 335 // FAST && FEATURES && !PARMERGE && !ARSP 336 337 // -------------------------------------------------------------------------------------------------------------------------------- 338 static void vuse3_Features_Rosenfeld_Dist(uint32 ed1, uint32 ed2, uint32 el3, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 339 // -------------------------------------------------------------------------------------------------------------------------------- 350 340 { 351 341 assert(ed1 != 0 && ed2 != 0 && el3 != 0); … … 354 344 uint32 r2 = FindRoot_Dist(D, ed2, alpha); 355 345 356 //uint32 r3 = FindRoot(T, el3); // local - distant357 346 uint32 r3 = T[el3]; // local - distant 358 347 assert(r3 != 0); … … 370 359 SetRoot_Features_Rosenfeld_Dist(D, r1, eps, alpha, F); 371 360 } 372 //r2 = T[r2];373 361 if (r2 > eps && r2 != r1) { 374 362 SetRoot_Features_Rosenfeld_Dist(D, r2, eps, alpha, F); 375 363 } 376 //r3 = T[r3];377 364 if (r3 > eps && r3 != r2 && r3 != r1) { 378 365 SetRoot_Features_Rosenfeld_Dist(D, r3, eps, alpha, F); 379 366 } 380 367 } 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 // -------------------------------------------------------------------------------------------------------------------- 368 #endif // FAST && FEATURES && !PARMERGE && !ARSP 369 370 371 #if FAST && !FEATURES && PARMERGE && ARSP 372 // ---------------------------------------------------------------------------------------------------------------- 373 static bool SetRoot_Parallel_Arsp_Rosenfeld_Dist(uint32 ** D, uint32 root, uint32 eps, int shift, RegionStats ** F) 374 // ---------------------------------------------------------------------------------------------------------------- 375 { 376 assert(root != 0 && eps != 0); 377 378 MCA_VERBOSE3(printf("F(%d) += F(%d)\n", eps, root)); 379 380 uint32_t mask = (1 << shift) - 1; 381 382 uint32_t r1 = root >> shift; 383 uint32_t r0 = root & mask; 384 385 pthread_spin_lock(&F[r1][r0].lock); 386 if (D[r1][r0] != root) { 387 pthread_spin_unlock(&F[r1][r0].lock); 388 return false; 389 } 390 391 D[r1][r0] = eps; 392 393 pthread_spin_unlock(&F[r1][r0].lock); 394 return true; 395 } 396 397 // FAST && !FEATURES && PARMERGE && ARSP 398 399 // ------------------------------------------------------------------------------------------------------------------------------ 400 static inline bool FindSmallerAncestor_Link(uint32 ** D, uint32_t rl, uint32_t el, uint32_t rd, uint32_t shift, RegionStats ** F) 401 // ------------------------------------------------------------------------------------------------------------------------------ 402 { 403 bool ok; 404 uint32_t el1, el0; 405 uint32_t mask = (1 << shift) - 1; 406 while (rl < el && rl > rd) { 407 el = rl; 408 el1 = rl >> shift; 409 el0 = rl & mask; 410 rl = D[el1][el0]; 411 } 412 if (rd != rl) { 413 if (rl == el && rl > rd) { 414 // L'ordre s'est inversé : on fait pointer rl vers rd 415 ok = SetRoot_Parallel_Arsp_Rosenfeld_Dist(D, rl, rd, shift, F); 416 } 417 else { 418 // On fait pointer rd vers rl 419 ok = SetRoot_Parallel_Arsp_Rosenfeld_Dist(D, rd, rl, shift, F); 420 } 421 } 422 else { 423 ok = true; 424 } 425 return ok; 426 } 427 428 // FAST && !FEATURES && PARMERGE && ARSP 429 430 // ----------------------------------------------------------------------------------------------------------------------- 431 static void vuse2_Parallel_Arsp_Rosenfeld_Dist(uint32 ed, uint32 el, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 432 // ----------------------------------------------------------------------------------------------------------------------- 433 { 434 assert(ed != 0 && el != 0); 435 436 uint32_t shift = alpha; 437 uint32_t mask = (1 << shift) - 1; 438 439 uint32_t rd = ed; 440 uint32_t rl = el; 441 442 uint32_t ed1; 443 uint32_t el1; 444 uint32_t ed0; 445 uint32_t el0; 446 447 bool ok; 448 449 // Fusion ed - el 450 do { 451 do { 452 ed = rd; 453 el = rl; 454 ed1 = rd >> shift; 455 el1 = rl >> shift; 456 ed0 = rd & mask; 457 el0 = rl & mask; 458 rd = D[ed1][ed0]; 459 rl = D[el1][el0]; 460 } while (rl < el && rd < ed); 461 462 assert(rl != 0 && rd != 0); 463 464 if (rd != rl) { 465 if (rd == ed) { 466 ok = FindSmallerAncestor_Link(D, rl, el, rd, shift, F); 467 } 468 else { 469 assert(rl == el); 470 ok = FindSmallerAncestor_Link(D, rd, ed, rl, shift, F); 471 } 472 } 473 else { 474 ok = true; 475 } 476 } while (!ok); 477 } 478 479 // FAST && !FEATURES && PARMERGE && ARSP 480 481 // ------------------------------------------------------------------------------------------------------------------------------------- 482 static void vuse3_Parallel_Arsp_Rosenfeld_Dist(uint32 ed1, uint32 ed2, uint32 el3, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 483 // ------------------------------------------------------------------------------------------------------------------------------------- 484 { 485 assert(ed1 != 0 && ed2 != 0 && el3 != 0); 486 487 uint32_t shift = alpha; 488 uint32_t mask = (1 << shift) - 1; 489 490 uint32_t r1 = ed1; 491 uint32_t r2 = ed2; 492 uint32_t r3 = el3; 493 494 uint32_t e11; 495 uint32_t e21; 496 uint32_t e31; 497 uint32_t e10; 498 uint32_t e20; 499 uint32_t e30; 500 501 uint32_t r0; 502 uint32_t ed0; 503 uint32_t e00; 504 uint32_t e01; 505 506 // Pas d'init pour que valgrind détecte une erreur si bool est lu sans être affecté 507 bool ok; 508 509 // Fusion ed1 - ed2 510 do { 511 do { 512 ed1 = r1; 513 ed2 = r2; 514 e11 = r1 >> shift; 515 e21 = r2 >> shift; 516 e10 = r1 & mask; 517 e20 = r2 & mask; 518 r1 = D[e11][e10]; 519 r2 = D[e21][e20]; 520 } while (r1 < ed1 && r2 < ed2); 521 522 assert(r1 != 0 && r2 != 0); 523 524 if (r1 != r2) { 525 if (r1 == ed1) { 526 ok = FindSmallerAncestor_Link(D, r2, ed2, r1, shift, F); 527 } 528 else { 529 assert(r2 == ed2); 530 ok = FindSmallerAncestor_Link(D, r1, ed1, r2, shift, F); 531 } 532 } 533 else { 534 ok = true; 535 } 536 } while (!ok); 537 538 // Fusion r0 = min(r1, r2) avec r3 539 if (r1 < r2) { 540 r0 = r1; 541 ed0 = r1; 542 e00 = e10; 543 e01 = e11; 544 } 545 else { 546 r0 = r2; 547 ed0 = r2; 548 e00 = e20; 549 e01 = e21; 550 } 551 552 // r0 est déjà une racine 553 goto r0_is_root; 554 do { 555 do { 556 ed0 = r0; 557 el3 = r3; 558 e01 = r0 >> shift; 559 e31 = r3 >> shift; 560 e00 = r0 & mask; 561 e30 = r3 & mask; 562 r0 = D[e01][e00]; 563 r3 = D[e31][e30]; 564 } while (r0 < ed0 && r3 < el3); 565 566 assert(r0 != 0 && r3 != 0); 567 568 if (r0 != r3) { 569 if (r0 == ed0) { 570 r0_is_root: 571 ok = FindSmallerAncestor_Link(D, r3, el3, r0, shift, F); 572 } 573 else { 574 assert(r3 == el3); 575 ok = FindSmallerAncestor_Link(D, r0, ed0, r3, shift, F); 576 } 577 } 578 else { 579 ok = true; 580 } 581 } while (!ok); 582 } 583 #endif // FAST && !FEATURES && PARMERGE && ARSP 584 585 586 587 #if FAST && FEATURES && PARMERGE && !ARSP 588 // --------------------------------------------------------------------------------------------------------------------------- 589 static void vuse2_Parallel_Features_Rosenfeld_Dist(uint32 ed, uint32 el, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 590 // --------------------------------------------------------------------------------------------------------------------------- 388 591 { 389 592 bool ok; … … 414 617 } while (!ok); 415 618 } 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 // ---------------------------------------------------------------------------------------------------------------------------------- 619 620 // FAST && FEATURES && PARMERGE && !ARSP 621 622 // ----------------------------------------------------------------------------------------------------------------------------------------- 623 static void vuse3_Parallel_Features_Rosenfeld_Dist(uint32 ed1, uint32 ed2, uint32 el3, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 624 // ----------------------------------------------------------------------------------------------------------------------------------------- 423 625 { 424 626 bool ok1, ok2, ok3; … … 457 659 } while (!(ok1 && ok2 && ok3)); 458 660 } 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 // ------------------------------------------------------------------------------------------------------ 661 #endif // FAST && FEATURES && PARMERGE && !ARSP 662 663 664 665 #if FAST 666 // ------------------------------------------------------------------------------------------------------------------------ 667 static void optimizedBorder_Rosenfeld_Dist(uint32 ** E, int i, int j, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 668 // ------------------------------------------------------------------------------------------------------------------------ 468 669 { 469 670 uint32 a, b, c, x; … … 473 674 b = E[i - 1][j]; 474 675 if (b) { 475 vuse2_Rosenfeld _Dist(b, x, T, D, alpha); // dist, local676 vuse2_Rosenfeld(b, x, T, D, alpha, F); // dist, local 476 677 } 477 678 else { … … 480 681 a = E[i - 1][j - 1]; 481 682 if (a) { 482 vuse3_Rosenfeld _Dist(a, c, x, T, D, alpha); // dist, local683 vuse3_Rosenfeld(a, c, x, T, D, alpha, F); // dist, local 483 684 } 484 685 else { 485 vuse2_Rosenfeld _Dist(c, x, T, D, alpha); // dist, local686 vuse2_Rosenfeld(c, x, T, D, alpha, F); // dist, local 486 687 } 487 688 } … … 489 690 a = E[i - 1][j - 1]; 490 691 if (a) { 491 vuse2_Rosenfeld _Dist(a, x, T, D, alpha); // dist, local692 vuse2_Rosenfeld(a, x, T, D, alpha, F); // dist, local 492 693 } 493 694 } … … 495 696 } 496 697 } 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 // --------------------------------------------------------------------------------------------------- 698 699 // FAST 700 701 // ---------------------------------------------------------------------------------------------------------------------------- 702 static void optimizedBorderLeft_Rosenfeld_Dist(uint32 ** E, int i, int j, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 703 // ---------------------------------------------------------------------------------------------------------------------------- 504 704 { 505 705 uint32 x = E[i][j]; … … 507 707 uint32 b = E[i - 1][j]; 508 708 if (b) { 509 vuse2_Rosenfeld _Dist(b, x, T, D, alpha); // dist, local709 vuse2_Rosenfeld(b, x, T, D, alpha, F); // dist, local 510 710 } 511 711 else { 512 712 uint32 c = E[i - 1][j + 1]; 513 713 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 // ----------------------------------------------------------------------------------------------------------- 714 vuse2_Rosenfeld(c, x, T, D, alpha, F); // dist, local 715 } 716 } 717 } 718 } 719 720 // FAST 721 722 // ----------------------------------------------------------------------------------------------------------------------------- 723 static void optimizedBorderRight_Rosenfeld_Dist(uint32 ** E, int i, int j, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 724 // ----------------------------------------------------------------------------------------------------------------------------- 526 725 { 527 726 // copie de optimizedBorder_Rosenfeld … … 533 732 if (x) { 534 733 if (b) { 535 vuse2_Rosenfeld _Dist(b, x, T, D, alpha); // dist, local734 vuse2_Rosenfeld(b, x, T, D, alpha, F); // dist, local 536 735 } 537 736 else { 538 737 uint32 a = E[i - 1][j - 1]; 539 738 if (a) { 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 // ------------------------------------------------------------------------------------------------------------------------ 739 vuse2_Rosenfeld(a, x, T, D, alpha, F); // dist, local 740 } 741 } 742 } 743 } 744 745 // FAST 746 747 // ------------------------------------------------------------------------------------------------------------------------------------------- 748 static void borderMerging_Fast_Rosenfeld_Dist(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 749 // ------------------------------------------------------------------------------------------------------------------------------------------- 552 750 { 553 751 // Prologue 554 optimizedBorderLeft_Rosenfeld_Dist(E, i, 0, T, D, alpha );752 optimizedBorderLeft_Rosenfeld_Dist(E, i, 0, T, D, alpha, F); 555 753 // Boucle principale 556 754 for (int j = 1; j < width - 1; j++) { 557 optimizedBorder_Rosenfeld_Dist(E, i, j, T, D, alpha );755 optimizedBorder_Rosenfeld_Dist(E, i, j, T, D, alpha, F); 558 756 } 559 757 // 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 { 570 int j; 758 optimizedBorderRight_Rosenfeld_Dist(E, i, width - 1, T, D, alpha, F); 759 } 760 #endif // FAST 761 762 763 764 #if SLOW 765 // ------------------------------------------------------------------------------------------------------------------------------------------- 766 static void borderMerging_Slow_Rosenfeld_Dist(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 767 // ------------------------------------------------------------------------------------------------------------------------------------------- 768 { 769 int j = 0; 571 770 572 771 uint32 eps; … … 577 776 // -- prologue -- 578 777 // -------------- 579 MCA_VERBOSE2(printf("[%s] i = %d\n", __func__, i)); 580 581 j = 0; 778 MCA_VERBOSE3(printf("[%s] i = %d\n", __func__, i)); 779 582 780 ex = E[i][j]; 583 781 584 782 if (ex) { 585 783 586 MCA_VERBOSE2(printf("[%s] j = %d\n", __func__, j)); 587 588 e2 = E[i - 1][j]; 589 e3 = E[i - 1][j + 1]; 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 598 MCA_VERBOSE2(printf("\n")); 599 MCA_VERBOSE2(printf("e2 = %4d -> %4d\n", e2, r2)); 600 MCA_VERBOSE2(printf("e3 = %4d -> %4d\n", e3, r3)); 601 MCA_VERBOSE2(printf("ex = %4d -> %4d\n", ex, rx)); 602 603 eps = ui32MinNonNul3(r2, r3, rx); 604 605 // Quick-Union 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)); 617 } 618 MCA_VERBOSE2(printf("\n")); 619 } 620 621 // ----------------------- 622 // -- boucle principale -- 623 // ----------------------- 624 625 for (j = 0 + 1; j < width - 1; j++) { 626 627 ex = E[i][j]; 628 629 // que le cas general (pour faire un code simple) 630 if (ex) { 631 MCA_VERBOSE2(printf("[%s] j = %d\n", __func__, j)); 632 633 e1 = E[i - 1][j - 1]; 634 e2 = E[i - 1][j]; 635 e3 = E[i - 1][j + 1]; 636 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 645 MCA_VERBOSE2(printf("\n")); 646 MCA_VERBOSE2(printf("e1 = %4d -> %4d\n", e1, r1)); 647 MCA_VERBOSE2(printf("e2 = %4d -> %4d\n", e2, r2)); 648 MCA_VERBOSE2(printf("e3 = %4d -> %4d\n", e3, r3)); 649 MCA_VERBOSE2(printf("ex = %4d -> %4d\n", ex, rx)); 650 651 eps = ui32MinNonNul4(r1, r2, r3, rx); 652 653 // Quick-Union 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)); 669 } 670 MCA_VERBOSE2(printf("\n")); 671 // attention SetRoot fait un while inutile 672 } 673 } 674 675 // -------------- 676 // -- epilogue -- 677 // -------------- 678 679 j = width - 1; 680 ex = E[i][j]; 681 682 if (ex) { 683 684 MCA_VERBOSE2(printf("[%s] j = %d\n", __func__, j)); 685 686 e1 = E[i - 1][j - 1]; 687 e2 = E[i - 1][j]; 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 696 MCA_VERBOSE2(printf("\n")); 697 MCA_VERBOSE2(printf("e1 = %4d -> %4d\n", e1, r1)); 698 MCA_VERBOSE2(printf("e2 = %4d -> %4d\n", e2, r2)); 699 MCA_VERBOSE2(printf("ex = %4d -> %4d\n", ex, rx)); 700 701 eps = ui32MinNonNul3(r1, r2, rx); 702 703 // Quick-Union 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)); 715 } 716 MCA_VERBOSE2(printf("\n")); 717 } 718 return; 719 } 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)); 784 MCA_VERBOSE3(printf("[%s] j = %d\n", __func__, j)); 745 785 746 786 e2 = E[i - 1][j]; … … 758 798 eps = ui32MinNonNul3(r2, r3, rx); 759 799 760 MCA_VERBOSE 2(printf("\n"));761 MCA_VERBOSE 2(printf("e2 = %5d -> r2 = %5d\n", e2, r2));762 MCA_VERBOSE 2(printf("e3 = %5d -> r3 = %5d\n", e3, r3));763 MCA_VERBOSE 2(printf("ex = %5d -> rx = %5d\n", ex, rx));764 MCA_VERBOSE 2(printf("eps = %5d\n", eps));800 MCA_VERBOSE3(printf("\n")); 801 MCA_VERBOSE3(printf("e2 = %5d -> r2 = %5d\n", e2, r2)); 802 MCA_VERBOSE3(printf("e3 = %5d -> r3 = %5d\n", e3, r3)); 803 MCA_VERBOSE3(printf("ex = %5d -> rx = %5d\n", ex, rx)); 804 MCA_VERBOSE3(printf("eps = %5d\n", eps)); 765 805 766 806 // Quick-Union 767 // @QM768 807 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); 808 SetRoot_Rosenfeld(D, r2, eps, alpha, F); 809 MCA_VERBOSE3(printf("D[%5d] <- %d\n", r2, eps)); 774 810 } 775 811 // 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")); 812 //if (r3 > 0) { 813 // r3 = FindRoot_Dist(D, r3, alpha); 814 //} 815 //if (r3 > eps) { 816 if (r3 > eps && r3 != r2) { 817 SetRoot_Rosenfeld(D, r3, eps, alpha, F); 818 MCA_VERBOSE3(printf("D[%5d] <- %d\n", r3, eps)); 819 } 820 //rx = FindRoot_Dist(D, rx, alpha); 821 //if (rx > eps) { 822 if (rx > eps && rx != r3 && rx != r2) { 823 SetRoot_Rosenfeld(D, rx, eps, alpha, F); 824 MCA_VERBOSE3(printf("D[%5d] <- %d\n", rx, eps)); 825 } 826 MCA_VERBOSE3(printf("---------------------------\n")); 788 827 } 789 828 } … … 799 838 if (ex) { 800 839 801 MCA_VERBOSE 2(printf("[%s] j = %d\n", __func__, j));840 MCA_VERBOSE3(printf("[%s] j = %d\n", __func__, j)); 802 841 803 842 e1 = E[i - 1][j - 1]; … … 816 855 eps = ui32MinNonNul4(r1, r2, r3, rx); 817 856 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)); 857 MCA_VERBOSE3(printf("\n")); 858 MCA_VERBOSE3(printf("e1 = %5d -> r1 = %5d\n", e1, r1)); 859 MCA_VERBOSE3(printf("e2 = %5d -> r2 = %5d\n", e2, r2)); 860 MCA_VERBOSE3(printf("e3 = %5d -> r3 = %5d\n", e3, r3)); 861 MCA_VERBOSE3(printf("ex = %5d -> rx = %5d\n", ex, rx)); 862 MCA_VERBOSE3(printf("eps = %5d\n", eps)); 863 824 864 825 865 // Quick-Union 826 // @QM827 866 if (r1 > eps) { 828 SetRoot_ Features_Rosenfeld_Dist(D, r1, eps, alpha, F);829 MCA_VERBOSE 2(printf("D[%5d] <- %d\n", r1, eps));867 SetRoot_Rosenfeld(D, r1, eps, alpha, F); 868 MCA_VERBOSE3(printf("D[%5d] <- %d\n", r1, eps)); 830 869 } 831 if (r2 > 0) { 832 r2 = FindRoot_Dist(D, r2, alpha); 870 //if (r2 > 0) { 871 // r2 = FindRoot_Dist(D, r2, alpha); 872 //} 873 if (r2 > eps && r2 != r1) { 874 //if (r2 > eps) { 875 SetRoot_Rosenfeld(D, r2, eps, alpha, F); 876 MCA_VERBOSE3(printf("D[%5d] <- %d\n", r2, eps)); 833 877 } 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)); 878 //if (r3 > 0) { 879 // r3 = FindRoot_Dist(D, r3, alpha); 880 //} 881 if (r3 > eps && r3 != r2 && r3 != r1) { 882 //if (r3 > eps) { 883 SetRoot_Rosenfeld(D, r3, eps, alpha, F); 884 MCA_VERBOSE3(printf("D[%5d] <- %d\n", r3, eps)); 838 885 } 839 if (r3 > 0) { 840 r3 = FindRoot_Dist(D, r3, alpha); 886 //rx = FindRoot_Dist(D, rx, alpha); 887 if (rx > eps && rx != r3 && rx != r2 && rx != r1) { 888 //if (rx > eps) { 889 SetRoot_Rosenfeld(D, rx, eps, alpha, F); 890 MCA_VERBOSE3(printf("D[%5d] <- %d\n", rx, eps)); 841 891 } 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 892 MCA_VERBOSE3(puts("---------------------------\n")); 856 893 } 857 894 } … … 867 904 if (ex) { 868 905 869 MCA_VERBOSE 2(printf("[%s] j = %d\n", __func__, j));906 MCA_VERBOSE3(printf("[%s] j = %d\n", __func__, j)); 870 907 871 908 e1 = E[i - 1][j - 1]; … … 883 920 eps = ui32MinNonNul3(r1, r2, rx); 884 921 885 MCA_VERBOSE 2(printf("\n"));886 MCA_VERBOSE 2(printf("e1 = %5d -> r1 = %5d\n", e1, r1));887 MCA_VERBOSE 2(printf("e2 = %5d -> r2 = %5d\n", e2, r2));888 MCA_VERBOSE 2(printf("ex = %5d -> rx = %5d\n", ex, rx));889 MCA_VERBOSE 2(printf("eps = %5d\n", eps));922 MCA_VERBOSE3(printf("\n")); 923 MCA_VERBOSE3(printf("e1 = %5d -> r1 = %5d\n", e1, r1)); 924 MCA_VERBOSE3(printf("e2 = %5d -> r2 = %5d\n", e2, r2)); 925 MCA_VERBOSE3(printf("ex = %5d -> rx = %5d\n", ex, rx)); 926 MCA_VERBOSE3(printf("eps = %5d\n", eps)); 890 927 891 928 // Quick-Union 892 929 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 { 930 SetRoot_Rosenfeld(D, r1, eps, alpha, F); 931 MCA_VERBOSE3(printf("D[%5d] <- %d\n", r1, eps)); 932 } 933 //if (r2 > 0) { 934 // r2 = FindRoot_Dist(D, r2, alpha); 935 //} 936 if (r2 > eps && r2 != r1) { 937 //if (r2 > eps) { 938 SetRoot_Rosenfeld(D, r2, eps, alpha, F); 939 MCA_VERBOSE3(printf("D[%5d] <- %d\n", r2, eps)); 940 } 941 //rx = FindRoot_Dist(D, rx, alpha); 942 if (rx > eps && rx != r2 && rx != r1) { 943 //if (rx > eps) { 944 SetRoot_Rosenfeld(D, rx, eps, alpha, F); 945 MCA_VERBOSE3(printf("D[%5d] <- %d\n", rx, eps)); 946 } 947 MCA_VERBOSE3(printf("---------------------------\n")); 948 } 949 } 950 } 951 #endif // SLOW 952 953 954 955 // -------------------------------------------------------------------------------------------------------------------------------------- 956 static void borderMerging_Rosenfeld_Dist(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ** D, int alpha, RegionStats ** F) 957 // -------------------------------------------------------------------------------------------------------------------------------------- 958 { 959 #if FAST 960 borderMerging_Fast_Rosenfeld_Dist(X, i, width, E, T, D, alpha, F); 961 #endif // FAST 1127 962 #if SLOW 1128 borderMerging_Slow_Rosenfeld_Dist(X, i, width, E, T, D, alpha); 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 963 borderMerging_Slow_Rosenfeld_Dist(X, i, width, E, T, D, alpha, F); 964 #endif // SLOW 965 } 1152 966 1153 967 … … 1383 1197 return ne; 1384 1198 } 1385 #endif // FAST 1386 1387 1388 #if FAST 1199 1200 // FAST 1201 1389 1202 // ---------------------------------------------------------------------------------------------- 1390 1203 static uint32 optimizedAccessRight_DT_Rosenfeld(uint32 ** E, int i, int j, uint32 * T, uint32 ne) … … 1416 1229 return ne; 1417 1230 } 1418 #endif // FAST 1419 1420 1421 #if FAST 1231 1232 // FAST 1233 1422 1234 // ----------------------------------------------------------------------------------------- 1423 1235 static uint32 optimizedAccess_DT_Rosenfeld(uint32 ** E, int i, int j, uint32 * T, uint32 ne) … … 1467 1279 return ne; 1468 1280 } 1469 #endif // FAST 1470 1471 1472 1473 #if FAST 1281 1282 // FAST 1283 1474 1284 // -------------------------------------------------------------------------------------------------------- 1475 1285 static uint32 lineLabeling_Fast_Rosenfeld(uint8 ** X, int i, int width, uint32 ** E, uint32 * T, uint32 ne) … … 1517 1327 #elif FAST 1518 1328 return lineLabeling_Fast_Rosenfeld(X, i, width, E, T, ne); 1519 #else1520 #error "Please define SLOW or FAST for the Rosenfeld version"1521 1329 #endif 1522 1330 } … … 1539 1347 1540 1348 1541 #if !FEATURES 1542 // --------------------------------------------------------------------- 1543 static void solveTable_Range_Rosenfeld(uint32 * T, uint32 e0, uint32 e1) 1544 // --------------------------------------------------------------------- 1545 { 1546 uint32 e, r; 1547 1548 for (e = e0; e <= e1; e++) { 1549 r = T[T[e]]; 1550 if (r < e) { 1551 T[e] = r; // racine de la classe d'equivalence 1552 } 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 // ---------------------------------------------------------------------------------------------------------- 1349 // ------------------------------------------------------------------------------------------ 1350 static void solveTable_Range_Rosenfeld(uint32 * T, uint32 e0, uint32 e1, RegionStats * Stats) 1351 // ------------------------------------------------------------------------------------------ 1562 1352 { 1563 1353 uint32 e, r; … … 1568 1358 if (r < e) { 1569 1359 T[e] = r; // racine de la classe d'equivalence 1360 #if FEATURES 1570 1361 RegionStats_Accumulate_Stats1_From_Index(Stats, r, e); 1571 } 1572 } 1573 } 1574 #endif // FEATURES 1575 1576 1577 #if !FEATURES 1578 // ------------------------------------- 1579 void MCA_Label_Rosenfeld_PAR1(MCA * mca) 1580 // ------------------------------------- 1362 #endif 1363 } 1364 } 1365 } 1366 1367 1368 // -------------------------------------------- 1369 static void MCA_Label_Rosenfeld_PAR1(MCA * mca) 1370 // -------------------------------------------- 1581 1371 { 1582 1372 if (mca->p == 0) { 1583 printf("*** %s ***\n", __func__); 1584 } 1585 1586 CLOCK_THREAD_START_STEP(mca->p, 0); 1373 MCA_VERBOSE2(printf("*** %s ***\n", __func__)); 1374 } 1375 1587 1376 1588 1377 int i0 = mca->i0; 1589 1378 int i1 = mca->i1; 1590 int width = mca->width; 1379 int width = mca->width; 1380 1591 1381 uint32 e0 = mca->e0; 1592 1382 uint32 e1 = mca->e1; … … 1598 1388 uint32 ** E = mca->E; 1599 1389 uint32 * T = mca->T; 1600 1390 RegionStats * stats = mca->stats; 1391 1392 // reset sous optimal (pour le moment = voir region32) 1601 1393 if (mca->p == 0) { 1602 1394 set_ui32vector_j(T, e0 - 1, e1); // car e0 = 1, on a besoin que T[0] = 0 pour FindRoot 1395 #if FEATURES 1396 zero_RegionStatsVector(stats, e0 - 1, e1); 1397 #endif 1603 1398 } 1604 1399 else { 1605 1400 set_ui32vector_j(T, e0, e1); 1606 } 1607 1608 MCA_VERBOSE2(display_ui8matrix_positive(X, i0, i1, 0, width - 1, 5, "Xp"); printf("\n")); 1401 #if FEATURES 1402 zero_RegionStatsVector(stats, e0, e1); 1403 #endif 1404 } 1405 1406 if (mca->p == 0) { 1407 MCA_VERBOSE3(display_ui8matrix_positive(X, i0, i1, 0, width - 1, 5, "Xp"); printf("\n")); 1408 } 1409 1410 // ---------------------------- // 1411 // -- Etiquetage d'une bande -- // 1412 // ---------------------------- // 1413 1414 CLOCK_THREAD_START_STEP(mca->p, 0); 1609 1415 1610 1416 ne = line0Labeling_Rosenfeld(X, i0, width, E, T, ne); 1417 #if FEATURES 1418 lineFeaturesComputation(E, i0, width, stats); 1419 #endif 1420 1611 1421 for (int i = i0 + 1; i <= i1; i++) { 1612 ne = lineLabeling_Rosenfeld(X, i, width, E, T, ne); 1613 } 1614 1615 MCA_VERBOSE2(display_ui32matrix_positive(E, i0, i1, 0, width - 1, 5, "Ep"); printf("\n")); 1422 ne = lineLabeling_Rosenfeld(X, i, width, E, T, ne); // Slow or Fast 1423 #if FEATURES 1424 lineFeaturesComputation(E, i, width, stats); 1425 #endif 1426 } 1427 mca->ne = ne; //plus grande etiquette de l'intervalle [e0..e1] 1428 1616 1429 if (mca->p == 0) { 1617 MCA_VERBOSE2(display_ui32vector_number(T, e0, ne, "%5d", "Tp_avant")); 1618 } 1619 1620 // fermeture transitive sans pack 1621 solveTable_Range_Rosenfeld(T, e0, ne); 1622 mca->ne = ne; // Plus grande etiquette de l'intervalle [e0..e1] 1623 1624 MCA_VERBOSE2(nr = countTable_Range_Rosenfeld(T, e0, ne)); 1625 MCA_VERBOSE2(printf("p = %d : e = [%d..%d] -> ne = %d -> nr = %d\n", mca->p, e0, ne, (ne - e0 + 1), nr)); 1430 MCA_VERBOSE3(printf("ne = %d\n", ne)); 1431 MCA_VERBOSE3(display_ui32matrix_positive(E, i0, i1, 0, width - 1, 5, "Ep"); printf("\n")); 1432 MCA_VERBOSE3(display_ui32vector_number(T, e0, ne, "%5d", "Tp_avant")); 1433 } 1434 1435 // ------------------------------------------------------ // 1436 // -- Fermeture transitive sans pack de chaque table T -- // 1437 // ------------------------------------------------------ // 1438 1439 solveTable_Range_Rosenfeld(T, e0, ne, stats); 1440 1626 1441 if (mca->p == 0) { 1627 MCA_VERBOSE2(display_ui32vector_number(T, e0, ne, "%5d", "Tp_apres")); 1628 } 1629 1442 MCA_VERBOSE3(nr = countTable_Range_Rosenfeld(T, e0, ne); 1443 printf("p = %d : e = [%d..%d] -> ne = %d -> nr = %d\n", mca->p, e0, ne, (ne - e0 + 1), nr)); 1444 MCA_VERBOSE3(display_ui32vector_number(T, e0, ne, "%5d", "Tp_apres")); 1445 } 1630 1446 CLOCK_THREAD_END_STEP(mca->p, 0); 1631 1447 } 1632 #endif // !FEATURES 1633 1634 1635 #if !FEATURES 1636 // ------------------------------------- 1637 void MCA_Label_Rosenfeld_PYR2(MCA * mca) 1638 // ------------------------------------- 1639 { 1640 // input 1448 1449 1450 1451 #if PARMERGE 1452 // ----------------------------------------------------- 1453 static void MCA_Label_Rosenfeld_PAR2(MCA * mca) 1454 // ----------------------------------------------------- 1455 { 1641 1456 int p = mca->p; 1642 1457 int nb_level = mca->nb_level; 1643 1458 1644 1459 if (mca->p == 0) { 1645 printf("*** %s ***\n", __func__);1460 MCA_VERBOSE2(printf("*** %s ***\n", __func__)); 1646 1461 } 1647 1462 1648 1463 // ------------------------------ 1649 // -- p yramidal border merging --1464 // -- parallel border merging -- 1650 1465 // ------------------------------ 1651 1466 … … 1662 1477 uint32 * T = mca->T; 1663 1478 uint32 ** D = mca->D; 1664 1665 CLOCK_THREAD_START_STEP(p, 1);1666 #if PYR_BARRIERS1667 // Version optimisée qui fait faire un break aux processeurs qui n'ont plus1668 // à faire de merge.1669 // Implique de pré-calculer le nombre de threads à chaque barriÚre1670 if (p != 0) { // thread 0 never has any merge to do1671 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 #else1685 for (int level = 1; level <= nb_level; level++) {1686 if ((p + (1 << (level - 1))) % (1 << level) == 0) {1687 // thread actif1688 borderMerging_Rosenfeld_Dist(X, i, width, E, T, D, alpha); // en (i) et (i-1)1689 }1690 pthread_barrier_wait(&main_barrier);1691 }1692 #endif1693 CLOCK_THREAD_END_STEP(p, 1);1694 1695 1696 // ---------------------------------1697 // -- parallel transitive closure --1698 // ---------------------------------1699 1700 CLOCK_THREAD_START_STEP(p, 2);1701 for (uint32 e = e0; e <= e1; e++) {1702 uint32 r = T[e]; // acces local1703 if (r < e) {1704 r = FindRoot_Dist(D, e, alpha); // acces distant1705 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 // !FEATURES1712 1713 1714 // -------------------------------------1715 void MCA_Label_Rosenfeld_PAR3(MCA * mca)1716 // -------------------------------------1717 {1718 // input1719 if (mca->p == 0) {1720 printf("*** %s ***\n", __func__);1721 }1722 1723 int i0 = mca->i0;1724 int i1 = mca->i1;1725 int j0 = 0;1726 int j1 = mca->width - 1;1727 1728 uint32 ** E = mca->E;1729 uint32 * T = mca->T;1730 1731 CLOCK_THREAD_START_STEP(mca->p, 3);1732 for (int i = i0; i <= i1; i++) {1733 for (int j = j0; j <= j1; j++) {1734 uint32 e = E[i][j];1735 if (e != 0) {1736 E[i][j] = T[e];1737 }1738 }1739 }1740 CLOCK_THREAD_END_STEP(mca->p, 3);1741 }1742 1743 1744 #if FEATURES1745 // -----------------------------------------------------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 zones1765 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 FindRoot1774 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 Fast1794 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 // FEATURES1818 1819 1820 #if FEATURES && !PARMERGE1821 // -----------------------------------------------------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 variables1837 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 zones1844 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_BARRIERS1852 // Version optimisée qui fait faire un break aux processeurs qui n'ont plus1853 // à faire de merge.1854 // Implique de pré-calculer le nombre de threads à chaque barriÚre1855 if (p != 0) { // thread 0 never has any merge to do1856 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 #else1870 for (int level = 1; level <= nb_level; level++) {1871 if ((p + (1 << (level - 1))) % (1 << level) == 0) {1872 // thread actif1873 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 #endif1878 CLOCK_THREAD_END_STEP(p, 1);1879 1880 1881 /**1882 * To remove?1883 // -- Affichage de debug1884 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 Features1908 1909 CLOCK_THREAD_START_STEP(p, 2);1910 for (uint32 e = e0; e <= e1; e++) {1911 uint32 r = T[e]; // acces local1912 if (r < e) {1913 r = FindRoot_Dist(D, e, alpha); // acces distant1914 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 accesses1921 CLOCK_THREAD_START_STEP(p, 3);1922 CLOCK_THREAD_END_STEP(p, 3);1923 }1924 #endif // FEATURES && !PARMERGE1925 1926 1927 #if FEATURES && PARMERGE1928 // -----------------------------------------------------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 variables1944 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 zones1951 uint8 ** X = mca->X;1952 uint32 ** E = mca->E;1953 uint32 * T = mca->T;1954 uint32 ** D = mca->D;1955 1479 RegionStats ** F = mca->F; 1956 1480 1957 1481 CLOCK_THREAD_START_STEP(p, 1); 1958 1482 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)1483 borderMerging_Rosenfeld_Dist(X, i, width, E, T, D, alpha, F); // (i) et (i-1) 1960 1484 } 1961 1485 pthread_barrier_wait(&main_barrier); … … 1975 1499 T[e] = r; 1976 1500 } 1977 MCA_VERBOSE 2(printf("p%d : T[%d] <- %d\n", p, e, r));1501 MCA_VERBOSE3(printf("p%d : T[%d] <- %d\n", p, e, r)); 1978 1502 } 1979 1503 CLOCK_THREAD_END_STEP(p, 2); … … 1983 1507 CLOCK_THREAD_END_STEP(p, 3); 1984 1508 } 1985 #endif // FEATURES 1986 1987 1988 1989 1990 #if !FEATURES 1991 // ============================================================= 1992 #if TARGET_OS == GIETVM 1993 __attribute__((constructor)) void MCA_Label_Rosenfeld(MCA * mca) 1509 #endif // PARMERGE 1510 1511 1512 #if !PARMERGE 1513 // -------------------------------------------- 1514 static void MCA_Label_Rosenfeld_PYR2(MCA * mca) 1515 // -------------------------------------------- 1516 { 1517 // input 1518 int p = mca->p; 1519 int nb_level = mca->nb_level; 1520 1521 if (mca->p == 0) { 1522 MCA_VERBOSE2(printf("*** %s ***\n", __func__)); 1523 } 1524 1525 // ------------------------------ 1526 // -- pyramidal border merging -- 1527 // ------------------------------ 1528 1529 // local variables 1530 int i = mca->i0; 1531 int width = mca->width; 1532 int alpha = mca->alpha; 1533 uint32 e0 = mca->e0; 1534 uint32 e1 = mca->ne; 1535 1536 // local memory zones 1537 uint8 ** X = mca->X; 1538 uint32 ** E = mca->E; 1539 uint32 * T = mca->T; 1540 uint32 ** D = mca->D; 1541 RegionStats ** F = mca->F; 1542 1543 CLOCK_THREAD_START_STEP(p, 1); 1544 #if PYR_BARRIERS 1545 // Version optimisée qui fait faire un break aux processeurs qui n'ont plus 1546 // à faire de merge. 1547 // Implique de pré-calculer le nombre de threads à chaque barriÚre 1548 if (p != 0) { // thread 0 never has any merge to do 1549 int been_active = 0; 1550 for (int level = 0; level < nb_level; level++) { 1551 if ((p + (1 << level)) % (1 << (level + 1)) == 0) { 1552 borderMerging_Rosenfeld_Dist(X, i, width, E, T, D, alpha, F); // (i) et (i-1) 1553 been_active = 1; 1554 } 1555 else if (been_active) { 1556 break; 1557 } 1558 pthread_barrier_wait(&mca->barriers[level]); 1559 } 1560 } 1561 pthread_barrier_wait(&main_barrier); 1994 1562 #else 1995 void MCA_Label_Rosenfeld(MCA * mca) 1563 for (int level = 1; level <= nb_level; level++) { 1564 if ((p + (1 << (level - 1))) % (1 << level) == 0) { 1565 // thread actif 1566 borderMerging_Rosenfeld_Dist(X, i, width, E, T, D, alpha, F); // (i) et (i-1) 1567 } 1568 pthread_barrier_wait(&main_barrier); 1569 } 1996 1570 #endif 1997 // ============================================================= 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 2015 MCA_Scatter_ImageX(mca); 2016 pthread_barrier_wait(&main_barrier); 2017 2018 MCA_Label_Rosenfeld_PAR1(mca); 2019 pthread_barrier_wait(&main_barrier); 2020 2021 MCA_Label_Rosenfeld_PYR2(mca); 2022 pthread_barrier_wait(&main_barrier); 2023 2024 MCA_Label_Rosenfeld_PAR3(mca); 2025 pthread_barrier_wait(&main_barrier); 2026 2027 MCA_Gather_ImageL(mca); 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 2034 if (mca->p != 0) { 2035 exit(0); 2036 } 2037 #endif 1571 CLOCK_THREAD_END_STEP(p, 1); 1572 1573 1574 // --------------------------------- 1575 // -- parallel transitive closure -- 1576 // --------------------------------- 1577 1578 CLOCK_THREAD_START_STEP(p, 2); 1579 for (uint32 e = e0; e <= e1; e++) { 1580 uint32 r = T[e]; // acces local 1581 if (r < e) { 1582 r = FindRoot_Dist(D, e, alpha); // acces distant 1583 T[e] = r; 1584 } 1585 MCA_VERBOSE3(printf("p%d : T[%d] <- %d\n", p, e, r)); 1586 } 1587 CLOCK_THREAD_END_STEP(p, 2); 2038 1588 } 2039 1589 #endif // !FEATURES 2040 1590 2041 1591 2042 #if FEATURES 1592 // ------------------------------------- 1593 void MCA_Label_Rosenfeld_PAR3(MCA * mca) 1594 // ------------------------------------- 1595 { 1596 // input 1597 if (mca->p == 0) { 1598 MCA_VERBOSE2(printf("*** %s ***\n", __func__)); 1599 } 1600 1601 int i0 = mca->i0; 1602 int i1 = mca->i1; 1603 int j0 = 0; 1604 int j1 = mca->width - 1; 1605 1606 uint32 ** E = mca->E; 1607 uint32 * T = mca->T; 1608 1609 CLOCK_THREAD_START_STEP(mca->p, 3); 1610 for (int i = i0; i <= i1; i++) { 1611 for (int j = j0; j <= j1; j++) { 1612 uint32 e = E[i][j]; 1613 if (e != 0) { 1614 E[i][j] = T[e]; 1615 } 1616 } 1617 } 1618 CLOCK_THREAD_END_STEP(mca->p, 3); 1619 } 1620 1621 1622 2043 1623 // ====================================================================== 2044 1624 #if TARGET_OS == GIETVM 2045 __attribute__((constructor)) void * MCA_Label_ Features_Rosenfeld(void * arg)1625 __attribute__((constructor)) void * MCA_Label_Rosenfeld(void * arg) 2046 1626 #else 2047 void * MCA_Label_ Features_Rosenfeld(void * arg)1627 void * MCA_Label_Rosenfeld(void * arg) 2048 1628 #endif 2049 1629 // ====================================================================== … … 2060 1640 // mca->p = 4 pour (x = 0, y = 1, lpid = 0) 2061 1641 // mca->p = 5 pour (x = 0, y = 1, lpid = 1) 2062 MCA_VERBOSE 2(printf("mca->p = %d pour (x = %d, y = %d, lpid = %d)\n", mca->p, x, y, lpid));1642 MCA_VERBOSE3(printf("mca->p = %d pour (x = %d, y = %d, lpid = %d)\n", mca->p, x, y, lpid)); 2063 1643 #endif 2064 1644 … … 2069 1649 pthread_barrier_wait(&main_barrier); 2070 1650 2071 MCA_Label_ Features_Rosenfeld_PAR1(mca);1651 MCA_Label_Rosenfeld_PAR1(mca); 2072 1652 pthread_barrier_wait(&main_barrier); 2073 1653 2074 1654 #if PARMERGE 2075 MCA_Label_ Features_Rosenfeld_PAR2(mca);1655 MCA_Label_Rosenfeld_PAR2(mca); 2076 1656 #else 2077 MCA_Label_ Features_Rosenfeld_PYR2(mca);1657 MCA_Label_Rosenfeld_PYR2(mca); 2078 1658 #endif 2079 1659 pthread_barrier_wait(&main_barrier); … … 2087 1667 CLOCK_THREAD_COMPUTE_END(mca->p); 2088 1668 1669 #if FEATURES 2089 1670 if (display_features) { 2090 1671 if (mca->p == 0) { 2091 1672 int i = 1; 2092 printf("[STATS]\n");1673 MCA_VERBOSE1(printf("[STATS]\n")); 2093 1674 for (int p = 0; p < mca->np; p++) { 2094 1675 MCA * mca_par = mca->mca->mcas[p]; … … 2097 1678 uint32 * T = mca_par->T; 2098 1679 RegionStats * stats = mca_par->stats; 2099 RegionStats_DisplayStats_Sparse(T, e0, e0 + ne, stats, NULL, &i); 2100 } 2101 printf("[/STATS]\n"); 2102 } 2103 } 1680 MCA_VERBOSE1(RegionStats_DisplayStats_Sparse(T, e0, e0 + ne, stats, NULL, &i)); 1681 } 1682 MCA_VERBOSE1(printf("[/STATS]\n")); 1683 } 1684 } 1685 #endif 2104 1686 2105 1687 CLOCK_THREAD_END(mca->p); … … 2113 1695 return NULL; 2114 1696 } 2115 #endif // FEATURES2116 1697 2117 1698
Note: See TracChangeset
for help on using the changeset viewer.