Observed issues › stress/nvhpc-declare-target-scalar-write-lost
nvfortran -mp=gpu: write to a declare target module scalar in a target region is lost (implicit map)
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 | 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 | 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 | NVHPC 25.11, A100 separate NVHPC 25.11, A100 managed NVHPC 26.9, A100 separate NVHPC 26.9, A100 managed | showg= 101 dev= 1 |
Reproduce
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
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 (38 lines)
! # Finding: NVHPC loses the device write to a declare target scalar
!
! - compilers: NVHPC nvfortran 25.11 and 26.9, A100 (sm_80), -mp=gpu -gpu=cc80, separate and
! managed memory, -O2
! - expected: g= 203 dev= 1. g appears in an enter clause (the 5.0 declare target(list) form). A
! variable in an enter clause referenced in a target construct is treated as map(tofrom) (5.2
! §5.8.1 p.148 l.9-11); its corresponding list item is never removed, "as if its reference count
! was initialized to positive infinity" (§5.8.4 p.159 l.10-14), so on entry and exit there is no
! transfer (§5.8.3 p.153 l.1-17, p.153 l.31-35, p.154 l.1-11): the region reads the device copy set by
! "target update to" (101), writes 203 to it, and "target update from" returns 203
! - actual: g= 101 dev= 1 on both releases and both memory modes
! - control (same compiler): the same program with an explicit map(tofrom: dev, g)
! (data/reports/fuzz-stress-audit/r4-declare-target-scalar-control.f90): 203 on both releases and
! modes. (CCE 21 fails that control: stress/cce21-declare-target-scalar-map-write-lost.f90.)
! - other families: AFAR and CCE 19/20/21 give 203 on this program (MI300A HSA_XNACK 1 and 0)
! - legality: legal by reading: a module variable, no parallelism in the region
! - evidence: results/stress/audit/runs-nvhpc.jsonl (tools/jobs/run_wingtip_fix1.sh). The confirmer gave
! needs_human (R22, no cross-machine witness); the audit counts the MI300A results
module dt_scalar_m
implicit none
integer(8) :: g
!$omp declare target(g)
end module dt_scalar_m
program declare_target_scalar
use omp_lib
use dt_scalar_m
implicit none
integer :: dev
g = 101
dev = -1
!$omp target update to(g)
!$omp target map(tofrom: dev)
g = 2 * g + 1
dev = merge(0, 1, omp_is_initial_device())
!$omp end target
!$omp target update from(g)
print '(a,i0,a,i0)', 'g= ', g, ' dev= ', dev
end program declare_target_scalar
Something to add? Dispute its legality · Report it fixed in a newer release · Report a mistake on this page
Expected and observed
Expected
g= 203 dev= 1
Observed where it behaves incorrectly
g= 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.148 l.9-11
OpenMP 5.2 §5.8.4 p.159 l.10-14
as if its reference count was initialized to positive infinity
OpenMP 5.2 §5.8.3 p.153 l.1-17
OpenMP 5.2 §5.8.3 p.153 l.1-17
OpenMP 5.2 §5.8.3 p.153 l.1-17
Evidence
Same compiler, one change
- g mapped explicitly: map(tofrom: dev, g): AFAR 24.3.0: correct; CCE 19.0.0: correct; CCE 20.0.2: correct; CCE 21.0.3: behaves incorrectly; CCE 21.0.4: behaves incorrectly; NVHPC 25.11: correct; NVHPC 26.9: correct
Control program
module dt_scalar_m implicit none integer(8) :: g !$omp declare target(g) end module dt_scalar_m program declare_target_scalar use omp_lib use dt_scalar_m implicit none integer :: dev g = 101 dev = -1 !$omp target update to(g) !$omp target map(tofrom: dev, g) g = 2 * g + 1 dev = merge(0, 1, omp_is_initial_device()) !$omp end target !$omp target update from(g) print '(a,i0,a,i0)', 'g= ', g, ' dev= ', dev end program declare_target_scalar
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, GCC 16.2.0