Changeset 821 for soft/giet_vm/applications/rosenfeld/src-par
- Timestamp:
- May 6, 2016, 3:06:29 PM (9 years ago)
- Location:
- soft/giet_vm/applications/rosenfeld/src-par
- Files:
-
- 2 added
- 1 deleted
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
soft/giet_vm/applications/rosenfeld/src-par/mca.c
r805 r821 15 15 #include <malloc.h> 16 16 17 #ifdef CLI18 17 #include "nrc_os_config.h" 18 #include "config.h" 19 19 #include "nrc.h" 20 #endif 21 20 21 #if TARGET_OS == GIETVM 22 #include <giet_config.h> 23 #endif 22 24 23 25 #include "util.h" 24 26 #include "ecc_common.h" 27 #include "ecc_features.h" 25 28 #include "mca_matrix_dist.h" 26 29 … … 34 37 35 38 36 // ---------------------- 39 // ----------------------- 37 40 void MCA_Error(char * msg) 38 // ---------------------- 41 // ----------------------- 39 42 { 40 43 printf("MCA ERROR: %s\n", msg); 41 44 printf("now exiting to system...\n"); 42 exit(1); 43 } 44 45 46 // --------------------- 47 void MCA_Zero(MCA * mca) 48 // --------------------- 49 { 45 exit(1); 50 46 } 51 47 … … 58 54 mca = (MCA *) malloc(sizeof(MCA)); 59 55 60 if (mca) { 61 MCA_Zero(mca); 62 } 63 else { 56 if (mca == NULL) { 64 57 MCA_Error("allocation failed in MCA_pConstructor_Empty"); 65 58 } … … 91 84 92 85 mca->j0 = 0; 93 mca->j1 = width -1;86 mca->j1 = width - 1; 94 87 } 95 88 … … 102 95 103 96 mca->i0 = 0; 104 mca->i1 = height -1;97 mca->i1 = height - 1; 105 98 } 106 99 … … 161 154 int j0_par, j1_par; 162 155 int height_par, height_mod; 163 156 164 157 int pw2; 165 158 int32 ne_par; // quantite par bande 166 159 uint32 nemax_par; // la puissance de 2 >= 167 160 uint32 e0_par, e1_par; // indice par bande [start..end] 161 int nb_level; 168 162 169 163 MCA ** mcas; 170 164 MCA * mca_par; 171 165 172 MCA_VERBOSE1(printf("====================\n")); 173 MCA_VERBOSE1(printf("== MCA_Initialize ==\n")); 174 MCA_VERBOSE1(printf("====================\n")); 175 176 MCA_VERBOSE1(printf("height = %d\n", height)); 177 MCA_VERBOSE1(printf("width = %d\n", width)); 166 printf("*** %s ***\n", __func__); 167 MCA_VERBOSE1(printf(" height = %d\n", height)); 168 MCA_VERBOSE1(printf(" width = %d\n", width)); 178 169 179 170 // array of pointers to mca workers … … 187 178 height_par = height / np; 188 179 height_mod = height % np; 189 //if(height % np) height_par++; 190 MCA_VERBOSE1(printf("height_par = %d x %d + %d\n", height_par, np, height_mod)); 191 192 MCA_VERBOSE1(printf("========================\n")); 180 181 MCA_VERBOSE1(printf(" height_par = %d x %d + %d\n", height_par, np, height_mod)); 182 MCA_VERBOSE1(printf(" ========================\n")); 193 183 194 184 i1_par_previous = 0; 195 196 for (int p = 0; p < np; p++) { 185 186 // puissance de 2 de chaque bande 187 ne_par = height_par * width + 1; 188 MCA_VERBOSE1(printf(" ne_par = %d\n", ne_par)); 189 pw2 = i32log2(ne_par); 190 if (ne_par > (1 << pw2)) { 191 pw2++; 192 } 193 nemax_par = 1 << pw2; 194 195 MCA_VERBOSE1(printf(" nemax_par = %d\n", nemax_par)); 196 197 nb_level = i32log2(np); 198 if ((1 << nb_level) < np) { 199 nb_level++; 200 } 201 202 #if PYR_BARRIERS 203 // ------------------------------------------ 204 // -- Allocation des barriÚres pyramidales -- 205 // ------------------------------------------ 206 207 pthread_barrier_t * barriers = NULL; 208 if (nb_level > 0) { 209 barriers = malloc(sizeof(pthread_barrier_t) * nb_level); 210 211 // Initially all threads are active except thread 0 212 int nb_active = np - 1; 213 pthread_barrier_init(&barriers[0], NULL, nb_active); 214 for (int i = 1; i < nb_level; i++) { 215 // thread 0 never does any merge 216 for (int p = 1; p < np; p++) { 217 if ((p + (1 << (i - 1))) % (1 << i) == 0) { 218 // thread inactive at level i 219 nb_active -= 1; 220 } 221 } 222 pthread_barrier_init(&barriers[i], NULL, nb_active); 223 } 224 } 225 #endif 226 227 for (int p = 0; p < np; p++) { 228 197 229 // ----------------- // 198 230 // -- constructor -- // 199 231 // ----------------- // 200 MCA_VERBOSE 1(printf("-- p = %d ----------------\n", p));232 MCA_VERBOSE2(printf("-- p = %d ----------------\n", p)); 201 233 202 234 // alloc of mca workers into array of pointers … … 208 240 mca_par->p = p; 209 241 mca_par->mca = mca; // pointer to master 242 #if TARGET_OS == GIETVM 243 int x, y; // cluster coordinates 244 // We have p == 4 => x = 0; y = 1 245 x = (p / NB_PROCS_MAX) / Y_SIZE; 246 y = (p / NB_PROCS_MAX) % Y_SIZE; 247 MCA_VERBOSE2(printf("p = %d (x = %d, y = %d)\n", p, x, y)); 248 #endif 210 249 211 250 // ------------------------------------- // … … 214 253 215 254 // hauteur de chaque bande 216 217 //printf("i1_par_previous = %d\n", i1_par_previous);218 219 255 if (p == 0) { 220 256 i0_par = 0; … … 232 268 i1_par_previous = i1_par; 233 269 234 MCA_VERBOSE1(printf("i0_par = %d\n", i0_par)); 235 MCA_VERBOSE1(printf("i1_par = %d\n", i1_par)); 236 237 // puissance de 2 de chaque bande 238 ne_par = height_par * width + 1; 239 //if (p == 0) { 240 // ne_par++; 241 //} 242 MCA_VERBOSE1(printf("ne_par = %d\n", ne_par)); 243 pw2 = i32log2(ne_par); 244 if (ne_par > (1 << pw2)) { 245 pw2++; 246 } 247 nemax_par = 1 << pw2; 248 MCA_VERBOSE1(printf("nemax_par = %d\n", nemax_par)); 270 MCA_VERBOSE2(printf("i0_par = %d\n", i0_par)); 271 MCA_VERBOSE2(printf("i1_par = %d\n", i1_par)); 249 272 250 273 // etiquettes … … 260 283 MCA_VERBOSE2(printf("e0_par = %d\n", e0_par)); 261 284 MCA_VERBOSE2(printf("e1_par = %d\n", e1_par)); 262 285 263 286 mca_par->width = width; 264 287 mca_par->height = height_par; 265 266 288 mca_par->i0 = i0_par; 267 289 mca_par->i1 = i1_par; 268 290 mca_par->j0 = 0; 269 291 mca_par->j1 = width - 1; 270 271 292 mca_par->e0 = e0_par; 272 293 mca_par->e1 = e1_par; 273 274 294 mca_par->alpha = pw2; 295 mca_par->np = np; 296 // Pour les barriÚres pyramidales 297 mca_par->nb_level = nb_level; 298 #if PYR_BARRIERS 299 mca_par->barriers = barriers; 300 #else 301 mca_par->barriers = NULL; 302 #endif 303 mca_par->F = NULL; // default init 304 mca_par->stats = NULL; // default init 275 305 276 306 // ---------------- // 277 307 // -- allocation -- // 278 308 // ---------------- // 279 309 #if TARGET_OS == GIETVM 310 mca_par->X = remote_ui8matrix(i0_par, i1_par, 0, width - 1, x, y); 311 mca_par->E = remote_dist_ui32matrix(i0_par, i1_par, 0, width - 1, x, y); // distributed matrix with border 312 313 if (p == 0) { 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 FEATURES 316 mca_par->stats = remote_RegionStatsVector(e0_par - 1, e1_par, x, y); 317 #endif 318 } 319 else { 320 mca_par->T = remote_ui32vector(e0_par, e1_par, x, y); 321 #if FEATURES 322 mca_par->stats = remote_RegionStatsVector(e0_par, e1_par, x, y); 323 #endif 324 } 325 326 mca_par->D = (uint32 **) remote_vvector(0, np - 1, x, y); 327 #if FEATURES 328 mca_par->F = (RegionStats **) remote_vvector(0, np - 1, x, y); 329 #endif 330 #else // !GIETVM 280 331 mca_par->X = ui8matrix (i0_par, i1_par, 0, width - 1); 281 332 mca_par->E = dist_ui32matrix(i0_par, i1_par, 0, width - 1); // distributed matrix with border … … 283 334 if (p == 0) { 284 335 mca_par->T = ui32vector(e0_par - 1, e1_par); // car e0 = 1, on a besoin que T[0] = 0 pour FindRoot 336 #if FEATURES 337 mca_par->stats = RegionStatsVector(e0_par - 1, e1_par); 338 339 #endif 285 340 } 286 341 else { 287 342 mca_par->T = ui32vector(e0_par, e1_par); 343 #if FEATURES 344 mca_par->stats = RegionStatsVector(e0_par, e1_par); 345 #endif 288 346 } 289 347 290 348 mca_par->D = (uint32 **) vvector(0, np - 1); 291 349 #if FEATURES 350 mca_par->F = (RegionStats **) vvector(0, np - 1); 351 #endif 352 #endif 292 353 MCA_VERBOSE2(printf("X = %p\n", mca_par->X)); 293 354 MCA_VERBOSE2(printf("E = %p\n", mca_par->E)); 294 355 MCA_VERBOSE2(printf("T = %p\n", mca_par->T)); 295 356 MCA_VERBOSE2(printf("D = %p\n", mca_par->D)); 296 297 357 } // p 298 358 299 // pour debug 300 MCA_VERBOSE2(printf("init des tables d'EQ a l'identite\n")); 301 for (int p = 0; p < np; p++) { 302 359 360 for (int p = 0; p < np; p++) { 303 361 MCA * mca_par = mcas[p]; 304 362 … … 319 377 MCA_VERBOSE2(printf("display des tables d'EQ\n")); 320 378 for (int p = 0; p < np; p++) { 321 322 379 MCA * mca_par = mcas[p]; 323 380 … … 326 383 uint32 e1 = mca_par->e1; 327 384 328 MCA_VERBOSE 1(printf("p = %d T[%d..%d]\n", p, e0, e1));385 MCA_VERBOSE2(printf("p = %d T[%d..%d]\n", p, e0, e1)); 329 386 if (p == 0) { 330 MCA_VERBOSE 1(display_ui32vector_number(T, e0 - 1, e0 + 10, "%5d", "T"));331 } 332 else { 333 MCA_VERBOSE 1(display_ui32vector_number(T, e0, e0 + 10, "%5d", "T"));387 MCA_VERBOSE2(display_ui32vector_number(T, e0 - 1, e0 + 10, "%5d", "T")); 388 } 389 else { 390 MCA_VERBOSE2(display_ui32vector_number(T, e0, e0 + 10, "%5d", "T")); 334 391 } 335 392 MCA_VERBOSE2(printf("\n")); … … 343 400 // table d'indirection distribuee D 344 401 MCA_VERBOSE2(printf("nemax_par = %d\n", nemax_par)); 345 346 for (int p = 0; p < np; p++) { 347 402 for (int p = 0; p < np; p++) { 348 403 MCA * mca_p = mcas[p]; 349 404 uint32 ** D = mca_p->D; 405 RegionStats ** F = mca_p->F; 350 406 351 407 for (int k = 0; k < np; k++) { 352 //mcas[p]->D[k] = (void*) (&(mcas[k]->T[mcas[k]->e0])) - mcas[k]->e0; //k * nemax_par;353 354 408 MCA * mca_k = mcas[k]; 355 409 uint32 * T = mca_k->T; 356 357 410 D[k] = T + k * nemax_par; // il faut soustraire le "MSB" 411 #if FEATURES 412 RegionStats * stat = mca_k->stats; 413 F[k] = stat + k * nemax_par; // il faut soustraire le "MSB" 414 #endif 358 415 } // k 359 416 } // p … … 376 433 MCA_VERBOSE2(display_ui32vector(D[k], 0, 9, "%5d", "D\n")); 377 434 } 378 printf("\n");435 MCA_VERBOSE2(printf("\n")); 379 436 } 380 437 … … 413 470 // ----------------------------------- 414 471 { 415 int p,np = mca->np;472 int np = mca->np; 416 473 417 474 MCA ** mcas = mca->mcas; 418 475 MCA * mca_par; 419 420 printf("============================\n"); 421 printf("== MCA_Display_Parameters ==\n"); 422 printf("============================\n"); 423 424 printf("height = %d\n", mca->height); 425 printf("width = %d\n", mca->width); 426 printf("np = %d\n", mca->np); 427 428 for (p = 0; p < np; p++) { 476 (void) mca_par; 477 478 printf("*** MCA_Display_Parameters ***\n"); 479 480 MCA_VERBOSE1(printf(" height = %d\n", mca->height)); 481 MCA_VERBOSE1(printf(" width = %d\n", mca->width)); 482 MCA_VERBOSE1(printf(" np = %d\n", mca->np)); 483 484 for (int p = 0; p < np; p++) { 429 485 mca_par = mcas[p]; 430 486 431 printf("Display MCA[%d]\n", p);432 printf("p = %d\n", mca_par->p);433 printf("i0 = %8d i1 = %8d\n", mca_par->i0, mca_par->i1);434 printf("j0 = %8d j1 = %8d\n", mca_par->j0, mca_par->j1);435 printf("e0 = %8d e1 = %8d\n", mca_par->e0, mca_par->e1);487 MCA_VERBOSE2(printf("Display MCA[%d]\n", p)); 488 MCA_VERBOSE2(printf("p = %d\n", mca_par->p)); 489 MCA_VERBOSE2(printf("i0 = %8d i1 = %8d\n", mca_par->i0, mca_par->i1)); 490 MCA_VERBOSE2(printf("j0 = %8d j1 = %8d\n", mca_par->j0, mca_par->j1)); 491 MCA_VERBOSE2(printf("e0 = %8d e1 = %8d\n", mca_par->e0, mca_par->e1)); 436 492 } 437 493 } … … 442 498 // ------------------------- 443 499 { 444 int p,np = mca->np;500 int np = mca->np; 445 501 446 502 MCA ** mcas = mca->mcas; … … 451 507 uint32 e0, e1; 452 508 453 printf("==================\n"); 454 printf("== MCA_Finalize ==\n"); 455 printf("==================\n"); 456 457 for (p = 0; p < np; p++) { 458 509 printf("*** MCA_Finalize ***\n"); 510 511 #if PYR_BARRIERS 512 free(mcas[0]->barriers); 513 #endif 514 515 for (int p = 0; p < np; p++) { 459 516 mca_par = mcas[p]; 460 517 … … 475 532 if (p == 0) { 476 533 free_ui32vector(mca_par->T, e0 - 1, e1); // car e0 = 1, on a besoin que T[0] = 0 pour FindRoot 534 #if FEATURES 535 free_RegionStatsVector(mca_par->stats, e0 - 1, e1); 536 #endif 477 537 } 478 538 else { 479 539 free_ui32vector(mca_par->T, e0, e1); 540 #if FEATURES 541 free_RegionStatsVector(mca_par->stats, e0, e1); 542 #endif 480 543 } 481 544 482 545 free_vvector((void **) mca_par->D, 0, np - 1); 483 484 } 485 printf("[MCA_Finalize]: fin boucle\n"); 546 #if FEATURES 547 free_vvector((void **) mca_par->F, 0, np - 1); 548 #endif 549 free(mca_par); 550 } 486 551 free(mcas); 487 printf("[MCA_Finalize]: mcas freed\n"); 488 free(mca); // plante si free XET, ne plante pas si pas de free ... 489 printf("[MCA_Finalize]: mca freed\n"); 490 } 491 492 493 // @QM check my modifs... 552 free(mca); 553 } 554 555 494 556 // ------------------------------- 495 557 void MCA_Scatter_ImageX(MCA * mca) … … 498 560 // diffusion de l'image binaire source 499 561 500 int 562 int np = mca->np; 501 563 uint8 ** X = mca->mca->X; 502 564 503 565 if (mca->p == 0) { 504 MCA_VERBOSE1(printf("------------------------\n")); 505 MCA_VERBOSE1(printf("-- MCA_Scatter_ImageX --\n")); 506 MCA_VERBOSE1(printf("------------------------\n")); 566 printf("*** MCA_Scatter_ImageX ***\n"); 507 567 } 508 568 … … 524 584 525 585 526 // @QM check my modifs...527 586 // ------------------------------ 528 587 void MCA_Gather_ImageL(MCA * mca) … … 532 591 int np = mca->np; 533 592 uint32 ** E = mca->mca->E; 593 594 if (mca->p == 0) { 595 printf("*** MCA_Gather_ImageL ***\n"); 596 } 534 597 535 598 int i0 = mca->i0; -
soft/giet_vm/applications/rosenfeld/src-par/mca_main.c
r805 r821 1 1 /* ------------------ */ 2 /* --- mca .c --- */2 /* --- mca_main.c --- */ 3 3 /* ------------------ */ 4 4 … … 12 12 #include <string.h> 13 13 #include <math.h> 14 15 #include <user_lock.h> 16 17 #ifdef CLI 14 #include <malloc.h> 15 18 16 #include "nrc_os_config.h" 17 #include "config.h" 19 18 #include "nrc.h" 20 #endif 21 19 20 #if TARGET_OS == GIETVM 21 #include <user_lock.h> 22 #include <malloc.h> 23 #include <giet_config.h> 24 #include <user_barrier.h> 25 #else 26 #include <unistd.h> 27 #endif 22 28 23 29 #include "util.h" 24 30 #include "ecc_common.h" 25 31 #include "ecc_features.h" 26 27 32 #include "palette.h" 28 33 #include "bmpNR.h" 29 34 #include "mca_matrix_dist.h" 35 #include "mca_rosenfeld.h" 36 #include "clock.h" 30 37 #include "str_ext.h" 38 31 39 32 40 /* -- local -- */ 33 41 #include "mca.h" 34 #include "mca_test.h" 35 36 42 43 #define MAX_THREADS 256 44 #define DEFAULT_NTHREADS 1 45 #define DEFAULT_IN_FILENAME "/misc/cadastre.pgm" 46 #define DEFAULT_OUT_FILENAME "out.bmp" 47 48 pthread_t thread_table[MAX_THREADS]; 49 pthread_barrier_t main_barrier; 50 int display_features = 0; 51 int generate_output_image = 0; 52 53 CLOCK_DEC; 54 55 static void usage(char * name) { 56 printf("Usage: %s <options>\n", name); 57 printf("options:\n"); 58 printf(" -i <input_file> : Input file (default = %s)\n", DEFAULT_IN_FILENAME); 59 printf(" -o <output_file> : Output file (default = %s)\n", DEFAULT_OUT_FILENAME); 60 printf(" -nN : N = number of threads (default = %d).\n", DEFAULT_NTHREADS); 61 printf(" -d : Display features (default = false, requires features computation).\n"); 62 printf(" -g : Generate output image (default = false).\n"); 63 printf(" -h : Print out command line options.\n\n"); 64 } 65 66 67 68 // -------------------------------------------------------------------------- 69 void init_forme_boulon1(uint8 *** X0, int * i0, int * i1, int * j0, int * j1) 70 // -------------------------------------------------------------------------- 71 { 72 uint8 ** X; 73 int i = 0; 74 int h = 28; 75 int w = 30; 76 77 X = ui8matrix(0, h - 1, 0, w - 1); 78 zero_ui8matrix(X, 0, h - 1, 0, w - 1); 79 80 *X0 = X; 81 *i0 = 0; 82 *i1 = h - 1; 83 *j0 = 0; 84 *j1 = w - 1; 85 86 // 0000000001111111111122222222223 87 // 0123456789012345678901234567890 88 set_ui8vector_str(X[i++], 0, w - 1, " 111 "); // 00 89 set_ui8vector_str(X[i++], 0, w - 1, " 11111 "); // 01 90 set_ui8vector_str(X[i++], 0, w - 1, " 1111111 "); // 02 91 set_ui8vector_str(X[i++], 0, w - 1, " 11111111 "); // 03 92 set_ui8vector_str(X[i++], 0, w - 1, " 1111111111"); // 04 93 set_ui8vector_str(X[i++], 0, w - 1, " 11111111111"); // 05 94 set_ui8vector_str(X[i++], 0, w - 1, " 1111111111111"); // 06 95 set_ui8vector_str(X[i++], 0, w - 1, " 11111111111111 "); // 07 96 set_ui8vector_str(X[i++], 0, w - 1, " 11111111111111 "); // 08 97 set_ui8vector_str(X[i++], 0, w - 1, " 11111111111111 "); // 09 98 set_ui8vector_str(X[i++], 0, w - 1, " 11 11111111111111 "); // 10 99 set_ui8vector_str(X[i++], 0, w - 1, " 111 11111111111111 "); // 11 100 set_ui8vector_str(X[i++], 0, w - 1, " 11111111111111111111 "); // 12 101 set_ui8vector_str(X[i++], 0, w - 1, " 11111111111111111111 "); // 13 102 set_ui8vector_str(X[i++], 0, w - 1, "1111111111111111111 "); // 14 103 set_ui8vector_str(X[i++], 0, w - 1, " 11111111111111111 "); // 15 104 set_ui8vector_str(X[i++], 0, w - 1, " 1111111111111111 "); // 16 105 set_ui8vector_str(X[i++], 0, w - 1, " 111111111111111 "); // 17 106 set_ui8vector_str(X[i++], 0, w - 1, " 111111111111 "); // 18 107 set_ui8vector_str(X[i++], 0, w - 1, " 1111111111 "); // 29 108 set_ui8vector_str(X[i++], 0, w - 1, " 1111111111 "); // 20 109 set_ui8vector_str(X[i++], 0, w - 1, " 111111111 "); // 21 110 set_ui8vector_str(X[i++], 0, w - 1, " 111111111 "); // 22 111 set_ui8vector_str(X[i++], 0, w - 1, " 11111111 "); // 23 112 set_ui8vector_str(X[i++], 0, w - 1, " 1111111 "); // 24 113 set_ui8vector_str(X[i++], 0, w - 1, " 11111 "); // 25 114 set_ui8vector_str(X[i++], 0, w - 1, " 111 "); // 26 115 set_ui8vector_str(X[i++], 0, w - 1, " "); // 27 116 117 //printf("[init_forme_boulon1]: h = %d i = %d\n", h, i); 118 if (i != h) { 119 MCA_Error("init_forme_boulon1 i != h"); 120 } 121 122 123 //display_ui8matrix_positive(X, 0, h-1, 0, w-1, 4, "forme_boulon1"); printf(""); 124 //write_ui8matrix_positive( X, 0, h-1, 0, w-1, 4, "forme_boulon1.txt"); 125 } 126 127 128 // QM : The cost of this function is horrible 129 // but it is only for testing purpose 130 // Renumbers object in a contiguous way, for an image which has already 131 // 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 table 138 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 } 162 } 163 } 164 } 165 free(equiv); 166 } 167 168 169 // ---------------------------- 170 void mca_test1(int num_threads) 171 // ---------------------------- 172 { 173 int i0, i1, j0, j1; 174 int height, width; 175 176 uint8 ** X0; 177 uint32 ** E; 178 MCA * mca; 179 180 pthread_barrier_init(&main_barrier, NULL, num_threads); 181 182 // -- Allocation -- 183 init_forme_boulon1(&X0, &i0, &i1, &j0, &j1); 184 185 height = i1 - i0 + 1; 186 width = j1 - j0 + 1; 187 188 E = ui32matrix(i0, i1, j0, j1); 189 190 zero_ui32matrix(E, i0, i1, j0, j1); 191 192 mca = MCA_pConstructor_Empty(); 193 194 // -- set param 195 MCA_Set_Size(mca, width, height); 196 MCA_Set_ImageX(mca, X0); 197 MCA_Set_ImageL(mca, E); 198 MCA_Set_NP(mca, num_threads); 199 200 // -- MCA init 201 MCA_Initialize(mca); 202 MCA_Display_Parameters(mca); 203 204 display_ui8matrix_positive(mca->X, i0, i1, j0, j1, 5, "X0"); 205 #if FEATURES 206 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 #else 211 for (int i = 1; i < num_threads; i++) { 212 pthread_create(&thread_table[i], NULL, MCA_Label_Rosenfeld, (void *) mca->mcas[i]); 213 } 214 MCA_Label_Rosenfeld(mca->mcas[0]); 215 #endif 216 for (int i = 1; i < num_threads; i++) { 217 pthread_join(thread_table[i], NULL); 218 } 219 display_ui32matrix_positive(mca->E, i0, i1, j0, j1, 5, "Efinal"); 220 221 222 // -- free -- 223 printf("Finalize\n"); 224 MCA_Finalize(mca); 225 226 printf("Free_matrix\n"); 227 free_ui8matrix (X0, i0, i1, j0, j1); 228 free_ui32matrix(E, i0, i1, j0, j1); 229 } 230 231 232 233 // ----------------------------------------------------------- 234 void mca_test2(int num_threads, char * infile, char * outfile) 235 // ----------------------------------------------------------- 236 { 237 int i0, i1, j0, j1; 238 int height, width; 239 240 uint8 ** X; 241 uint8 ** E8; 242 uint32 ** E; 243 MCA * mca; 244 245 RGBQuad palette[256]; 246 247 pthread_barrier_init(&main_barrier, NULL, num_threads); 248 249 Palette_18ColorsBW(palette); 250 251 printf("Loading file %s... ", infile); 252 X = LoadPGM_ui8matrix(infile, &i0, &i1, &j0, &j1); 253 printf("done.\n"); 254 255 printf("Allocating memory... "); 256 height = i1 - i0 + 1; 257 width = j1 - j0 + 1; 258 259 E8 = ui8matrix (i0, i1, j0, j1); 260 E = ui32matrix(i0, i1, j0, j1); 261 262 zero_ui8matrix(E8, i0, i1, j0, j1); 263 zero_ui32matrix(E, i0, i1, j0, j1); 264 265 // pre-traitements 266 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"); 270 mca = MCA_pConstructor_Empty(); 271 272 // -- set param 273 MCA_Set_Size(mca, width, height); 274 MCA_Set_ImageX(mca, X); 275 MCA_Set_ImageL(mca, E); 276 MCA_Set_NP(mca, num_threads); 277 278 // -- MCA init 279 MCA_Initialize(mca); 280 MCA_Display_Parameters(mca); 281 printf("End of MCA allocation and initialization.\n"); 282 283 CLOCK_APP_CREATE; 284 #if FEATURES 285 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 #else 290 for (int i = 1; i < num_threads; i++) { 291 pthread_create(&thread_table[i], NULL, MCA_Label_Rosenfeld, (void *) mca->mcas[i]); 292 } 293 MCA_Label_Rosenfeld(mca->mcas[0]); 294 #endif 295 for (int i = 1; i < num_threads; i++) { 296 pthread_join(thread_table[i], NULL); 297 } 298 CLOCK_APP_JOIN; 299 300 if (generate_output_image) { 301 #if TARGET_OS != GIETVM 302 renumber_image(mca->E, i0, i1, j0, j1); 303 #else 304 printf("Warning: the output image has not been renumbered, it cannot be used as a comparison with the reference\n"); 305 #endif 306 mod_ui32matrix_ui8matrix(mca->E, i0, i1, j0, j1, E8); 307 printf("Saving file %s for verification... ", outfile); 308 SaveBMP2_ui8matrix(E8, width, height, palette, outfile); 309 printf("done.\n"); 310 } 311 312 MCA_Finalize(mca); 313 printf("Deallocating memory..."); 314 free_ui8matrix (X, i0, i1, j0, j1); 315 free_ui8matrix (E8, i0, i1, j0, j1); 316 free_ui32matrix(E, i0, i1, j0, j1); 317 printf("done.\n"); 318 } 319 320 321 // -------------------------------------------------------------- 322 int main_test_mca(int num_threads, char * infile, char * outfile) 323 // -------------------------------------------------------------- 324 { 325 CLOCK_INIT(num_threads, 4); // 4 = Number of steps in body 326 CLOCK_APP_START; 327 328 mca_test2(num_threads, infile, outfile); 329 330 CLOCK_APP_END; 331 CLOCK_FINALIZE; 332 PRINT_CLOCK; 333 CLOCK_FREE; 334 335 return 0; 336 } 337 338 339 #if TARGET_OS == GIETVM 340 // ------------------------------------ 341 __attribute__((constructor)) int main() 342 // ------------------------------------ 343 #else 37 344 // ----------------------------- 38 __attribute__((constructor)) void main()345 int main(int argc, char ** argv) 39 346 // ----------------------------- 40 { 347 #endif 348 { 349 char * infile = DEFAULT_IN_FILENAME; 350 char * outfile = DEFAULT_OUT_FILENAME; 351 352 int ch; 353 int num_threads = DEFAULT_NTHREADS; 354 355 printf("*** Starting application Rosenfeld ***\n"); 356 357 #if TARGET_OS != GIETVM // @QM I think the giet has some random (uninitialized) values for argc and argv 358 while ((ch = getopt(argc, argv, "i:o:n:hdg")) != EOF) { 359 switch (ch) { 360 case 'i': 361 infile = optarg; 362 break; 363 case 'o': 364 outfile = optarg; 365 break; 366 case 'n': 367 num_threads = atoi(optarg); 368 break; 369 case 'h': 370 usage(argv[0]); 371 return 0; 372 break; 373 case 'd': 374 #if !FEATURES 375 fprintf(stderr, "*** Error: Features display requires features computation\n"); 376 return 1; 377 #endif 378 display_features = 1; 379 break; 380 case 'g': 381 generate_output_image = 1; 382 break; 383 default: 384 usage(argv[0]); 385 return 1; 386 break; 387 } 388 } 389 390 // Check arguments 391 if (num_threads < 1) { 392 fprintf(stderr, "*** Error: The number of threads must at least be 1\n"); 393 usage(argv[0]); 394 return -1; 395 } 396 #endif 397 398 #if TARGET_OS == GIETVM 399 { 400 unsigned int xsize, ysize, nprocs; 401 giet_procs_number(&xsize, &ysize, &nprocs); 402 num_threads = xsize * ysize * nprocs; 403 } 404 #endif 405 406 if (num_threads > MAX_THREADS) { 407 printf("*** Error: The maximum number of threads is %d, i.e. less than the current number of threads.\n", MAX_THREADS); 408 printf("Please recompile with a bigger MAX_THREADS value.\n"); 409 exit(1); 410 } 411 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); 416 #if FAST 417 printf("- Using decision trees (fast): yes\n"); 418 #elif SLOW 419 printf("- Using decision trees (fast): no\n"); 420 #endif 421 #if FEATURES 422 printf("- Computing features: yes\n"); 423 #else 424 printf("- Computing features: no\n"); 425 #endif 426 427 41 428 #if TARGET_OS == GIETVM 42 429 giet_tty_alloc(1); 43 heap_init(0, 0); 44 #endif 45 lock_init(&print_lock); 46 main_test_mca(); 47 48 exit(0); 49 } 50 430 printf("Initializing heaps... "); 431 for (int i = 0; i < X_SIZE; i++) { 432 for (int j = 0; j < X_SIZE; j++) { 433 heap_init(i, j); 434 } 435 } 436 printf("done.\n"); 437 #endif 438 439 pthread_mutex_init(&print_lock, PTHREAD_PROCESS_PRIVATE); 440 main_test_mca(num_threads, infile, outfile); 441 442 return 0; 443 } 444 -
soft/giet_vm/applications/rosenfeld/src-par/mca_matrix_dist.c
r805 r821 14 14 #include <malloc.h> 15 15 16 #ifdef CLI17 16 #include "nrc_os_config.h" 18 17 #include "nrc.h" 19 #endif20 18 21 19 … … 61 59 } 62 60 61 #if TARGET_OS == GIETVM 62 // --------------------------------------------------------------------------- 63 uint32 ** remote_dist_ui32matrix(int i0, int i1, int j0, int j1, int x, int y) 64 // --------------------------------------------------------------------------- 65 { 66 int i; 67 int nrow = i1 - i0 + 1; 68 int ncol = j1 - j0 + 1; 69 uint32 ** m; 70 71 // allocate pointers to rows 72 m = (uint32 **) remote_malloc((nrow + 2) * sizeof(uint32 *), x, y); 73 if (!m) { 74 nrerror("allocation failure 1 in dist_ui32matrix()"); 75 } 76 m -= i0; 77 m += 1; 78 79 // allocate rows and set pointers to them 80 m[i0] = (uint32 *) remote_malloc((nrow * ncol + 1) * sizeof(uint32), x, y); 81 if (!m[i0]) { 82 nrerror("allocation failure 2 in dist_ui32matrix()"); 83 } 84 m[i0] -= j0; 85 86 for (i = i0 + 1; i <= i1; i++) { 87 m[i] = m[i - 1] + ncol; 88 } 89 90 // make borders to point to first and last lines 91 m[i0 - 1] = m[i0]; 92 m[i1 + 1] = m[i1]; 93 94 return m; 95 } 96 #endif 97 98 63 99 64 100 // ------------------------------------------------------------------- … … 66 102 // ------------------------------------------------------------------- 67 103 { 68 free( (FREE_ARG) (m[i0] + j0));69 free( (FREE_ARG) (m + i0 - 1));104 free(m[i0] + j0); 105 free(m + i0 - 1); 70 106 } 71 107 -
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.