OpenMP: Add Fortran support for inoutset depend-kind

Fortran additions to the C/C++ + ME/libgomp commit
r13-556-g2c16eb3157f86ae561468c540caf8eb326106b5f

gcc/fortran/ChangeLog:

	* gfortran.h (enum gfc_omp_depend_op): Add OMP_DEPEND_INOUTSET.
	(gfc_omp_clauses): Enlarge ENUM_BITFIELD.
	* dump-parse-tree.cc (show_omp_namelist, show_omp_clauses): Handle
	'inoutset' depend modifier.
	* openmp.cc (gfc_match_omp_clauses, gfc_match_omp_depobj): Likewise.
	* trans-openmp.cc (gfc_trans_omp_clauses, gfc_trans_omp_depobj):
	Likewise.

libgomp/ChangeLog:

	* libgomp.texi (OpenMP 5.1): Set 'inoutset' to Y.
	(OpenMP Context Selectors): Add missing comma.
	* testsuite/libgomp.fortran/depend-5.f90: Add inoutset test.
	* testsuite/libgomp.fortran/depend-6.f90: Likewise.
	* testsuite/libgomp.fortran/depend-7.f90: Likewise.
	* testsuite/libgomp.fortran/depend-inoutset-1.f90: New test.

gcc/testsuite/ChangeLog:

	* gfortran.dg/gomp/all-memory-1.f90: Add inoutset test.
	* gfortran.dg/gomp/all-memory-2.f90: Likewise.
	* gfortran.dg/gomp/depobj-1.f90: Likewise.
	* gfortran.dg/gomp/depobj-2.f90: Likewise.
This commit is contained in:
Tobias Burnus 2022-05-18 12:04:21 +02:00
parent 9f068ad0f2
commit ba8563693f
13 changed files with 221 additions and 13 deletions

View File

@ -1379,6 +1379,7 @@ show_omp_namelist (int list_type, gfc_omp_namelist *n)
case OMP_DEPEND_IN: fputs ("in:", dumpfile); break;
case OMP_DEPEND_OUT: fputs ("out:", dumpfile); break;
case OMP_DEPEND_INOUT: fputs ("inout:", dumpfile); break;
case OMP_DEPEND_INOUTSET: fputs ("inoutset:", dumpfile); break;
case OMP_DEPEND_DEPOBJ: fputs ("depobj:", dumpfile); break;
case OMP_DEPEND_MUTEXINOUTSET:
fputs ("mutexinoutset:", dumpfile);
@ -1898,6 +1899,7 @@ show_omp_clauses (gfc_omp_clauses *omp_clauses)
case OMP_DEPEND_IN: deptype = "IN"; break;
case OMP_DEPEND_OUT: deptype = "OUT"; break;
case OMP_DEPEND_INOUT: deptype = "INOUT"; break;
case OMP_DEPEND_INOUTSET: deptype = "INOUTSET"; break;
case OMP_DEPEND_MUTEXINOUTSET: deptype = "MUTEXINOUTSET"; break;
default: gcc_unreachable ();
}

View File

@ -1271,6 +1271,7 @@ enum gfc_omp_depend_op
OMP_DEPEND_IN,
OMP_DEPEND_OUT,
OMP_DEPEND_INOUT,
OMP_DEPEND_INOUTSET,
OMP_DEPEND_MUTEXINOUTSET,
OMP_DEPEND_DEPOBJ,
OMP_DEPEND_SINK_FIRST,
@ -1540,7 +1541,7 @@ typedef struct gfc_omp_clauses
ENUM_BITFIELD (gfc_omp_memorder) fail:3;
ENUM_BITFIELD (gfc_omp_cancel_kind) cancel:3;
ENUM_BITFIELD (gfc_omp_proc_bind_kind) proc_bind:3;
ENUM_BITFIELD (gfc_omp_depend_op) depobj_update:3;
ENUM_BITFIELD (gfc_omp_depend_op) depobj_update:4;
ENUM_BITFIELD (gfc_omp_bind_type) bind:2;
ENUM_BITFIELD (gfc_omp_at_type) at:2;
ENUM_BITFIELD (gfc_omp_severity_type) severity:2;

View File

