Hi Tobias! On Sat, 20 Sep 2014 13:51:58 +0200, Tobias Burnus <[email protected]> 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
