aboutsummaryrefslogtreecommitdiff
path: root/libgomp
diff options
context:
space:
mode:
authorTobias Burnus <tobias@codesourcery.com>2022-05-17 11:01:04 +0200
committerTobias Burnus <tobias@codesourcery.com>2022-05-17 11:01:04 +0200
commit4f94c38a9237b728b3a3f76c169b5b47f6c45187 (patch)
tree2ec7b560f303f268bb602613d6ea0d3eff96e428 /libgomp
parentebce0e9bd8d714a8607ae24331a3d842b0d11859 (diff)
downloadgcc-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.texi4
-rw-r--r--libgomp/testsuite/libgomp.fortran/depend-5.f90121
-rw-r--r--libgomp/testsuite/libgomp.fortran/depend-6.f90126
-rw-r--r--libgomp/testsuite/libgomp.fortran/depend-7.f90113
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