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_IN: fputs ("in:", dumpfile); break;
|
||||||
case OMP_DEPEND_OUT: fputs ("out:", dumpfile); break;
|
case OMP_DEPEND_OUT: fputs ("out:", dumpfile); break;
|
||||||
case OMP_DEPEND_INOUT: fputs ("inout:", 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_DEPOBJ: fputs ("depobj:", dumpfile); break;
|
||||||
case OMP_DEPEND_MUTEXINOUTSET:
|
case OMP_DEPEND_MUTEXINOUTSET:
|
||||||
fputs ("mutexinoutset:", dumpfile);
|
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_IN: deptype = "IN"; break;
|
||||||
case OMP_DEPEND_OUT: deptype = "OUT"; break;
|
case OMP_DEPEND_OUT: deptype = "OUT"; break;
|
||||||
case OMP_DEPEND_INOUT: deptype = "INOUT"; break;
|
case OMP_DEPEND_INOUT: deptype = "INOUT"; break;
|
||||||
|
case OMP_DEPEND_INOUTSET: deptype = "INOUTSET"; break;
|
||||||
case OMP_DEPEND_MUTEXINOUTSET: deptype = "MUTEXINOUTSET"; break;
|
case OMP_DEPEND_MUTEXINOUTSET: deptype = "MUTEXINOUTSET"; break;
|
||||||
default: gcc_unreachable ();
|
default: gcc_unreachable ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1271,6 +1271,7 @@ enum gfc_omp_depend_op
|
||||||
OMP_DEPEND_IN,
|
OMP_DEPEND_IN,
|
||||||
OMP_DEPEND_OUT,
|
OMP_DEPEND_OUT,
|
||||||
OMP_DEPEND_INOUT,
|
OMP_DEPEND_INOUT,
|
||||||
|
OMP_DEPEND_INOUTSET,
|
||||||
OMP_DEPEND_MUTEXINOUTSET,
|
OMP_DEPEND_MUTEXINOUTSET,
|
||||||
OMP_DEPEND_DEPOBJ,
|
OMP_DEPEND_DEPOBJ,
|
||||||
OMP_DEPEND_SINK_FIRST,
|
OMP_DEPEND_SINK_FIRST,
|
||||||
|
@ -1540,7 +1541,7 @@ typedef struct gfc_omp_clauses
|
||||||
ENUM_BITFIELD (gfc_omp_memorder) fail:3;
|
ENUM_BITFIELD (gfc_omp_memorder) fail:3;
|
||||||
ENUM_BITFIELD (gfc_omp_cancel_kind) cancel:3;
|
ENUM_BITFIELD (gfc_omp_cancel_kind) cancel:3;
|
||||||
ENUM_BITFIELD (gfc_omp_proc_bind_kind) proc_bind: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_bind_type) bind:2;
|
||||||
ENUM_BITFIELD (gfc_omp_at_type) at:2;
|
ENUM_BITFIELD (gfc_omp_at_type) at:2;
|
||||||
ENUM_BITFIELD (gfc_omp_severity_type) severity: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;
|
break;
|
||||||
m = MATCH_YES;
|
m = MATCH_YES;
|
||||||
gfc_omp_depend_op depend_op = OMP_DEPEND_OUT;
|
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;
|
depend_op = OMP_DEPEND_INOUT;
|
||||||
else if (gfc_match ("in") == MATCH_YES)
|
else if (gfc_match ("in") == MATCH_YES)
|
||||||
depend_op = OMP_DEPEND_IN;
|
depend_op = OMP_DEPEND_IN;
|
||||||
|
@ -3805,7 +3807,9 @@ gfc_match_omp_depobj (void)
|
||||||
if (gfc_match ("update ( ") == MATCH_YES)
|
if (gfc_match ("update ( ") == MATCH_YES)
|
||||||
{
|
{
|
||||||
c = gfc_get_omp_clauses ();
|
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;
|
c->depobj_update = OMP_DEPEND_INOUT;
|
||||||
else if (gfc_match ("in )") == MATCH_YES)
|
else if (gfc_match ("in )") == MATCH_YES)
|
||||||
c->depobj_update = OMP_DEPEND_IN;
|
c->depobj_update = OMP_DEPEND_IN;
|
||||||
|
@ -3815,8 +3819,8 @@ gfc_match_omp_depobj (void)
|
||||||
c->depobj_update = OMP_DEPEND_MUTEXINOUTSET;
|
c->depobj_update = OMP_DEPEND_MUTEXINOUTSET;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
gfc_error ("Expected IN, OUT, INOUT, MUTEXINOUTSET followed by "
|
gfc_error ("Expected IN, OUT, INOUT, INOUTSET or MUTEXINOUTSET "
|
||||||
"%<)%> at %C");
|
"followed by %<)%> at %C");
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2937,6 +2937,9 @@ gfc_trans_omp_clauses (stmtblock_t *block, gfc_omp_clauses *clauses,
|
||||||
case OMP_DEPEND_INOUT:
|
case OMP_DEPEND_INOUT:
|
||||||
OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_INOUT;
|
OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_INOUT;
|
||||||
break;
|
break;
|
||||||
|
case OMP_DEPEND_INOUTSET:
|
||||||
|
OMP_CLAUSE_DEPEND_KIND (node) = OMP_CLAUSE_DEPEND_INOUTSET;
|
||||||
|
break;
|
||||||
case OMP_DEPEND_MUTEXINOUTSET:
|
case OMP_DEPEND_MUTEXINOUTSET:
|
||||||
OMP_CLAUSE_DEPEND_KIND (node)
|
OMP_CLAUSE_DEPEND_KIND (node)
|
||||||
= OMP_CLAUSE_DEPEND_MUTEXINOUTSET;
|
= 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_IN: k = GOMP_DEPEND_IN; break;
|
||||||
case OMP_DEPEND_OUT: k = GOMP_DEPEND_OUT; break;
|
case OMP_DEPEND_OUT: k = GOMP_DEPEND_OUT; break;
|
||||||
case OMP_DEPEND_INOUT: k = GOMP_DEPEND_INOUT; 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;
|
case OMP_DEPEND_MUTEXINOUTSET: k = GOMP_DEPEND_MUTEXINOUTSET; break;
|
||||||
default: gcc_unreachable ();
|
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 target depend(mutexinoutset : omp_all_memory ) ! { dg-error "'omp_all_memory' used with DEPEND kind other than OUT or INOUT" }
|
||||||
! !$omp end target
|
! !$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 target depend ( depobj : omp_all_memory) ! { dg-error "'omp_all_memory' used with DEPEND kind other than OUT or INOUT" }
|
||||||
!!$omp end target
|
!!$omp end target
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,9 @@ subroutine f6
|
||||||
!$omp target depend(mutexinoutset : omp_all_memory )
|
!$omp target depend(mutexinoutset : omp_all_memory )
|
||||||
! !$omp end target
|
! !$omp end target
|
||||||
|
|
||||||
|
!$omp target depend(inoutset : omp_all_memory )
|
||||||
|
! !$omp end target
|
||||||
|
|
||||||
!$omp target depend ( depobj : omp_all_memory)
|
!$omp target depend ( depobj : omp_all_memory)
|
||||||
!$omp end target
|
!$omp end target
|
||||||
|
|
||||||
|
|
|
@ -22,4 +22,7 @@ subroutine f1
|
||||||
!$omp task depend(mutexinoutset: a)
|
!$omp task depend(mutexinoutset: a)
|
||||||
!$omp end task
|
!$omp end task
|
||||||
!$omp depobj(depobj2) destroy
|
!$omp depobj(depobj2) destroy
|
||||||
|
!$omp depobj(depobj1) depend(inoutset: a)
|
||||||
|
!$omp depobj(depobj1) update(mutexinoutset)
|
||||||
|
!$omp depobj(depobj1) update(inoutset)
|
||||||
end subroutine f1
|
end subroutine f1
|
||||||
|
|
|
@ -23,9 +23,9 @@ subroutine f1
|
||||||
!$omp depobj(depobj) depend(mutexinoutset : a) ! OK
|
!$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(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) 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(source) ! { dg-error "Expected IN, OUT, INOUT, INOUTSET or MUTEXINOUTSET followed by '\\)'" }
|
||||||
!$omp depobj(depobj) update(sink) ! { dg-error "Expected IN, OUT, INOUT, 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, MUTEXINOUTSET followed by '\\)'" }
|
!$omp depobj(depobj) update(depobj) ! { dg-error "Expected IN, OUT, INOUT, INOUTSET or MUTEXINOUTSET followed by '\\)'" }
|
||||||
|
|
||||||
! Valid in OpenMP 5.1:
|
! 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" }
|
!$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 @code{nowait} clause in @code{taskwait} directive @tab N @tab
|
||||||
@item Extensions to the @code{atomic} directive @tab Y @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{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}
|
@item @code{private} and @code{firstprivate} argument to @code{default}
|
||||||
clause in C and C++ @tab Y @tab
|
clause in C and C++ @tab Y @tab
|
||||||
@item @code{present} argument to @code{defaultmap} clause @tab N @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}
|
@code{i586}, @code{i686}, @code{ia32}
|
||||||
@tab @code{host}
|
@tab @code{host}
|
||||||
@tab See @code{-m...} flags in ``x86 Options'' (without @code{-m})
|
@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 @code{gpu}
|
||||||
@tab See @code{-march=} in ``AMD GCN Options''
|
@tab See @code{-march=} in ``AMD GCN Options''
|
||||||
@item @code{nvptx}
|
@item @code{nvptx}
|
||||||
|
|
|
@ -59,6 +59,12 @@ subroutine test (ifval)
|
||||||
call usleep (5000)
|
call usleep (5000)
|
||||||
b(4) = 48
|
b(4) = 48
|
||||||
end block
|
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.
|
! None of the above tasks depend on each other.
|
||||||
! The following task depends on all but the a(4) = 46; one.
|
! 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)
|
!$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 &
|
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. 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(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
|
error stop
|
||||||
do i = 0, 7
|
do i = 0, 7
|
||||||
if (i /= 4) &
|
if (i /= 4) &
|
||||||
|
|
|
@ -62,6 +62,12 @@ subroutine test (ifval)
|
||||||
call usleep (5000)
|
call usleep (5000)
|
||||||
b(4) = 48
|
b(4) = 48
|
||||||
end block
|
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.
|
! None of the above tasks depend on each other.
|
||||||
! The following task depends on all but the a(4) = 46; one.
|
! The following task depends on all but the a(4) = 46; one.
|
||||||
!$omp task shared(a, b) depend(depobj: d1) private(i) if(ifval)
|
!$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 &
|
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. 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(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
|
error stop
|
||||||
do i = 0, 7
|
do i = 0, 7
|
||||||
if (i /= 4) &
|
if (i /= 4) &
|
||||||
|
|
|
@ -57,6 +57,12 @@ program main
|
||||||
call usleep (5000)
|
call usleep (5000)
|
||||||
b(4) = 48
|
b(4) = 48
|
||||||
end block
|
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.
|
! None of the above tasks depend on each other.
|
||||||
! The following task depends on all but the a(4) = 46; one.
|
! 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)
|
!$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 &
|
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. 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(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
|
error stop
|
||||||
do i = 0, 7
|
do i = 0, 7
|
||||||
if (i /= 4) &
|
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