| 578 | | === Translating `reduction` clause === |
| 579 | | |
| | 579 | === Translating `master` === |
| | 580 | |
| | 581 | {{{ |
| | 582 | #pragma omp master |
| | 583 | S |
| | 584 | }}} |
| | 585 | |
| | 586 | => |
| | 587 | |
| | 588 | {{{ |
| | 589 | if (tid == 0) { |
| | 590 | translate(S); |
| | 591 | } |
| | 592 | }}} |
| | 593 | |
| | 594 | ([https://vsl.cis.udel.edu/trac/civl/wiki/Next-GenOpenMPTransformation#OpenMPConstructs back to top]) |
| | 595 | |
| | 596 | === Translating `barrier` === |
| | 597 | |
| | 598 | {{{ |
| | 599 | #pragma omp barrier |
| | 600 | }}} |
| | 601 | |
| | 602 | => |
| | 603 | |
| | 604 | {{{ |
| | 605 | $omp_barrier_and_flush(team); |
| | 606 | }}} |
| | 607 | |
| | 608 | ([https://vsl.cis.udel.edu/trac/civl/wiki/Next-GenOpenMPTransformation#OpenMPConstructs back to top]) |
| | 609 | |
| | 610 | === Translating `critical` === |
| | 611 | |
| | 612 | Basically, use a lock for each critical name, plus one for the "no name". All threads must obtain lock to enter the critical section, then release it. |
| | 613 | I.e., if there are critical sections name a, b, and c, there should be global root-scope variables of boolean type named `_critical_noname`, `_critical_a`, etc. |
| | 614 | |
| | 615 | {{{ |
| | 616 | #pragma omp critical(a) |
| | 617 | S |
| | 618 | }}} |
| | 619 | |
| | 620 | => |
| | 621 | |
| | 622 | {{{ |
| | 623 | ... |
| | 624 | _Bool _critical_a = $false; |
| | 625 | . |
| | 626 | . |
| | 627 | . |
| | 628 | $when (!_critical_a) _critical_a=$true; |
| | 629 | translate(S); |
| | 630 | _critical_a=$false; |
| | 631 | }}} |
| | 632 | |
| | 633 | ([https://vsl.cis.udel.edu/trac/civl/wiki/Next-GenOpenMPTransformation#OpenMPConstructs back to top]) |
| | 634 | |
| | 635 | === Translating `atomic` === |
| | 636 | |
| | 637 | In general, reads and writes to shared variables will be processed using the protocols described above. However if the operation occurs within an omp atomic construct, it is translated differently. |
| | 638 | |
| | 639 | TODO: need to look up the rules on the different flavors of atomics. |
| | 640 | |
| | 641 | If sequentially consistent atomic... |
| | 642 | |
| | 643 | If non-sequentially consistent atomic... |
| | 644 | |
| | 645 | ([https://vsl.cis.udel.edu/trac/civl/wiki/Next-GenOpenMPTransformation#OpenMPConstructs back to top]) |
| | 646 | |
| | 647 | === Translating`ordered` === |
| | 648 | |
| | 649 | This can only be used inside and OMP `for` loop in which the pragma used the `ordered` clause. (Check that.) It indicates that the specified region must be executed in iteration order. |
| | 650 | |
| | 651 | In this case the system function must return an int iterator in which the ints occur in loop order. |
| | 652 | |
| | 653 | {{{ |
| | 654 | #pragma omp for ordered |
| | 655 | for (i=a; i<b; i++) { |
| | 656 | ... |
| | 657 | #pragma omp ordered |
| | 658 | S1 |
| | 659 | ... |
| | 660 | #pragma omp ordered |
| | 661 | S2 |
| | 662 | ... |
| | 663 | } |
| | 664 | }}} |
| | 665 | |
| | 666 | => |
| | 667 | |
| | 668 | {{{ |
| | 669 | { |
| | 670 | $domain loop_domain = {a..b}; |
| | 671 | $domain(1) my_iters = ($domain(1))$omp_arrive_loop(team, FOR_LOC++, loop_domain, STRATEGY); |
| | 672 | int order1=a, order2=a; |
| | 673 | |
| | 674 | $for (int i : my_iters) { |
| | 675 | ... |
| | 676 | $when (order1==i) { |
| | 677 | translate(S1); |
| | 678 | order1++; |
| | 679 | } |
| | 680 | ... |
| | 681 | $when (order2==i) { |
| | 682 | translate(S2); |
| | 683 | order2++; |
| | 684 | } |
| | 685 | ... |
| | 686 | } |
| | 687 | } |
| | 688 | }}} |
| | 689 | |
| | 690 | ([https://vsl.cis.udel.edu/trac/civl/wiki/Next-GenOpenMPTransformation#OpenMPConstructs back to top]) |
| | 691 | |
| | 692 | === Translating `nowait` === |
| | 693 | |
| | 694 | Just leave out the `$omp_barrier_and_flush` at the end of the translated construct. |
| | 695 | |
| | 696 | ([https://vsl.cis.udel.edu/trac/civl/wiki/Next-GenOpenMPTransformation#OpenMPConstructs back to top]) |
| | 697 | |
| | 698 | === Translating `reduction` === |
| 666 | | |
| 667 | | === Translating `master` === |
| 668 | | |
| 669 | | {{{ |
| 670 | | #pragma omp master |
| 671 | | S |
| 672 | | }}} |
| 673 | | |
| 674 | | => |
| 675 | | |
| 676 | | {{{ |
| 677 | | if (tid == 0) { |
| 678 | | translate(S); |
| 679 | | } |
| 680 | | }}} |
| 681 | | |
| 682 | | ([https://vsl.cis.udel.edu/trac/civl/wiki/Next-GenOpenMPTransformation#OpenMPConstructs back to top]) |
| 683 | | |
| 684 | | === Translating `barrier` === |
| 685 | | |
| 686 | | {{{ |
| 687 | | #pragma omp barrier |
| 688 | | }}} |
| 689 | | |
| 690 | | => |
| 691 | | |
| 692 | | {{{ |
| 693 | | $omp_barrier_and_flush(team); |
| 694 | | }}} |
| 695 | | |
| 696 | | ([https://vsl.cis.udel.edu/trac/civl/wiki/Next-GenOpenMPTransformation#OpenMPConstructs back to top]) |
| 697 | | |
| 698 | | === Translating `critical` === |
| 699 | | |
| 700 | | Basically, use a lock for each critical name, plus one for the "no name". All threads must obtain lock to enter the critical section, then release it. |
| 701 | | I.e., if there are critical sections name a, b, and c, there should be global root-scope variables of boolean type named `_critical_noname`, `_critical_a`, etc. |
| 702 | | |
| 703 | | {{{ |
| 704 | | #pragma omp critical(a) |
| 705 | | S |
| 706 | | }}} |
| 707 | | |
| 708 | | => |
| 709 | | |
| 710 | | {{{ |
| 711 | | ... |
| 712 | | _Bool _critical_a = $false; |
| 713 | | . |
| 714 | | . |
| 715 | | . |
| 716 | | $when (!_critical_a) _critical_a=$true; |
| 717 | | translate(S); |
| 718 | | _critical_a=$false; |
| 719 | | }}} |
| 720 | | |
| 721 | | ([https://vsl.cis.udel.edu/trac/civl/wiki/Next-GenOpenMPTransformation#OpenMPConstructs back to top]) |
| 722 | | |
| 723 | | === Translating `atomic` === |
| 724 | | |
| 725 | | In general, reads and writes to shared variables will be processed using the protocols described above. However if the operation occurs within an omp atomic construct, it is translated differently. |
| 726 | | |
| 727 | | TODO: need to look up the rules on the different flavors of atomics. |
| 728 | | |
| 729 | | If sequentially consistent atomic... |
| 730 | | |
| 731 | | If non-sequentially consistent atomic... |
| 732 | | |
| 733 | | ([https://vsl.cis.udel.edu/trac/civl/wiki/Next-GenOpenMPTransformation#OpenMPConstructs back to top]) |
| 734 | | |
| 735 | | === Translating`ordered` === |
| 736 | | |
| 737 | | This can only be used inside and OMP `for` loop in which the pragma used the `ordered` clause. (Check that.) It indicates that the specified region must be executed in iteration order. |
| 738 | | |
| 739 | | In this case the system function must return an int iterator in which the ints occur in loop order. |
| 740 | | |
| 741 | | {{{ |
| 742 | | #pragma omp for ordered |
| 743 | | for (i=a; i<b; i++) { |
| 744 | | ... |
| 745 | | #pragma omp ordered |
| 746 | | S1 |
| 747 | | ... |
| 748 | | #pragma omp ordered |
| 749 | | S2 |
| 750 | | ... |
| 751 | | } |
| 752 | | }}} |
| 753 | | |
| 754 | | => |
| 755 | | |
| 756 | | {{{ |
| 757 | | { |
| 758 | | $domain loop_domain = {a..b}; |
| 759 | | $domain(1) my_iters = ($domain(1))$omp_arrive_loop(team, FOR_LOC++, loop_domain, STRATEGY); |
| 760 | | int order1=a, order2=a; |
| 761 | | |
| 762 | | $for (int i : my_iters) { |
| 763 | | ... |
| 764 | | $when (order1==i) { |
| 765 | | translate(S1); |
| 766 | | order1++; |
| 767 | | } |
| 768 | | ... |
| 769 | | $when (order2==i) { |
| 770 | | translate(S2); |
| 771 | | order2++; |
| 772 | | } |
| 773 | | ... |
| 774 | | } |
| 775 | | } |
| 776 | | }}} |
| 777 | | |
| 778 | | ([https://vsl.cis.udel.edu/trac/civl/wiki/Next-GenOpenMPTransformation#OpenMPConstructs back to top]) |
| 779 | | |
| 780 | | === Translating `nowait` === |
| 781 | | |
| 782 | | Just leave out the `$omp_barrier_and_flush` at the end of the translated construct. |