On 11.10.22 16:15, Jakub Jelinek wrote:

I think the most common case is:

integer, allocatable :: var(:)
!$omp allocators allocator(my_alloc) ! must be in same scope as decl of 'var'
...
! optionally: deallocate(var)
end ! of scope: block/subroutine/... - automatic deallocation



So you talk here about the declarative directive the patch does sorry on,
or about the executable one above allocate stmt?

Here, I was only talking about the most common usage case, with the
assumption that the user code does not cause any reallocation.

I later talked about accepting only code which cannot cause
reallocation (compile-time check of the code contained in the
scope).

Thus, a 'call foo(a)' would be fine, but not for ...


Anyway, even this simple case has the problem that one can have
subroutine foo (var)
 integer, allocatable:: var(:)

a 'foo' that has an 'allocatable' attribute for the dummy argument.
I think in the common case, it has not – such that most code can run w/o 
running into this issue.

However, for code like
 type t
   real, allocatable :: x(:), y(:), z(:)
 end type t
 type(t) :: var
 !$omp allocators(my_alloc)
 allocate(var%x(N), var%y(N), var%z(N))

 call bar(var%x)
 call foo(var)

it is more difficult: 'bar' works (if its dummy argument is not 'allocatable')
but for 'foo', the (re|de)allocation cannot be ruled out.
Thus, we always have to 'sorry' for such a code – and I fear it could be 
somewhat
common.



Well, it can use a weak symbol, if not linked against libgomp, the bit
that it is OpenMP shouldn't be set and so realloc/free will be used
and do
 if (arrdescr.gomp_alloced_bit)
   GOMP_free (arrdescr.data, 0);
 else
   free (arrdescr.data);
and similar.  And I think we can just document that we do this only for
-fopenmp compiled code.
But do we have a place to store that bit?

I presume in array descriptors
there could be some bit for it, but what to do about scalar allocatables,
or allocatable components etc.?

As mentioned, we could use the 'dtype.attribute' field which is currently not 
really used – and if, only 2 of the 16 bits are used. But you are right that 
for scalar allocatables, we do not use array descriptors (except with BIND(C)). 
Hmm.

For allocatable components, the same applied: If arrays, then there is an array 
descriptor – for scalars, there isn't. (And storing the length of a scalar 
character string with deferred length uses an aux variable + has lots of bugs.)

In theory we could use ugly stuff like if all the allocations would be
guaranteed to have at least 2 byte alignment use LSB bit of the pointer
to mark GOMP_alloc allocated memory for the scalar allocatables etc. but
then would need in -fopenmp compiled code to strip it away.

I think we could do tricks with scalar allocatable variable – but it will be 
more complicated with scalar allocatable components. Hmm.

As for pinned memory, if it is allocated through libgomp allocators, that
should just work if GOMP_free/GOMP_realloc is used, that is why we have
those extra data in front of the allocations where we store everything we
need.  But those also make the OpenMP allocations incompatible with
malloc/free allocations.


The problem of making pseudo-USM work is that it has to be applied to all 
(stack,heap) memory – which implies that all code using malloc/free needs to be 
either call the GOMP version or the GLIBC version, but shall not mix one or the 
other. – Thus, calling some library or any other file that was not compiled 
with -f... will have issues with malloc/free. Another issue is that variables 
not allocated via GOMP_* will not be accessible on the device in that case.

Tobias

-----------------
Siemens Electronic Design Automation GmbH; Anschrift: Arnulfstraße 201, 80634 
München; Gesellschaft mit beschränkter Haftung; Geschäftsführer: Thomas 
Heurung, Frank Thürauf; Sitz der Gesellschaft: München; Registergericht 
München, HRB 106955

Reply via email to