This is the mail archive of the fortran@gcc.gnu.org mailing list for the GNU Fortran project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Implementing OpenACC's Fortran module


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


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]