@ -1915,7 +1915,9 @@ gfc_match_omp_clauses (gfc_omp_clauses **cp, const omp_mask mask,
break;
m = MATCH_YES;
gfc_omp_depend_op depend_op = OMP_DEPEND_OUT;
if (gfc_match ("inout") == MATCH_YES)
if (gfc_match ("inoutset") == MATCH_YES)
depend_op = OMP_DEPEND_INOUTSET;
else if (gfc_match ("inout") == MATCH_YES)
depend_op = OMP_DEPEND_INOUT;
else if (gfc_match ("in") == MATCH_YES)
depend_op = OMP_DEPEND_IN;
@ -3805,7 +3807,9 @@ gfc_match_omp_depobj (void)
if (gfc_match ("update ( ") == MATCH_YES)
{
c = gfc_get_omp_clauses ();
if (gfc_match ("inout )") == MATCH_YES)
if (gfc_match ("inoutset )") == MATCH_YES)
c->depobj_update = OMP_DEPEND_INOUTSET;
else if (gfc_match ("inout )") == MATCH_YES)
c->depobj_update = OMP_DEPEND_INOUT;
else if (gfc_match ("in )") == MATCH_YES)
c->depobj_update = OMP_DEPEND_IN;
@ -3815,8 +3819,8 @@ gfc_match_omp_depobj (void)
c->depobj_update = OMP_DEPEND_MUTEXINOUTSET;
else
{
gfc_error ("Expected IN, OUT, INOUT, MUTEXINOUTSET followed by "
"%<)%> at %C");
gfc_error ("Expected IN, OUT, INOUT, INOUTSET or MUTEXINOUTSET "
"followed by %<)%> at %C");
goto error;
}
}

View File

@ -2937,6 +2937,9 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
case OMP_DEPEND_INOUT:
OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_INOUT;
break;
case OMP_DEPEND_INOUTSET:
OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_INOUTSET;
break;
case OMP_DEPEND_MUTEXINOUTSET:
OMP_CLAUSE_DEPEND_KIND (node)
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
@ -5593,6 +5596,7 @@ gfc_trans_omp_depobj (gfc_code *code)
case OMP_DEPEND_IN: k = GOMP_DEPEND_IN; break;
case OMP_DEPEND_OUT: k = GOMP_DEPEND_OUT; break;
case OMP_DEPEND_INOUT: k = GOMP_DEPEND_INOUT; break;
case OMP_DEPEND_INOUTSET: k = GOMP_DEPEND_INOUTSET; break;
case OMP_DEPEND_MUTEXINOUTSET: k = GOMP_DEPEND_MUTEXINOUTSET; break;
default: gcc_unreachable ();
}

View File

@ -44,6 +44,9 @@ subroutine f6
!$omp target depend(mutexinoutset : omp_all_memory ) ! { dg-error "'omp_all_memory' used with DEPEND kind other than OUT or INOUT" }
! !$omp end target
!$omp target depend(inoutset : omp_all_memory ) ! { dg-error "'omp_all_memory' used with DEPEND kind other than OUT or INOUT" }
! !$omp end target
!$omp target depend ( depobj : omp_all_memory) ! { dg-error "'omp_all_memory' used with DEPEND kind other than OUT or INOUT" }
!!$omp end target

View File

@ -45,6 +45,9 @@ subroutine f6
!$omp target depend(mutexinoutset : omp_all_memory )
! !$omp end target
!$omp target depend(inoutset : omp_all_memory )
! !$omp end target
!$omp target depend ( depobj : omp_all_memory)
!$omp end target

View File

@ -22,4 +22,7 @@ subroutine f1
!$omp task depend(mutexinoutset: a)
!$omp end task
!$omp depobj(depobj2) destroy
!$omp depobj(depobj1) depend(inoutset: a)
!$omp depobj(depobj1) update(mutexinoutset)
!$omp depobj(depobj1) update(inoutset)
end subroutine f1

View File

@ -23,9 +23,9 @@ subroutine f1
!$omp depobj(depobj) depend(mutexinoutset : a) ! OK
!$omp depobj(depobj) depend(source) ! { dg-error "DEPEND clause at .1. of OMP DEPOBJ construct shall not have dependence-type SOURCE, SINK or DEPOBJ" }
!$omp depobj(depobj) depend(sink : i + 1) ! { dg-error "DEPEND clause at .1. of OMP DEPOBJ construct shall not have dependence-type SOURCE, SINK or DEPOBJ" }
!$omp depobj(depobj) update(source) ! { dg-error "Expected IN, OUT, INOUT, MUTEXINOUTSET followed by '\\)'" }
!$omp depobj(depobj) update(sink) ! { dg-error "Expected IN, OUT, INOUT, MUTEXINOUTSET followed by '\\)'" }
!$omp depobj(depobj) update(depobj) ! { dg-error "Expected IN, OUT, INOUT, MUTEXINOUTSET followed by '\\)'" }
!$omp depobj(depobj) update(source) ! { dg-error "Expected IN, OUT, INOUT, INOUTSET or MUTEXINOUTSET followed by '\\)'" }
!$omp depobj(depobj) update(sink) ! { dg-error "Expected IN, OUT, INOUT, INOUTSET or MUTEXINOUTSET followed by '\\)'" }
!$omp depobj(depobj) update(depobj) ! { dg-error "Expected IN, OUT, INOUT, INOUTSET or MUTEXINOUTSET followed by '\\)'" }
! Valid in OpenMP 5.1:
!$omp depobj(depobj5) depend(depobj: depobj3) ! { dg-error "DEPEND clause at .1. of OMP DEPOBJ construct shall not have dependence-type SOURCE, SINK or DEPOBJ" }

