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:
parent
9f068ad0f2
commit
ba8563693f
|
@ -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 ();
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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 ();
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" }
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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) &
|
||||
|
|
|
@ -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) &
|
||||
|
|
|
@ -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) &
|
||||
|
|
|
@ -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
|
Loading…
Reference in New Issue