Hi Jakub, hi Abid, hi all,

On 21.02.22 16:50, Jakub Jelinek via Fortran wrote:
The thing is, omp_requires_mask was added for C/C++ from the C/C++ notion of
translation units (and a question is how does that cope with C++20 modules),
with the assumption that once certain #pragma omp requires is seen, it
applies for the rest of the translation unit and there are some restrictions
that require it to appear before certain constructs in the source.

But, Fortran I think doesn't really have a concept of the translation unit,
the OpenMP term compilation unit is in Fortran program unit, so each
function/subroutine should have its own.

[Nit picking: "A program unit is a main program, an external subprogram,
a module, a submodule, or a block data program unit." Thus,
subroutines/functions which are contained inside a (sub)module or the
main program or another subroutine/function do not form a program
unit by themselves.]

I wonder whether there is a real problem in terms of the ME, but maybe
there is.

For atomic_default_mem_order: That's purely handle by the FEs by
setting the default – and just using it when parsing the 'atomic'
directive, if there is no explicit mem_order.

And for reverse_offload, unified_address or unified_shared_memory,
it has to be always the same in all 'compilation units' (which use
device-related OpenMP things).

I think both is handled correctly by gfortran and the C/C++ FE.
For gfortran, including pulling those requires by use-association
from a module ("unless the directive appears by referencing a module"
implies that this is intended).

The interesting question is about "requires dynamic_allocators".
However, I think one can still stuff it into a TU-wide
omp_requires_mask. While not all TU or even Fortran program units
have to set it, as soon as it appears in any 'requires', it affects
the available devices.

Thus, I do not see a problem to treat it like, e.g., unified_shared_memory,
except that there should be no error when not set in another program unit
(that uses OpenMP target stuff).

So, instead of what gfc_parse_file
does currently where it computes omp_requires as or of requires from each
function/subroutine (I think especially for atomic_default_mem_order that
can do really weird things, nothing requires that e.g. in different
functions those can't be different in Fortran, while in C/C++ it needs to be
the same), we need to make sure that omp_requires_mask omp-generic.cc sees
or uses is for Fortran the value from the current function/subroutine.

Cf. above - is this really needed? And do you think there is an issue with
the current implementation?

For the yet unimplemented requires unified_address etc., the plan was that
we'd emit the requirement e.g. into the offloading data such that we could
tell the runtime library all the requirements together from whole program or
shared library.  In that case using an or from the various
functions/subroutines is desirable, if at least one function requires
unified_address, the runtime should filter out any devices that don't
satisfy it, etc.

Regarding the implementation, there is a patch for it on OG11,
https://gcc.gnu.org/g:f5bfc65f9a6 which does an initial implementation.
(It prints a diagnostic instead of doing the filtering – but that could
be fixed easily. I think until and include 5.2, the spec is not that clear.
Post 5.2, the "supported devices" definition makes it clear, that the
device list should be filtered.)

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