Observed issues › nested/gcc-fortran-pointer-component-alloc-bounds-lost
GCC Fortran: pointer component entered with alloc comes back with wrong values
Legality: not independently confirmed. Independent readings are uncertain: Mapping r with alloc treats the association status of its pointer component r%a as undefined, and r%a is then mapped and attached separately. Exit data of r%a detaches, and exit data of r later copies back r including the pointer component whose association status the specification leaves undefined, so reading r%a on the host afterwards is not clearly guaranteed. How this is checked
GCC returns wrong values for a Fortran pointer component entered with map(alloc:).
Affected variants
| Compiler | MI300A gfx942 unified memory (XNACK 1) | MI300A gfx942 copy (XNACK 0) | MI250X gfx90a copy (XNACK 0) | MI300X gfx942 copy (XNACK 0) | MI350X gfx950 copy (XNACK 0) | A100 sm_80 separate memory | A100 sm_80 managed memory |
|---|---|---|---|---|---|---|---|
| AFAR 24.3.0 | correct | correct | unknown not run | correct | correct | n/a | n/a |
| CCE 19.0.0 | correct | correct | unknown not run | unknown not run | unknown not run | n/a | n/a |
| CCE 20.0.2 | correct | correct | unknown not run | unknown not run | unknown not run | n/a | n/a |
| CCE 21.0.3 | correct | correct | unknown not run | unknown not run | unknown not run | n/a | n/a |
| CCE 21.0.4 | correct | correct | unknown not run | unknown not run | unknown not run | n/a | n/a |
| NVHPC 25.11 | n/a | n/a | n/a | n/a | n/a | correct | correct |
| NVHPC 26.9 | n/a | n/a | n/a | n/a | n/a | correct | correct |
| GCC 16.2.0 | behaves incorrectly | behaves incorrectly | behaves incorrectly | behaves incorrectly | behaves incorrectly | behaves incorrectly | n/a |
"behaves incorrectly" / "not supported": this issue, confirmed in up to four environments (another build directory, another node, a repeat). "fails another way": a different failure, not counted as this issue. "unknown": not run there, or the runs disagree.
Messages
| Result | Compiler and GPU | Message |
|---|---|---|
| behaves incorrectly | GCC 16.2.0, MI300A unified GCC 16.2.0, MI300A copy GCC 16.2.0, MI250X GCC 16.2.0, MI300X GCC 16.2.0, MI350X | showtot= 504 s= 900 RESULT ran_on_host=0 check=fail |
| behaves incorrectly | GCC 16.2.0, A100 separate | showtot= 507 s= 900 RESULT ran_on_host=0 check=fail |
Reproduce
GCC 16.2.0, MI300A unified
export LD_LIBRARY_PATH=$GCC_16_2/lib64:/opt/rocm-7.2.1/lib $GCC_16_2/bin/gfortran -fopenmp -foffload=amdgcn-amdhsa -foffload-options=amdgcn-amdhsa=-march=gfx942 -O2 repro.f90 -o repro HSA_XNACK=1 OMP_TARGET_OFFLOAD=mandatory ./repro
GCC 16.2.0, A100 separate
export PATH=/usr/local/cuda/bin:$PATH export LD_LIBRARY_PATH=$GCC_16_2/lib64 $GCC_16_2/bin/gfortran -fopenmp -foffload=nvptx-none -foffload-options=nvptx-none=-march=sm_80 -foffload-options=nvptx-none=-latomic -O2 repro.f90 -o repro OMP_TARGET_OFFLOAD=mandatory ./repro
AFAR 24.3.0, MI300A unified (runs correctly)
$AFAR/bin/amdflang -fopenmp --offload-arch=gfx942 -O2 repro.f90 -o repro HSA_XNACK=1 OMP_TARGET_OFFLOAD=mandatory ./repro
Program (55 lines)
! # Finding (nested-data): GCC: a pointer component mapped alloc and written on the device comes back with the wrong values
! # (bounds of the attached descriptor not set)
!
! - toolchains and modes that fail: gcc_g90 (GCC 16.2.0), gcc_sm80 (GCC 16.2.0); modes: copy; -O2
! - build: gfortran -fopenmp -foffload=amdgcn-amdhsa -foffload-options=amdgcn-amdhsa=-march=gfx90a -O2 (gcc_g90); gfortran -fopenmp
! -foffload=nvptx-none -foffload-options=nvptx-none=-march=sm_80 -foffload-options=nvptx-none=-latomic -O2 (gcc_sm80)
! - failure: wrong_answer (check=fail)
! - observed: `tot= 504`, `s= 900` with `check=fail`
! - expected: compiles and prints `tot= 4028`, `s= 900` with `check=pass` (the model of the program: the sum of the
! written values)
! - rule: on entry the corresponding pointer "is associated with a pointer target that has the same rank and bounds as
! the pointer target of the original pointer, such that the corresponding list item can be accessed through the
! pointer in a target region" (5.2 §5.8.3 p.152 l.11-13); the structure is entered with map(alloc:), so its descriptor
! is not initialized by a transfer and has to be set by the attach
! - same-compiler control: controls/g2-ctl-entered-to.f90 (one change from this file; correct on gcc_g90 (GCC 16.2.0), gcc_sm80 (GCC
! 16.2.0); rows results/nested/red/red1.jsonl, results/nested/red/tuo2.jsonl, results/nested/red/wgs.jsonl,
! results/nested/red/wnv.jsonl); controls/g2-ctl-allocatable.f90 (one change from this file; correct on gcc_g90 (GCC 16.2.0),
! gcc_sm80 (GCC 16.2.0); rows results/nested/red/red1.jsonl, results/nested/red/wgs.jsonl, results/nested/red/wnv.jsonl)
! - other families: afar (AFAR 24.3.0), cce19 (CCE 19.0.0), cce20 (CCE 20.0.2), cce21 (CCE 21.0.3), cce21_4 (CCE 21.0.4), nvhpc
! (NVHPC 25.11), nvhpc269 (NVHPC 26.9) run the file correctly (rows results/nested/red/tuo2.jsonl, results/nested/red/wnv.jsonl,
! site rows, check case site-nested--gcc-fortran-pointer-component-alloc-bounds-lost)
! - legality: the rules (offload.engine.rules) accept it, AFAR's flang front end accepts it
program t
use omp_lib
implicit none
type :: n0
integer :: s = 0
integer, pointer :: a(:) => null()
end type n0
type(n0) :: r
integer :: q, hf, tot
logical :: ok
hf = 1
!$omp target map(from: hf)
hf = merge(1, 0, omp_is_initial_device())
!$omp end target
allocate(r%a(8))
r%s = -1
r%a = -1
!$omp target enter data map(alloc: r)
!$omp target enter data map(alloc: r%a)
!$omp target
do q = 1, 8
r%a(q) = 500 + q - 1
end do
r%s = 900
!$omp end target
!$omp target exit data map(from: r%a)
!$omp target exit data map(from: r)
tot = sum(r%a)
ok = tot == 4028 .and. r%s == 900
print '(a,i0)', 'tot= ', tot
print '(a,i0)', 's= ', r%s
print '(a,i0,a,a)', 'RESULT ran_on_host=', hf, ' check=', merge('pass', 'fail', ok)
end program t
Something to add? Dispute its legality · Report it fixed in a newer release · Report a mistake on this page
Expected and observed
Observed where it behaves incorrectly
tot= 504 s= 900 RESULT ran_on_host=0 check=fail
What the specification requires
The specification text this program relies on and the compiler is expected to support.
OpenMP 5.2 §5.8.3 p.152 l.11-13
is associated with a pointer target that has the same rank and bounds as the pointer target of the original pointer, such that the corresponding list item can be accessed through the pointer in a target region
Evidence
Same compiler, one change
- one change from the finding; correct on gcc_g90, gcc_sm80: not run yet
Control program
! control: entered with to program t use omp_lib implicit none type :: n0 integer :: s = 0 integer, pointer :: a(:) => null() end type n0 type(n0) :: r integer :: q, hf, tot logical :: ok hf = 1 !$omp target map(from: hf) hf = merge(1, 0, omp_is_initial_device()) !$omp end target allocate(r%a(8)) r%s = -1 r%a = -1 !$omp target enter data map(to: r) !$omp target enter data map(to: r%a) !$omp target do q = 1, 8 r%a(q) = 500 + q - 1 end do r%s = 900 !$omp end target !$omp target exit data map(from: r%a) !$omp target exit data map(from: r) tot = sum(r%a) ok = tot == 4028 .and. r%s == 900 print '(a,i0)', 'tot= ', tot print '(a,i0)', 's= ', r%s print '(a,i0,a,a)', 'RESULT ran_on_host=', hf, ' check=', merge('pass', 'fail', ok) end program t - one change from the finding; correct on gcc_g90, gcc_sm80: not run yet
Control program
! control: allocatable component program t use omp_lib implicit none type :: n0 integer :: s = 0 integer, allocatable :: a(:) end type n0 type(n0) :: r integer :: q, hf, tot logical :: ok hf = 1 !$omp target map(from: hf) hf = merge(1, 0, omp_is_initial_device()) !$omp end target allocate(r%a(8)) r%s = -1 r%a = -1 !$omp target enter data map(alloc: r) !$omp target enter data map(alloc: r%a) !$omp target do q = 1, 8 r%a(q) = 500 + q - 1 end do r%s = 900 !$omp end target !$omp target exit data map(from: r%a) !$omp target exit data map(from: r) tot = sum(r%a) ok = tot == 4028 .and. r%s == 900 print '(a,i0)', 'tot= ', tot print '(a,i0)', 's= ', r%s print '(a,i0,a,a)', 'RESULT ran_on_host=', hf, ' check=', merge('pass', 'fail', ok) end program t
Other compilers run it correctly
AFAR 24.3.0, CCE 19.0.0, CCE 20.0.2, CCE 21.0.3, CCE 21.0.4, NVHPC 25.11, NVHPC 26.9