Fortran/C interfacing
Tobias Burnus
burnus@net-b.de
Fri Nov 14 21:01:00 GMT 2014
Am 14.11.2014 um 16:56 schrieb Thomas Schwinge:
> Hi!
>
> On Wed, 12 Nov 2014 11:06:26 +0100, Jakub Jelinek <jakub@redhat.com> wrote:
>> On Tue, Nov 11, 2014 at 01:53:23PM +0000, Julian Brown wrote:
>>> [OpenACC libgomp changes][openacc.f90, and exporting symbols in libgomp.map]
>>>
>>>
>> Somebody recently suggested (for OpenMP) that we just should use
>> bind(C) in the Fortran module, it is too late for OpenMP, as we
>> have to keep the *_ entrypoints for compatibility anyway, but
>> for OpenACC and new OpenMP functions supposedly you could avoid
>> exporting all the *_ wrappers and use * directly.
> Tobis, as our local expert :-) -- how does that "resonate" with the
> discussion (and implementation) about Fortran/C interfacing
Unfortunately, it a wrapper either on C or on Fortran side is unavoidable.
For C/C++, one has has:
void* acc_copyin(h_void*, size_t );
That matches (if one ignores the return type):
subroutine acc_copyin(a, len) bind(C)
use iso_c_binding, only: c_size_t
type(*) :: a
integer(c_size_t) :: len
If one looks at Fortran's first interface, it seems to match:
subroutine acc_copyin(a, len )
type:: a
integer :: len
However, a default-size integer in Fortran is usually* 4-bytes wide
while size_t on most 64bit systems** is 8-bytes wide. As Fortran doesn't
automatically convert the integer type, I think there is no way but
providing additionally a function which takes an "int"/default-kind
integer. (* unless one uses -fdefault-integer-8; ** such as x32.)
I think in the current version of the patch â I haven't re-checked â,
one provides both a function for int32 and int64, one matching a 32 and
one a 64 bit integer. Additionally, it permits to use >2GB arrays. In
principle, one of the versions could directly invoke the C function
without the wrapper [where c_size_t == kind(integer)] - but that would
require come conditional compilation.
Whether one has a trailing "_" and whether one implements it in C or in
Fortran doesn't really matter.
The second Fortran interface is:
subroutine acc_copyin(a)
type, dimension(: [,:]â¦) :: a
which can be best writtin in modern Fortran as:
class(*), dimension(..) :: a
and which, knowing the internal implementation, I wrote as
type(*), dimension(..) :: a
as it avoids some extra code on the caller side - but it is not fully
standard conform. On the other hand, "type(*), dimension(..)" can be
also marked as BIND(C).
There is no C equivalent but one can use something like
call acc_copyin(c_loc(a), size(a)*storage_size(a)/8)
to convert it to the C form of the function.
Again, this conversion can be done either in Fortran or in C. One just
needs to take the first field of the array descriptor - the address of
the actual data - and needs to extract the size of an element and the
number of elements. (Caveat: The current code only works if the array is
contiguous and the argument is not an assumed-size array.)
Thus, all in all, I think the current implementation is okay. However,
if someone has a better suggestion, I am interested.
Tobias
PS: I am happy that TYPE(*) and DIMENSION(..) exist (both in the
standard and in the compiler) as they make life much simpler. Otherwise,
providing an explicit interface would be tediuous for intrinsic types
and impossible for derived types.
More information about the Gcc-patches
mailing list