diff options
author | Tobias Burnus <tobias@codesourcery.com> | 2022-05-17 11:01:04 +0200 |
---|---|---|
committer | Tobias Burnus <tobias@codesourcery.com> | 2022-05-17 11:01:04 +0200 |
commit | 4f94c38a9237b728b3a3f76c169b5b47f6c45187 (patch) | |
tree | 2ec7b560f303f268bb602613d6ea0d3eff96e428 /libgomp | |
parent | ebce0e9bd8d714a8607ae24331a3d842b0d11859 (diff) | |
download | gcc-4f94c38a9237b728b3a3f76c169b5b47f6c45187.zip gcc-4f94c38a9237b728b3a3f76c169b5b47f6c45187.tar.gz gcc-4f94c38a9237b728b3a3f76c169b5b47f6c45187.tar.bz2 |
OpenMP: Add omp_all_memory support to Fortran
Fortran part to the C/C++/backend implementation
r13-337-g7f78783dbedca0183d193e475262ca3c489fd365
gcc/fortran/ChangeLog:
* dump-parse-tree.cc (show_omp_namelist): Handle omp_all_memory.
* openmp.cc (gfc_match_omp_variable_list, gfc_match_omp_depend_sink,
gfc_match_omp_clauses, resolve_omp_clauses): Likewise.
* trans-openmp.cc (gfc_trans_omp_clauses, gfc_trans_omp_depobj):
Likewise.
* resolve.cc (resolve_symbol): Reject it as symbol.
libgomp/ChangeLog:
* libgomp.texi (OpenMP 5.1): Set omp_all_memory to 'Y'.
* testsuite/libgomp.fortran/depend-5.f90: New test.
* testsuite/libgomp.fortran/depend-6.f90: New test.
* testsuite/libgomp.fortran/depend-7.f90: New test.
gcc/testsuite/ChangeLog:
* gfortran.dg/gomp/all-memory-1.f90: New test.
* gfortran.dg/gomp/all-memory-2.f90: New test.
* gfortran.dg/gomp/all-memory-3.f90: New test.
Diffstat (limited to 'libgomp')
-rw-r--r-- | libgomp/libgomp.texi | 4 | ||||
-rw-r--r-- | libgomp/testsuite/libgomp.fortran/depend-5.f90 | 121 | ||||
-rw-r--r-- | libgomp/testsuite/libgomp.fortran/depend-6.f90 | 126 | ||||
-rw-r--r-- | libgomp/testsuite/libgomp.fortran/depend-7.f90 | 113 |
4 files changed, 362 insertions, 2 deletions
diff --git a/libgomp/libgomp.texi b/libgomp/libgomp.texi index b5e5fbb..d9d86f3 100644 --- a/libgomp/libgomp.texi +++ b/libgomp/libgomp.texi @@ -274,7 +274,7 @@ The OpenMP 4.5 specification is fully supported. @multitable @columnfractions .60 .10 .25 @headitem Description @tab Status @tab Comments @item OpenMP directive as C++ attribute specifiers @tab Y @tab -@item @code{omp_all_memory} reserved locator @tab N @tab +@item @code{omp_all_memory} reserved locator @tab Y @tab @item @emph{target_device trait} in OpenMP Context @tab N @tab @item @code{target_device} selector set in context selectors @tab N @tab @item C/C++'s @code{declare variant} directive: elision support of @@ -283,7 +283,7 @@ The OpenMP 4.5 specification is fully supported. @code{append_args} @tab N @tab @item @code{dispatch} construct @tab N @tab @item device-specific ICV settings the environment variables @tab N @tab -@item assume directive @tab N @tab +@item @code{assume} directive @tab N @tab @item @code{nothing} directive @tab Y @tab @item @code{error} directive @tab Y @tab @item @code{masked} construct @tab Y @tab diff --git a/libgomp/testsuite/libgomp.fortran/depend-5.f90 b/libgomp/testsuite/libgomp.fortran/depend-5.f90 new file mode 100644 index 0000000..a350e79 --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/depend-5.f90 @@ -0,0 +1,121 @@ +! { dg-additional-sources my-usleep.c } +! { dg-prune-output "command-line option '-fintrinsic-modules-path=.*' is valid for Fortran but not for C" } + +module m + implicit none + + interface + subroutine usleep(t) bind(C, name="my_usleep") + use iso_c_binding + integer(c_int), value :: t + end subroutine + end interface + +contains +subroutine test (ifval) + logical, value :: ifval + integer :: a(0:7), b(0:7), i + + do i = 0, 7 + a(i) = i + b(i) = 2 * i + end do + !$omp parallel + block + !$omp single + block + !$omp task shared(a) depend(in: a(0)) + block + call usleep (5000) + a(0) = 42 + end block + !$omp task shared(a) depend(out: a(1)) + block + call usleep (5000) + a(1) = 43 + end block + !$omp task shared(a) depend(inout: a(2)) + block + call usleep (5000) + a(2) = 44 + end block + !$omp task shared(a) depend(mutexinoutset: a(3)) + block + call usleep (5000) + a(3) = 45 + end block + !$omp task shared(a) + block + call usleep (15000) + a(4) = 46 + end block + !$omp task shared(b) depend(in: b(0)) + block + call usleep (5000) + b(0) = 47 + end block + !$omp task shared(b) depend(in: b(4)) + block + call usleep (5000) + b(4) = 48 + end block + ! None of the above tasks depend on each other. + ! The following task depends on all but the a(4) = 46; one. + !$omp task shared(a, b) depend(out: omp_all_memory) private(i) if(ifval) + block + if (a(0) /= 42 .or. a(1) /= 43 .or. a(2) /= 44 .or. a(3) /= 45 & + .or. a(5) /= 5 .or. a(6) /= 6 .or. a(7) /= 7 & + .or. b(0) /= 47 .or. b(1) /= 2 .or. b(2) /= 4 .or. b(3) /= 6 & + .or. b(4) /= 48 .or. b(5) /= 10 .or. b(6) /= 12 .or. b(7) /= 14) & + error stop + do i = 0, 7 + if (i /= 4) & + a(i) = 3 * i + 7 + end do + do i = 0, 7 + b(i) = 4 * i - 7 + end do + end block + ! The following task depends on both b(0) = 47; and + ! above omp_all_memory tasks, but as the latter depends on + ! the former, effectively it is dependent just on the omp_all_memory + ! task. + !$omp task shared(b) depend(inout: b(0)) + block + call usleep (5000) + b(0) = 49 + end block + ! The following task depends on all the above except a(4) = 46; one, + ! but it can be reduced to dependency on the above omp_all_memory + ! one and b(0) = 49; one. + !$omp task shared(a, b) depend(inout: b(7), omp_all_memory, b(6)) & + !$omp& private(i) if(ifval) + block + do i = 0, 7 + if (i /= 4) then + if (a(i) /= 3 * i + 7) & + error stop + a(i) = 5 * i + 50 + end if + end do + if (b(0) /= 49) & + error stop + b(0) = 6 * i + 57 + do i = 1, 7 + if (b(i) /= 4 * i - 7) & + error stop + b(i) = 6 * i + 57 + end do + end block + !$omp taskwait + if (a(4) /= 46) & + error stop + end block ! end single + end block ! end parallel +end +end module m + +use m +call test(.true.) +call test(.false.) +end diff --git a/libgomp/testsuite/libgomp.fortran/depend-6.f90 b/libgomp/testsuite/libgomp.fortran/depend-6.f90 new file mode 100644 index 0000000..edea857 --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/depend-6.f90 @@ -0,0 +1,126 @@ +! { dg-additional-sources my-usleep.c } +! { dg-prune-output "command-line option '-fintrinsic-modules-path=.*' is valid for Fortran but not for C" } + +module m + use omp_lib + implicit none + + interface + subroutine usleep(t) bind(C, name="my_usleep") + use iso_c_binding + integer(c_int), value :: t + end subroutine + end interface + +contains +subroutine test (ifval) + logical, value :: ifval + integer :: a(0:7), b(0:7), i + integer(omp_depend_kind) d1, d2 + !$omp depobj (d1) depend(inout: omp_all_memory) + !$omp depobj (d2) depend(out: omp_all_memory) + do i = 0, 7 + a(i) = i + b(i) = 2 * i + end do + !$omp parallel + block + !$omp single + block + !$omp task shared(a) depend(in: a(0)) + block + call usleep (5000) + a(0) = 42 + end block + !$omp task shared(a) depend(out: a(1)) + block + call usleep (5000) + a(1) = 43 + end block + !$omp task shared(a) depend(inout: a(2)) + block + call usleep (5000) + a(2) = 44 + end block + !$omp task shared(a) depend(mutexinoutset: a(3)) + block + call usleep (5000) + a(3) = 45 + end block + !$omp task shared(a) + block + call usleep (15000) + a(4) = 46 + end block + !$omp task shared(b) depend(in: b(0)) + block + call usleep (5000) + b(0) = 47 + end block + !$omp task shared(b) depend(in: b(4)) + block + call usleep (5000) + b(4) = 48 + end block + ! None of the above tasks depend on each other. + ! The following task depends on all but the a(4) = 46; one. + !$omp task shared(a, b) depend(depobj: d1) private(i) if(ifval) + block + if (a(0) /= 42 .or. a(1) /= 43 .or. a(2) /= 44 .or. a(3) /= 45 & + .or. a(5) /= 5 .or. a(6) /= 6 .or. a(7) /= 7 & + .or. b(0) /= 47 .or. b(1) /= 2 .or. b(2) /= 4 .or. b(3) /= 6 & + .or. b(4) /= 48 .or. b(5) /= 10 .or. b(6) /= 12 .or. b(7) /= 14) & + error stop + do i = 0, 7 + if (i /= 4) & + a(i) = 3 * i + 7 + end do + do i = 0, 7 + b(i) = 4 * i - 7 + end do + end block + ! The following task depends on both b(0) = 47; and + ! above omp_all_memory tasks, but as the latter depends on + ! the former, effectively it is dependent just on the omp_all_memory + ! task. + !$omp task shared(b) depend(inout: b(0)) + block + call usleep (5000) + b(0) = 49 + end block + ! The following task depends on all the above except a(4) = 46; one, + ! but it can be reduced to dependency on the above omp_all_memory + ! one and b(0) = 49; one. + !$omp task shared(a, b) depend(inout: b(6)) depend(depobj: d2) & + !$omp& depend(out: b(7)) private(i) if(ifval) + block + do i = 0, 7 + if (i /= 4) then + if (a(i) /= 3 * i + 7) & + error stop + a(i) = 5 * i + 50 + end if + end do + if (b(0) /= 49) & + error stop + b(0) = 6 * i + 57 + do i = 1, 7 + if (b(i) /= 4 * i - 7) & + error stop + b(i) = 6 * i + 57 + end do + end block + !$omp taskwait + if (a(4) /= 46) & + error stop + end block + end block + !$omp depobj (d2) destroy + !$omp depobj (d1) destroy +end +end module m + +use m +call test (.true.) +call test (.false.) +end diff --git a/libgomp/testsuite/libgomp.fortran/depend-7.f90 b/libgomp/testsuite/libgomp.fortran/depend-7.f90 new file mode 100644 index 0000000..d3f3988 --- /dev/null +++ b/libgomp/testsuite/libgomp.fortran/depend-7.f90 @@ -0,0 +1,113 @@ +! { dg-additional-sources my-usleep.c } +! { dg-prune-output "command-line option '-fintrinsic-modules-path=.*' is valid for Fortran but not for C" } + +program main + implicit none + + interface + subroutine usleep(t) bind(C, name="my_usleep") + use iso_c_binding + integer(c_int), value :: t + end subroutine + end interface + + integer :: a(0:7), b(0:7), i + + do i = 0, 7 + a(i) = i + b(i) = 2 * i + end do + + !$omp parallel + block + !$omp single + block + !$omp task shared(a) depend(in: a(0)) + block + call usleep (5000) + a(0) = 42 + end block + !$omp task shared(a) depend(out: a(1)) + block + call usleep (5000) + a(1) = 43 + end block + !$omp task shared(a) depend(inout: a(2)) + block + call usleep (5000) + a(2) = 44 + end block + !$omp task shared(a) depend(mutexinoutset: a(3)) + block + call usleep (5000) + a(3) = 45 + end block + !$omp task shared(a) + block + call usleep (15000) + a(4) = 46 + end block + !$omp task shared(b) depend(in: b(0)) + block + call usleep (5000) + b(0) = 47 + end block + !$omp task shared(b) depend(in: b(4)) + block + call usleep (5000) + b(4) = 48 + end block + ! None of the above tasks depend on each other. + ! The following task depends on all but the a(4) = 46; one. + !$omp task shared(a, b) depend(iterator (j=0:7), inout: omp_all_memory) private(i) + block + if (a(0) /= 42 .or. a(1) /= 43 .or. a(2) /= 44 .or. a(3) /= 45 & + .or. a(5) /= 5 .or. a(6) /= 6 .or. a(7) /= 7 & + .or. b(0) /= 47 .or. b(1) /= 2 .or. b(2) /= 4 .or. b(3) /= 6 & + .or. b(4) /= 48 .or. b(5) /= 10 .or. b(6) /= 12 .or. b(7) /= 14) & + error stop + do i = 0, 7 + if (i /= 4) & + a(i) = 3 * i + 7 + end do + do i = 0, 7 + b(i) = 4 * i - 7 + end do + end block + ! The following task depends on both b(0) = 47; and + ! above omp_all_memory tasks, but as the latter depends on + ! the former, effectively it is dependent just on the omp_all_memory + ! task. + !$omp task shared(b) depend(inout: b(0)) + block + call usleep (5000) + b(0) = 49 + end block + ! The following task depends on all the above except a(4) = 46; one, + ! but it can be reduced to dependency on the above omp_all_memory + ! one and b(0) = 49; one. + !$omp task shared(a, b) depend(inout: b(7)) depend(iterator(j=4:5), out: omp_all_memory) & + !$omp& depend(inout: b(6)) private(i) + block + do i = 0, 7 + if (i /= 4) then + if (a(i) /= 3 * i + 7) & + error stop + a(i) = 5 * i + 50 + end if + end do + if (b(0) /= 49) & + error stop + b(0) = 6 * i + 57 + do i = 1, 7 + if (b(i) /= 4 * i - 7) & + error stop + b(i) = 6 * i + 57 + end do + end block + !$omp taskwait + if (a(4) /= 46) & + error stop + end block + end block +end program |