https://gcc.gnu.org/bugzilla/show_bug.cgi?id=122892

            Bug ID: 122892
           Summary: [OpenMP] With ALLOCATE directive, for global static
                    variables, reject allocators with access
                    trait:cgroup/pteam/thread
           Product: gcc
           Version: 16.0
            Status: UNCONFIRMED
          Keywords: accepts-invalid, diagnostic, openmp
          Severity: normal
          Priority: P3
         Component: c
          Assignee: unassigned at gcc dot gnu.org
          Reporter: burnus at gcc dot gnu.org
  Target Milestone: ---

OpenMP 6 added a restriction applicable for the 'allocate' directive
on a static variable that is not a 'local static variable' (new glossary term).

New with OpenMP 6.0 (OpenMP Spec Issue #3294), "8.2 Memory Allocators":
Restrictions:
  [...]
  * The omp_cgroup_mem_alloc, omp_pteam_mem_alloc, and omp_thread_mem_alloc
    predefined memory allocators must not be used to allocate a variable
    with static storage duration unless the variable is a local static
variable.

* * * 

#include <omp.h>

int ok1 = ok2 = ok3 = ok4 = ok5 = 1;
#pragma omp allocate(ok1) allocator(omp_default_mem_alloc)    // OK - 'access'
trait is 'device'
#pragma omp allocate(ok2) allocator(omp_large_cap_mem_alloc)  // OK - 'access'
trait is 'device'
#pragma omp allocate(ok3) allocator(omp_const_mem_alloc)      // OK - 'access'
trait is 'device'
#pragma omp allocate(ok4) allocator(omp_high_bw_mem_alloc)    // OK - 'access'
trait is 'device'
#pragma omp allocate(ok5) allocator(omp_low_lat_mem_alloc)    // OK - 'access'
trait is 'device'

int x = 42, y = 13, z = 42;
#pragma omp allocate(y) allocator(omp_cgroup_mem_alloc) // Invalid global var +
access trait 'cgroup'
#pragma omp allocate(x) allocator(omp_pteam_mem_alloc)  // Likewise with
access:pteam
#pragma omp allocate(z) allocator(omp_thread_mem_alloc) // Likewise with
access:thread

* * *

module m
use omp_lib
implicit none
  ! implied 'save' because in module and because initialized
integer :: ok1 = 1, ok2 = 1, ok3 = 1, ok4 = 1, ok5 = 1
!$omp allocate(ok1) allocator(omp_default_mem_alloc)    ! OK - 'access' trait
is 'device'
!$omp allocate(ok2) allocator(omp_large_cap_mem_alloc)  ! OK - 'access' trait
is 'device'
!$omp allocate(ok3) allocator(omp_const_mem_alloc)      ! OK - 'access' trait
is 'device'
!$omp allocate(ok4) allocator(omp_high_bw_mem_alloc)    ! OK - 'access' trait
is 'device'
!$omp allocate(ok5) allocator(omp_low_lat_mem_alloc)    ! OK - 'access' trait
is 'device'

integer :: x = 42, y = 13, z = 42
!$omp allocate(y) allocator(omp_cgroup_mem_alloc) ! Invalid global var + access
trait 'cgroup'
!$omp allocate(x) allocator(omp_pteam_mem_alloc)  ! Likewise with access:pteam
!$omp allocate(z) allocator(omp_thread_mem_alloc) ! Likewise with access:thread
end module

Likewise (cf. definition local variable)

program prog
  integer :: wrong  ! implied 'save' because in main program
  !$omp allocate(y) allocator(omp_cgroup_mem_alloc) ! Invalid global var +
access trait 'cgroup'

  block ! OK - block construct
    integer, save :: valid = 1
    !$omp allocate(valid) allocator(omp_cgroup_mem_alloc) ! OK, inside BLOCK
  end block
end

subroutine sub
  integer, save :: also_valid = 1 ! in a subroutine/function
  !$omp allocate(also_valid) allocator(omp_cgroup_mem_alloc)
end

Reply via email to