View File

@ -306,7 +306,7 @@ The OpenMP 4.5 specification is fully supported.
@item @code{nowait} clause in @code{taskwait} directive @tab N @tab
@item Extensions to the @code{atomic} directive @tab Y @tab
@item @code{seq_cst} clause on a @code{flush} construct @tab Y @tab
@item @code{inoutset} argument to the @code{depend} clause @tab N @tab
@item @code{inoutset} argument to the @code{depend} clause @tab Y @tab
@item @code{private} and @code{firstprivate} argument to @code{default}
clause in C and C++ @tab Y @tab
@item @code{present} argument to @code{defaultmap} clause @tab N @tab
@ -4279,7 +4279,7 @@ The following sections present notes on the offload-target specifics.
@code{i586}, @code{i686}, @code{ia32}
@tab @code{host}
@tab See @code{-m...} flags in ``x86 Options'' (without @code{-m})
@item @code{amdgcn} @code{gcn}
@item @code{amdgcn}, @code{gcn}
@tab @code{gpu}
@tab See @code{-march=} in ``AMD GCN Options''
@item @code{nvptx}

View File

@ -59,6 +59,12 @@ subroutine test (ifval)
call usleep (5000)
b(4) = 48
end block
!$omp task shared(b) depend(inoutset: b(5))
block
call usleep (5000)
b(5) = 49
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)
@ -66,7 +72,7 @@ subroutine test (ifval)
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) &
.or. b(4) /= 48 .or. b(5) /= 49 .or. b(6) /= 12 .or. b(7) /= 14) &
error stop
do i = 0, 7
if (i /= 4) &

View File

@ -62,6 +62,12 @@ subroutine test (ifval)
call usleep (5000)
b(4) = 48
end block
!$omp task shared(b) depend(inoutset: b(5))
block
call usleep (5000)
b(5) = 49
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)
@ -69,7 +75,7 @@ subroutine test (ifval)
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) &
.or. b(4) /= 48 .or. b(5) /= 49 .or. b(6) /= 12 .or. b(7) /= 14) &
error stop
do i = 0, 7
if (i /= 4) &

View File

@ -57,6 +57,12 @@ program main
call usleep (5000)
b(4) = 48
end block
!$omp task shared(b) depend(inoutset: b(5))
block
call usleep (5000)
b(5) = 49
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)
@ -64,7 +70,7 @@ program main
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) &
.or. b(4) /= 48 .or. b(5) /= 49 .or. b(6) /= 12 .or. b(7) /= 14) &
error stop
do i = 0, 7
if (i /= 4) &

View File

