This is the mail archive of the
fortran@gcc.gnu.org
mailing list for the GNU Fortran project.
Re: Implementing OpenACC's Fortran module
- From: Tobias Burnus <tobias dot burnus at physik dot fu-berlin dot de>
- To: Thomas Schwinge <thomas at codesourcery dot com>
- Cc: jnorris at codesourcery dot com, fortran at gcc dot gnu dot org, jakub at redhat dot com
- Date: Wed, 23 Jul 2014 15:39:24 +0200
- Subject: Re: Implementing OpenACC's Fortran module
- Authentication-results: sourceware.org; auth=none
- References: <87lhs5rwzo dot fsf at schwinge dot name> <53C544C3 dot 1010604 at mentor dot com> <20140722133959 dot GA11110 at physik dot fu-berlin dot de> <874my9s45m dot fsf at schwinge dot name>
On Tue, Jul 22, 2014 at 07:18:45PM +0200, Thomas Schwinge wrote:
> | subroutine acc_copyin ( a, len )
> | type :: a
> | integer :: len
> interface acc_copyin
> subroutine f_acc_copyin (h, s) bind (c)
> use iso_c_binding
> type (*) :: h
> integer (c_size_t) :: s
> end subroutine
Ignoring that the C side probably wants to have the len passed by VALUE (which
can be done by that attribute), using integer(c_size_t) is incompatible with
the OpenACC spec which requires a default-kind integer. Hence, on a 64bit
system, it will fail with:
call acc_copyin (a, 5)
1
Error: There is no specific subroutine for the generic 'acc_copyin' at (1)
One really has to use "integer", which could be done by supporting
both int32 and int64 versions - which would extend the spec by allowing
more integer kinds.
> subroutine f_acc_copyin_array (h) bind (c)
> use iso_c_binding
> type (*), target, dimension(..) :: h
> call f_acc_copyin(c_loc(h), size(h, kind = c_size_t))
> end subroutine
As I realized later, SIZE is not sufficient as it only contains the arr
size; one also needs to multiply it by the size of an element. In
principle, STORAGE_SIZE()/8 returns this - or one gets the whole size
(array * element size) at once using c_sizeof() or sizeof() [the latter
is a GNU extension]. However, all those require that the type is known,
which is not the case for TYPE(*). (It is, however, known for
"type(*),dimension(..)".)
Hence, one either needs to use to "class(*)" which has this information
or one enhances one of the intrinsics - such as the GNU intrinsic SIZEOF
to permit type(*) if and only if used with dimension(..).
In any case, SIZEOF has a bug [PR61888] as has CLASS(*) [PR61881]. I
will try to fix them this evening - and add support for SIZEOF for
"type(*),dimension(..)" as extension to that vendor intrinsic.
> (Tobias: to get around the two compiler errors, I changed the compiler
> From the system's 4.8 version to the current trunk, and added the »kind =
> c_size_t« to have the SIZE intrinsic return the appropriate data type.
(Aha, it already surprised me that it didn't work, assuming that the
gomp-4_0-branch or some branch tracking it was in the path. Some C
binding changes were done for GCC 4.9.)
> > To conclude, one has three possibilities:
> >
> > 1. To use the module outlined above - and as pasted below.
[The size calculation and integer-kind conversions causes that an .o
file generated.]
> > or alternatively
> > 2. To handle the Fortran code directly in C, i.e. doing the size
> > calculation in C.
[This avoids the .o file, but requires code in the C file]
> > or alternatively
> > 3. To create a virtual module as done for iso_c_binding and iso_fortran_env,
> > which is completely handled in the compiler.
Cheers,
Tobias