Hi Tobias! On Sat, 20 Sep 2014 13:51:58 +0200, Tobias Burnus <bur...@net-b.de> wrote: > On 19.09.2014 11:03, Thomas Schwinge wrote: > > Regarding linking the object file produced by Fortran openacc.f90 into > > libgomp: (with the version that Jim already has internally checked in) > > I find that libgomp then has undefined references to > > _gfortran_internal_unpack and _gfortran_internal_pack. > > Internal pack and unpack appears when you a (potentially) noncontiguous > array is passed as argument to an argument which requires a contiguous > argument. Internal pack checks at run time whether the argument is > contiguous - and if not it creates a temporary and copies the data to > the temporary ('copy in') - internal unpack ensures for all arrays but > intent(in) that the data is propagated back to the original one.
Thanks for the explanation. > I am pretty sure that copy-in will break the OpenACC functions. > > One possibility would be to mark the dummy arguments in openacc.f90 as > CONTIGUOUS. That way, no internal pack/unpack is called by openacc.f90. > (If one has a noncontiguous array, the caller of openacc.f90 will do the > copy in/out.) > > Thus, you could try to add ", contiguous" to all procedures which take > an assumed-rank array "(..)" as argument. That works. For avoidance of doubt: just tag to the actual implementation (which is enough to avoid the references to _gfortran_internal_unpack and _gfortran_internal_pack), or also the interfaces, as detailed in the following "pseudo patch": [openacc.f90] module openacc_internal use openacc_kinds implicit none interface subroutine acc_delete_32_h (a, len) use iso_c_binding, only: c_int32_t, c_size_t !GCC$ ATTRIBUTES NO_ARG_CHECK :: a type(*), dimension(*) :: a integer(c_int32_t) len end subroutine subroutine acc_delete_64_h (a, len) use iso_c_binding, only: c_int64_t, c_size_t !GCC$ ATTRIBUTES NO_ARG_CHECK :: a type(*), dimension(*) :: a integer(c_int64_t) len end subroutine subroutine acc_delete_array_h (a) use iso_c_binding, only: c_size_t - type(*), dimension(..) :: a + type(*), dimension(..), contiguous :: a end subroutine end interface interface subroutine acc_delete_l (a, len) & bind(C, name="acc_delete") use iso_c_binding, only: c_size_t !GCC$ ATTRIBUTES NO_ARG_CHECK :: a type(*), dimension(*) :: a integer(c_size_t), value :: len end subroutine end interface end module module openacc use openacc_kinds use openacc_internal interface acc_delete procedure :: acc_delete_32_h procedure :: acc_delete_64_h procedure :: acc_delete_array_h end interface end module subroutine acc_delete_32_h (a, len) use iso_c_binding, only: c_int32_t, c_size_t use openacc_internal, only: acc_delete_l !GCC$ ATTRIBUTES NO_ARG_CHECK :: a type(*), dimension(*) :: a integer(c_int32_t) len call acc_delete_l (a, int (len, kind=c_size_t)) end subroutine subroutine acc_delete_64_h (a, len) use iso_c_binding, only: c_int64_t, c_size_t use openacc_internal, only: acc_delete_l !GCC$ ATTRIBUTES NO_ARG_CHECK :: a type(*), dimension(*) :: a integer(c_int64_t) len call acc_delete_l (a, int (len, kind=c_size_t)) end subroutine subroutine acc_delete_array_h (a) use iso_c_binding, only: c_size_t use openacc_internal, only: acc_delete_l - type(*), dimension(..) :: a + type(*), dimension(..), contiguous :: a call acc_delete_l (a, sizeof (a)) end subroutine [openacc_lib.h] interface acc_delete subroutine acc_delete_32_h (a, len) use iso_c_binding, only: c_int32_t !GCC$ ATTRIBUTES NO_ARG_CHECK :: a type(*), dimension(*) :: a integer(c_int32_t) len end subroutine subroutine acc_delete_64_h (a, len) use iso_c_binding, only: c_int64_t !GCC$ ATTRIBUTES NO_ARG_CHECK :: a type(*), dimension(*) :: a integer(c_int64_t) len end subroutine subroutine acc_delete_array_h (a) - class(*), dimension(..) :: a + class(*), dimension(..), contiguous :: a end subroutine end interface Grüße, Thomas
pgpYDfNt3QQpL.pgp
Description: PGP signature