@ -0,0 +1,170 @@
! { 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
use omp_lib
implicit none (type, external)
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) = 0
integer(omp_depend_kind) :: d1, d2
!$omp depobj (d1) depend(inoutset: a)
!$omp depobj (d2) depend(inout: a)
!$omp depobj (d2) update(inoutset)
!$omp parallel
!$omp barrier
!$omp master
!$omp task shared(a) depend(out: a)
block
call usleep (5000)
a(0) = 1; a(1) = 2; a(2) = 3; a(3) = 4
end block
! The above task needs to finish first.
!$omp task shared(a) depend(in: a)
block
if (a(0) /= 1 .or. a(1) /= 2 .or. a(2) /= 3 .or. a(3) /= 4) &
error stop
call usleep (5000)
a(4) = 42
end block
!$omp task shared(a) depend(in: a)
block
if (a(0) /= 1 .or. a(1) /= 2 .or. a(2) /= 3 .or. a(3) /= 4) &
error stop
call usleep (5000);
a(5) = 43
end block
!$omp task shared(a) depend(in: a)
block
if (a(0) /= 1 .or. a(1) /= 2 .or. a(2) /= 3 .or. a(3) /= 4) &
error stop
call usleep (5000)
a(6) = 44
end block
!$omp task shared(a) depend(in: a)
block
if (a(0) /= 1 .or. a(1) /= 2 .or. a(2) /= 3 .or. a(3) /= 4) &
error stop
call usleep (5000)
a(7) = 45
end block
! The above 4 tasks can be scheduled in any order but need to wait
! for the depend(out: a) task.
!$omp task shared(a) depend(inoutset: a)
block
if (a(4) /= 42 .or. a(5) /= 43 .or. a(6) /= 44 .or. a(7) /= 45) &
error stop
call usleep (5000)
a(0) = 42
end block
!$omp task shared(a) depend(iterator(i=1:3:2), inoutset: a)
block
if (a(4) /= 42 .or. a(5) /= 43 .or. a(6) /= 44 .or. a(7) /= 45) &
error stop
call usleep (5000)
a(1) = 43
end block
!$omp task shared(a) depend(depobj: d1)
block
if (a(4) /= 42 .or. a(5) /= 43 .or. a(6) /= 44 .or. a(7) /= 45) &
error stop
call usleep (5000)
a(2) = 44
end block
!$omp task shared(a) depend(depobj: d2)
block
if (a(4) /= 42 .or. a(5) /= 43 .or. a(6) /= 44 .or. a(7) /= 45) &
error stop
call usleep (5000)
a(3) = 45
end block
! The above 4 tasks can be scheduled in any order but need to wait
! for all the above depend(in: a) tasks.
!$omp task shared(a) depend(in: a)
block
if (a(0) /= 42 .or. a(1) /= 43 .or. a(2) /= 44 .or. a(3) /= 45) &
error stop
call usleep (5000)
a(4) = 46
end block
!$omp task shared(a) depend(in: a)
block
if (a(0) /= 42 .or. a(1) /= 43 .or. a(2) /= 44 .or. a(3) /= 45) &
error stop
call usleep (5000)
a(5) = 47
end block
!$omp task shared(a) depend(in: a)
block
if (a(0) /= 42 .or. a(1) /= 43 .or. a(2) /= 44 .or. a(3) /= 45) &
error stop
call usleep (5000)
a(6) = 48
end block
!$omp task shared(a) depend(in: a)
block
if (a(0) /= 42 .or. a(1) /= 43 .or. a(2) /= 44 .or. a(3) /= 45) &
error stop
call usleep (5000)
a(7) = 49
end block
! The above 4 tasks can be scheduled in any order but need to wait
! for all the above depend(inoutset: a),
! depend(iterator(i=1:3:2), inoutset: a), depend(depobj: d1) and
! depend(depobj: d2) tasks.
!$omp task shared(a) depend(inoutset: a)
block
if (a(4) /= 46.or. a(5) /= 47 .or. a(6) /= 48 .or. a(7) /= 49) &
error stop
call usleep (5000)
a(0) = 50
end block
! The above task needs to wait for all the above 4 depend(in: a)
! tasks.
!$omp task shared(a) depend(out: a)
block
if (a(0) /= 50 .or. a(4) /= 46.or. a(5) /= 47 .or. a(6) /= 48 .or. a(7) /= 49) &
error stop
call usleep (5000)
a(0) = 51
end block
! The above task needs to wait for the above depend(inoutset: a) task.
!$omp task shared(a) depend(inoutset: a)
block
if (a(0) /= 51 .or. a(4) /= 46.or. a(5) /= 47 .or. a(6) /= 48 .or. a(7) /= 49) &
error stop
call usleep (5000)
a(0) = 52
end block
! The above task needs to wait for the above depend(out: a) task.
!$omp task shared(a) depend(mutexinoutset: a)
block
if (a(0) /= 52 .or. a(4) /= 46.or. a(5) /= 47 .or. a(6) /= 48 .or. a(7) /= 49) &
error stop
call usleep (5000)
a(0) = 53
end block
! The above task needs to wait for the above depend(inoutset: a) task.
!$omp task shared(a) depend(inoutset: a)
block
if (a(0) /= 53 .or. a(4) /= 46.or. a(5) /= 47 .or. a(6) /= 48 .or. a(7) /= 49) &
error stop
call usleep (5000)
a(0) = 54
end block
! The above task needs to wait for the above
! depend(mutexinoutset: a) task.
!$omp end master
!$omp end parallel
if (a(0) /= 54 .or. a(1) /= 43 .or. a(2) /= 44 .or. a(3) /= 45 &
.or. a(4) /= 46.or. a(5) /= 47 .or. a(6) /= 48 .or. a(7) /= 49) &
error stop
end