Hi!

Hacking on Fortran target support now, I ran into an issue with
Fortran array pointers or other types using array descriptors.
The problem is that right now for OpenMP (I think OpenACC has it different)
we have only the OpenMP mandates kinds (alloc, to, from, tofrom),
which have address, size, kind, alignment quadruplets (the last two
things encoded in a single byte), and one special kind, pointer,
which uses address, bias, kind, alignment quadruplet with
size being implicit - sizeof (void *).  Pointer kind works like
alloc, with additional pointer assignment if it has been allocated
(read the host value of the pointer pointed by the address, add bias
to it, translate that address to target address, subtract bias and
store the result into the allocated target memory).

Fortran array descriptor is a pointer plus lots of other data though,
and I'm not sure we want to hardcode forever that the pointer must be
the first in there and certainly can't hardcode the array descriptor size.
Furthermore, if we used the pointer kind for the first sizeof(void*) bytes
of the descriptor and the to kind for the rest of the descriptor, which is
pretty much how we want it to behave, the library doesn't guarantee they
would be consecutive allocations in the target.

So, I'm afraid we need a new kind for this.  I'm considering
kind pset (pointer set), which would be like to kind, but in addition to
that it would affect behavior of all following pointer kind map clauses
where the address falls into the pset range.
So, to describe a Fortran array descriptor (say rank 3), there would be e.g.
map (to: ptrvar [pointer set, len: 96]) map (alloc: ptrvar [pointer assign, 
bias: 0])
which would transform into:
addr_array[] = { &ptrvar, &ptrvar };
size_array[] = { 96, 0 };
kind_array[] = { (align << 3) | 5, (align << 3) | 4 };
GOMP_target_* (..., addr_array, size_array, kind_array);
If the pset map would be found already allocated, it wouldn't do anything
beyond to kind, nothing and all the following pointer maps would also do
nothing (as they are already alocated too).
If it is found not to be allocated, it would allocate it, copy to target,
and for all immediately following pointer map would check if they fall into
the given host range, if it does, then it wouldn't ignore the pointer, just
wouldn't allocate it again, but would perform pointer assignment.

Does this sound ok to anyone?

Also, I'm afraid we'll need to ignore map clauses where the host address
is NULL, and for pointer assignment if host pointer is NULL assign NULL to
target.

        Jakub

Reply via email to