Hi!

On 2023-11-17T16:24:46+0100, I wrote:
> [...] attached "Add 'libgomp.c++/static-local-variable-1.C'" [...]

Now, working on translating this into an OpenMP 'target' variant.  My
goal here is not necessarily to make this work now, but rather to figure
out whether '-fthreadsafe-statics' actually does or doesn't need to be
supported in offloading compilation, whether '__cxa_guard_acquire' is in
fact unreachable there.  (Currently the latter symbol isn't available in
offloading compilation; as you know I'm currently working on GPU
libstdc++ library support.)  However, GCC offloading compilation
currently fails differently, as follows:

    r.cc:16:12: error: variable ‘_ZGVZL1fvE1s’ has been referenced in offloaded 
code but hasn’t been marked to be included in the offloaded code
       16 |   static S s;
          |            ^
    lto1: fatal error: errors during merging of translation units
    compilation terminated.
    nvptx mkoffload: fatal error: 
build-gcc/gcc/x86_64-pc-linux-gnu-accel-nvptx-none-gcc returned 1 exit status
    [...]

... with:

    $ c++filt _ZGVZL1fvE1s
    guard variable for f()::s

Now I wonder how is that supposed to behave; is this valid OpenMP
'target' code at all?  Can you please help me find my way through the
OpenMP specification regarding this?

In OpenMP 5.2, 5.1.1 "Variables Referenced in a Construct", we have:

      - Variables with static storage duration that are declared in a scope 
inside the construct are shared.

Does this apply to a 'declare target'ed function 'f'?  (I was thinking:
"dynamic extend" of the scope of the 'target' construct?)  Ah, probably
that's 5.1.2 "Variables Referenced in a Region but not in a Construct":

      - Variables with static storage duration that are declared in called 
routines in the region are shared.

In 7.8 "Declare Target Directives", we have:

    If a variable with static storage duration is declared in a device routine 
then the named variable is
    treated as if it had appeared in an 'enter' clause on a declare target 
directive.

Similarly, in 13.8 "'target' Construct":

    If a variable with static storage duration is declared in a 'target' 
construct that does not specify a
    'device' clause in which the 'ancestor' _device-modifier_ appears then the 
named variable is
    treated as if it had appeared in a 'enter' clause on a declare target 
directive.

Per those occurrences, and per GCC not raising an error when encountering
a static local variable, I assume this is intended to work "as expected"?

On the other hand, NVHPC nvc++ 23.1-0 fails, too:

    NVC++-S-1062-Support procedure called within a compute region - 
__cxa_guard_acquire (r.cc: 16)
    [local to r_cc]::f():
         16, Accelerator restriction: unsupported call to support routine 
'__cxa_guard_acquire'
    NVC++/x86-64 Linux 23.1-0: compilation completed with severe errors

Hmm...


Grüße
 Thomas


-----------------
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
#pragma omp declare target

struct S
{
  S()
  {
  }

  ~S()
  {
  }
};

static void f()
{
  static S s;
}

#pragma omp end declare target

int main()
{
#pragma omp target
  {
    f();
  }
}

Reply via email to