| | 458 | === Translating `sections` === |
| | 459 | |
| | 460 | Say there are `numSections` sections. This number is known statically. |
| | 461 | |
| | 462 | {{{ |
| | 463 | #pragma omp sections |
| | 464 | #pragma omp section |
| | 465 | S1 // section 1 |
| | 466 | #pragma omp section |
| | 467 | S2 // section 2 |
| | 468 | ... |
| | 469 | }}} |
| | 470 | |
| | 471 | => |
| | 472 | |
| | 473 | {{{ |
| | 474 | { |
| | 475 | $domain(1) sections_dist = $omp_arrive_sections( |
| | 476 | team, section_id++, numSections); |
| | 477 | |
| | 478 | $for (int _omp_sid : sections_dist) { |
| | 479 | if(_omp_sid == 1) { // section 1 |
| | 480 | translate(S1); |
| | 481 | } |
| | 482 | if(_omp_sid == 2) { // section 2 |
| | 483 | translate(S2); |
| | 484 | } |
| | 485 | ... |
| | 486 | } |
| | 487 | $omp_barrier_and_flush(); |
| | 488 | } |
| | 489 | }}} |
| | 490 | |
| | 491 | === Translating `single` === |
| | 492 | |
| | 493 | {{{ |
| | 494 | #pragma omp single |
| | 495 | BLOCK |
| | 496 | }}} |
| | 497 | |
| | 498 | => |
| | 499 | |
| | 500 | {{{ |
| | 501 | { // single construct (begin) |
| | 502 | int _omp_single_dist = $omp_arrive_single( |
| | 503 | team, single_id++); |
| | 504 | |
| | 505 | if (_omp_tid == _omp_single_dist) { |
| | 506 | translate(S); |
| | 507 | } |
| | 508 | |
| | 509 | $omp_barrier_and_flush(team); |
| | 510 | } // single construct (end) |
| | 511 | }}} |
| | 512 | |
| 524 | | $domain loop_domain = {a..b-1}; |
| 525 | | $domain(1) my_iters = ($domain(1))$omp_arrive_loop(team, FOR_LOC++, loop_domain, STRATEGY); |
| 526 | | double _x=0.0, _y=0.0; // not the local view of the shared variable x/y |
| 527 | | |
| 528 | | $for (int i : my_iters) { |
| 529 | | translate(S) but replace x with _x and y with _y; |
| 530 | | } |
| 531 | | $omp_apply_assoc(x_shared, CIVL_SUM, &_x); |
| 532 | | $omp_apply_assoc(y_shared, CIVL_SUM, &_y); |
| | 576 | int tid = omp_get_thread_num(); |
| | 577 | |
| | 578 | sum += a[tid]; |
| | 579 | prod *= a[tid]; |
| | 580 | } |
| | 581 | }}} |
| | 582 | |
| | 583 | => |
| | 584 | |
| | 585 | {{{ |
| | 586 | int sum = sum_base; |
| | 587 | int prod = prod_base; |
| | 588 | |
| | 589 | { // parallel construct (begin) |
| | 590 | .. |
| | 591 | $parfor (..) { |
| | 592 | .. |
| | 593 | int *_omp_rdc_0_sum = ∑ |
| | 594 | int sum = 0; |
| | 595 | int *_omp_rdc_1_prod = ∏ |
| | 596 | int prod = 1; |
| | 597 | |
| | 598 | int tid = _omp_tid; |
| | 599 | |
| | 600 | sum += a[tid]; |
| | 601 | prod *= a[tid]; |
| | 602 | |
| | 603 | $omp_reduction_combine(ADD, _omp_rdc_0_sum, sum); |
| | 604 | $omp_reduction_combine(MULT, _omp_rdc_1_prod, prod); |
| | 605 | |
| | 606 | $omp_barrier_and_flush(team); //check data race |
| | 607 | .. |
| | 608 | } |
| | 609 | .. |
| | 610 | } // parallel construct (end) |
| | 611 | }}} |
| | 612 | |
| | 613 | ==== Case 2: for reduction ==== |
| | 614 | |
| | 615 | {{{ |
| | 616 | #pragma omp for reduction(+: fsum, isum) |
| | 617 | for (i=a; i<b; i+=c) { |
| | 618 | BLOCK |
| | 619 | fsum += EXPR0; |
| | 620 | isum += EXPR1; |
| | 621 | } |
| | 622 | }}} |
| | 623 | |
| | 624 | => |
| | 625 | |
| | 626 | {{{ |
| | 627 | { // worksharing-loop construct (begin) |
| | 628 | $domain loop_domain = {a..b-1#c}; |
| | 629 | $domain(1) loop_dist = ($domain(1))$omp_arrive_loop( |
| | 630 | team, loop_id++, loop_domain, STRATEGY); |
| | 631 | |
| | 632 | float *_omp_rdc_0_fsum = &fsum; |
| | 633 | float fsum = 0.0; |
| | 634 | int *_omp_rdc_1_isum = &isum; |
| | 635 | int isum = 0; |
| | 636 | |
| | 637 | $for (int i : loop_dist) { |
| | 638 | translate(BLOCK) |
| | 639 | fsum += translate(EXPR0); |
| | 640 | isum += translate(EXPR1); |
| | 641 | } |
| | 642 | |
| | 643 | $omp_reduction_combine(ADD, _omp_rdc_0_fsum, fsum); |
| | 644 | $omp_reduction_combine(ADD, _omp_rdc_1_isum, isum); |
| | 645 | |
| 534 | | } |
| 535 | | }}} |
| 536 | | |
| 537 | | |
| 538 | | |
| 539 | | === Translating `sections` === |
| 540 | | |
| 541 | | Say there are `numSections` sections. This number is known statically. |
| 542 | | |
| 543 | | {{{ |
| 544 | | #pragma omp sections |
| 545 | | #pragma omp section |
| 546 | | S0 // section 1 |
| 547 | | #pragma omp section |
| 548 | | S1 // section 2 |
| 549 | | ... |
| 550 | | }}} |
| 551 | | |
| 552 | | => |
| 553 | | |
| 554 | | {{{ |
| 555 | | { |
| 556 | | $domain(1) my_secs = $omp_arrive_sections(team, section_id++, numSections); |
| 557 | | |
| 558 | | $for (int i : my_secs) { |
| 559 | | |
| 560 | | if(section_id == 1) { |
| 561 | | translate(S0); |
| 562 | | } |
| 563 | | if(section_id == 2) { |
| 564 | | translate(S0); |
| 565 | | } |
| 566 | | ... |
| 567 | | } /* end of switch */ |
| 568 | | } /* end of $for loop */ |
| 569 | | $omp_barrier_and_flush(); |
| 570 | | } |
| 571 | | }}} |
| 572 | | |
| 573 | | |
| 574 | | === Translating `single` === |
| 575 | | |
| 576 | | {{{ |
| 577 | | #pragma omp single |
| 578 | | S |
| 579 | | }}} |
| 580 | | |
| 581 | | => |
| 582 | | |
| 583 | | {{{ |
| 584 | | int owner = $omp_arrive_single(team, SINGLE_LOC++); |
| 585 | | |
| 586 | | if (owner == _tid) { |
| 587 | | translate(S); |
| 588 | | } |
| 589 | | $omp_barrier_and_flush(team); |
| 590 | | }}} |
| 591 | | |
| | 647 | } // worksharing-loop construct (end) |
| | 648 | }}} |
| | 649 | |
| | 650 | In `Case1` the combination is performed in `$parfor` after the completion of |
| | 651 | the last statement in the original structured block. |
| | 652 | In `Case2` the combination is performed immediately after the end of `$for`. |