Observed issues › stress/nvhpc-target-scalar-implicit-firstprivate
Scalar with the TARGET attribute is treated as firstprivate in a target region (device write lost)
Legality: independently confirmed. 2 independent readings find the program legal and the result required. How this is checked
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 | behaves incorrectly | behaves incorrectly | unknown not run | behaves incorrectly | behaves incorrectly | 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 | behaves incorrectly | behaves incorrectly |
| NVHPC 26.9 | n/a | n/a | n/a | n/a | n/a | behaves incorrectly | behaves incorrectly |
| GCC 16.2.0 | correct | correct | correct | correct | correct | correct | 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 | AFAR 24.3.0, MI300A unified AFAR 24.3.0, MI300A copy AFAR 24.3.0, MI300X AFAR 24.3.0, MI350X NVHPC 25.11, A100 separate NVHPC 25.11, A100 managed NVHPC 26.9, A100 separate NVHPC 26.9, A100 managed | showrd= 101 s= 101 dev= 1 |
Reproduce
AFAR 24.3.0, MI300A unified
$AFAR/bin/amdflang -fopenmp --offload-arch=gfx942 -O2 repro.f90 -o repro HSA_XNACK=1 OMP_TARGET_OFFLOAD=mandatory ./repro
NVHPC 25.11, A100 separate
export LD_LIBRARY_PATH=$NVHPC_25_11/compilers/lib nvfortran -mp=gpu -gpu=cc80 -gpu=mem:separate -O2 repro.f90 -o repro OMP_TARGET_OFFLOAD=mandatory ./repro
NVHPC 26.9, A100 separate
export LD_LIBRARY_PATH=$NVHPC_26_9/compilers/lib nvfortran -mp=gpu -gpu=cc80 -gpu=mem:separate -O2 repro.f90 -o repro OMP_TARGET_OFFLOAD=mandatory ./repro
CCE 19.0.0, MI300A unified (runs correctly)
module load cce/19.0.0 craype-accel-amd-gfx942 rocm/6.4.3 module unload cray-mpich ftn -fopenmp -O2 repro.f90 -o repro HSA_XNACK=1 OMP_TARGET_OFFLOAD=mandatory ./repro
Program (35 lines)
! # Finding: NVHPC treats a TARGET scalar as firstprivate in a target region
!
! - compilers: NVHPC nvfortran 25.11 and 26.9, A100 (sm_80), -mp=gpu -gpu=cc80, separate
! (-gpu=mem:separate) and managed (-gpu=mem:managed) memory, -O2
! - expected: rd= 101 s= 203 dev= 1. A scalar with the TARGET attribute referenced in a target region
! "is treated as if it had appeared in a map clause with a map-type of tofrom" (5.2 §5.8.1 p.149
! l.6-7; 5.0 §2.19.7 p.315 l.7-8; 6.0 §7.9.3 p.277 l.17-18), so the write s = 2*s+1 returns 203
! - actual: rd= 101 s= 101 dev= 1 on both releases and both memory modes (the region ran on the
! device and read s; its write was not copied back: s behaves as firstprivate)
! - control (same compiler): the same program with map(tofrom: rd, dev, s)
! (data/reports/fuzz-stress-audit/r1-target-scalar-control.f90): 203 on both releases and modes
! - other families: CCE 19/20/21 give 203 on the same program (MI300A HSA_XNACK 1 and 0; MI250X).
! AFAR fails the same way: stress/afar-target-scalar-implicit-firstprivate.f90 (sibling entry)
! - legality: legal by reading: one initial thread in the region; rd and dev mapped tofrom, s
! implicitly tofrom; no data race
! - evidence: results/stress/audit/runs-nvhpc.jsonl (tools/jobs/run_wingtip_fix1.sh, tools/campaigns/stress_audit.py
! on data/reports/fuzz-stress-audit/r1-target-scalar*.f90). The confirmer gave needs_human (R22): it
! does not draw a witness across machines; the audit counts the executed MI300A results
! as the other-family witness for this deterministic single-construct program
program target_scalar_tofrom
use omp_lib
implicit none
integer(8), target :: s
integer(8) :: rd
integer :: dev
s = 101
rd = -1
dev = -1
!$omp target map(tofrom: rd, dev)
rd = s
s = 2 * s + 1
dev = merge(0, 1, omp_is_initial_device())
!$omp end target
print '(a,i0,a,i0,a,i0)', 'rd= ', rd, ' s= ', s, ' dev= ', dev
end program target_scalar_tofrom
Something to add? Dispute its legality · Report it fixed in a newer release · Report a mistake on this page
Expected and observed
Expected
rd= 101 s= 203 dev= 1
Observed where it behaves incorrectly
rd= 101 s= 101 dev= 1
What the specification requires
The specification text this program relies on and the compiler is expected to support.
OpenMP 5.2 §5.8.1 p.149 l.6-7
is treated as if it had appeared in a map clause with a map-type of tofrom
OpenMP 5.0 §2.19.7 p.315 l.7-8
OpenMP 6.0 §7.9.3 p.277 l.17-18
Evidence
Same compiler, one change
- s mapped explicitly: map(tofrom: rd, dev, s): AFAR 24.3.0: correct; CCE 19.0.0: correct; CCE 20.0.2: correct; CCE 21.0.3: correct; CCE 21.0.4: correct; NVHPC 25.11: correct; NVHPC 26.9: correct
Control program
program target_scalar_tofrom use omp_lib implicit none integer(8), target :: s integer(8) :: rd integer :: dev s = 101 rd = -1 dev = -1 !$omp target map(tofrom: rd, dev, s) rd = s s = 2 * s + 1 dev = merge(0, 1, omp_is_initial_device()) !$omp end target print '(a,i0,a,i0,a,i0)', 'rd= ', rd, ' s= ', s, ' dev= ', dev end program target_scalar_tofrom
Other compilers run it correctly
CCE 19.0.0, CCE 20.0.2, CCE 21.0.3, CCE 21.0.4, GCC 16.2.0