Observed issues › cce-defaultmap-tofrom-explicit-map
With a defaultmap clause on target, an explicitly mapped map(tofrom) scalar is not copied back, and with defaultmap(tofrom) an array in map(alloc) or map(to) is copied back
Legality: not independently confirmed. no independent review yet How this is checked
Same issue as cce21-defaultmap-aggregate-flag; this program is another reproducer of it.
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 | correct | correct | correct | correct | n/a | n/a |
| CCE 19.0.0 | behaves incorrectly | behaves incorrectly | behaves incorrectly | unknown not run | unknown not run | n/a | n/a |
| CCE 20.0.2 | behaves incorrectly | correct | correct | unknown not run | unknown not run | n/a | n/a |
| CCE 21.0.3 | behaves incorrectly | behaves incorrectly | behaves incorrectly | unknown not run | unknown not run | n/a | n/a |
| CCE 21.0.4 | behaves incorrectly | behaves incorrectly | behaves incorrectly | unknown not run | unknown not run | n/a | n/a |
| NVHPC 25.11 | n/a | n/a | n/a | n/a | n/a | correct | behaves incorrectly |
| NVHPC 26.9 | n/a | n/a | n/a | n/a | n/a | correct | 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 CCE 19.0.0, MI300A unified CCE 20.0.2, MI300A unified NVHPC 25.11, A100 managed NVHPC 26.9, A100 managed | showregion 1: host_flag=0 host a unchanged: 0 region 2: host_flag=0 host a unchanged: 0 region 3: host_flag=0 host a unchanged: 0 region 4: host_flag=0 host a unchanged: 0 |
| behaves incorrectly | CCE 19.0.0, MI300A copy CCE 19.0.0, MI250X | showregion 1: host_flag=0 host a unchanged: 64 region 2: host_flag=0 host a unchanged: 0 region 3: host_flag=0 host a unchanged: 64 region 4: host_flag=0 host a unchanged: 0 |
| behaves incorrectly | CCE 21.0.3, MI300A unified CCE 21.0.4, MI300A unified | showregion 1: host_flag=0 host a unchanged: 0 region 2: host_flag=1 host a unchanged: 0 region 3: host_flag=0 host a unchanged: 0 region 4: host_flag=1 host a unchanged: 0 |
| behaves incorrectly | CCE 21.0.3, MI300A copy CCE 21.0.3, MI250X CCE 21.0.4, MI300A copy CCE 21.0.4, MI250X | showregion 1: host_flag=0 host a unchanged: 64 region 2: host_flag=1 host a unchanged: 0 region 3: host_flag=0 host a unchanged: 64 region 4: host_flag=1 host a unchanged: 0 |
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
CCE 19.0.0, MI300A unified
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
CCE 20.0.2, MI300A unified
module load cce/20.0.2 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
CCE 21.0.3, MI300A unified
module load cce/21.0.3 craype-accel-amd-gfx942 rocm/7.2.0 module unload cray-mpich ftn -fopenmp -O2 repro.f90 -o repro HSA_XNACK=1 OMP_TARGET_OFFLOAD=mandatory ./repro
CCE 21.0.4, MI300A unified
module load cce/21.0.4 craype-accel-amd-gfx942 rocm/7.2.0 module unload cray-mpich ftn -fopenmp -O2 repro.f90 -o repro HSA_XNACK=1 OMP_TARGET_OFFLOAD=mandatory ./repro
NVHPC 25.11, A100 managed
export LD_LIBRARY_PATH=$NVHPC_25_11/compilers/lib nvfortran -mp=gpu -gpu=cc80 -gpu=mem:managed -O2 repro.f90 -o repro OMP_TARGET_OFFLOAD=mandatory ./repro
NVHPC 26.9, A100 managed
export LD_LIBRARY_PATH=$NVHPC_26_9/compilers/lib nvfortran -mp=gpu -gpu=cc80 -gpu=mem:managed -O2 repro.f90 -o repro OMP_TARGET_OFFLOAD=mandatory ./repro
GCC 16.2.0, MI300A unified (runs correctly)
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
Program (85 lines)
! CCE 19 applies defaultmap(tofrom) to an array the
! same target construct maps EXPLICITLY with map(alloc:) or map(to:): on
! exit it copies the device values back to the host.
! Spec: on exit from the region the original list item is updated only "if
! the map-type is from or tofrom" (5.2 §5.8.3 p.154, exit step 1a); alloc
! and to have no from transfer. "The defaultmap clause determines the
! implicit data-mapping or data-sharing attribute of certain variables"
! (5.2 §5.8.7 p.161), and "explicit data-environment attribute clauses on
! target directives determine the attributes" of the variables they name
! (5.2 §5.8.1 p.148), so defaultmap(tofrom) does not change a's map type.
! Premise: the original and corresponding items do not share storage. The
! spec allows shared storage (5.2 §5.8.3 p.153, "may share storage"), so
! the evidence holds only where they are separate: run at HSA_XNACK=0 (on
! MI300A copy mode, on MI250X a discrete GPU), and the control regions 1
! and 3 (the same maps without defaultmap) must leave the host a unchanged
! (64 of 64): separate storage in the same configuration without
! defaultmap; for regions 2 and 4 separate storage is the premise.
! Expected: every region prints "host a unchanged: 64".
! Observed (2026-10-22, -O2, OMP_TARGET_OFFLOAD=mandatory, HSA_XNACK=0, two
! runs each, the same every run; <host> MI250X gfx90a and <host>
! MI300A gfx942):
! - CCE 19.0.0: regions 1 and 3: 64; regions 2 and 4
! (with defaultmap(tofrom)), ran_on_host=0: 0 -- the device's writes
! reached the host a.
! - CCE 20.0.2 and AFAR 24.0.0git: 64 in every region (correct).
! - CCE 21.0.3 and 21.0.4 : regions 2 and 4 print
! ran_on_host=1, but that is the map(tofrom) host_flag, which CCE 21 does
! not copy back in a region with defaultmap (cce21-defaultmap-aggregate-
! flag.f90): the label `ran_on_host=` names no independent measurement,
! and the regions run on the device. At HSA_XNACK=0 CCE 21.0.3 and 21.0.4
! copy a back in regions 2 and 4 (host a unchanged: 0): this defect, fixed
! in 20.0.2, is back in 21 (data/vendor/hpe/cce21-defaultmap-aggregate-
! flag.md, variants: confirmed in the four environments on both releases).
! Found by the gfx90a map-mutant audit (data/reports/map-mutant-audit-
! gfx90a.md): the weaken_map and swap_to_from mutants of the defaultmap-
! tofrom programs survive on CCE 19.
! CCE: ftn -fopenmp -O2 (module load cce/<v> craype-accel-amd-<gfx>
! rocm/<r>; module unload cray-mpich)
! AFAR: amdflang -fopenmp --offload-arch=<gfx> -O2
! Run: OMP_TARGET_OFFLOAD=mandatory HSA_XNACK=0 ./a.out
program p
use omp_lib, only: omp_is_initial_device
implicit none
integer, parameter :: n = 64
integer, allocatable :: a(:)
integer :: i, k, host_flag
do k = 1, 4
allocate(a(n))
a = [(i, i = 1, n)]
host_flag = 1
select case (k)
case (1)
!$omp target map(alloc: a) map(tofrom: host_flag)
host_flag = merge(1, 0, omp_is_initial_device())
do i = 1, n
a(i) = -i
end do
!$omp end target
case (2)
!$omp target map(alloc: a) map(tofrom: host_flag) defaultmap(tofrom)
host_flag = merge(1, 0, omp_is_initial_device())
do i = 1, n
a(i) = -i
end do
!$omp end target
case (3)
!$omp target map(to: a) map(tofrom: host_flag)
host_flag = merge(1, 0, omp_is_initial_device())
do i = 1, n
a(i) = -i
end do
!$omp end target
case (4)
!$omp target map(to: a) map(tofrom: host_flag) defaultmap(tofrom)
host_flag = merge(1, 0, omp_is_initial_device())
do i = 1, n
a(i) = -i
end do
!$omp end target
end select
print '(a,i0,a,i0,a,i0)', 'region ', k, ': ran_on_host=', host_flag, &
' host a unchanged: ', count(a == [(i, i = 1, n)])
deallocate(a)
end do
end program p
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
region 1: host_flag=0 host a unchanged: 0 region 2: host_flag=0 host a unchanged: 0 region 3: host_flag=0 host a unchanged: 0 region 4: host_flag=0 host a unchanged: 0
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.154
if the map-type is from or tofrom
OpenMP 5.2 §5.8.7 p.161
The defaultmap clause determines the implicit data-mapping or data-sharing attribute of certain variables
OpenMP 5.2 §5.8.1 p.148
OpenMP 5.2 §5.8.3 p.153
Evidence
Same compiler, one change
- defaultmap(tofrom) removed from regions 2 and 4: AFAR 24.3.0: behaves incorrectly; AFAR 24.3.0: correct; CCE 19.0.0: behaves incorrectly; CCE 19.0.0: correct; CCE 20.0.2: behaves incorrectly; CCE 20.0.2: correct; CCE 21.0.3: behaves incorrectly; CCE 21.0.3: correct; CCE 21.0.4: behaves incorrectly; CCE 21.0.4: correct
Control program
program p use omp_lib, only: omp_is_initial_device implicit none integer, parameter :: n = 64 integer, allocatable :: a(:) integer :: i, k, host_flag do k = 1, 4 allocate(a(n)) a = [(i, i = 1, n)] host_flag = 1 select case (k) case (1) !$omp target map(alloc: a) map(tofrom: host_flag) host_flag = merge(1, 0, omp_is_initial_device()) do i = 1, n a(i) = -i end do !$omp end target case (2) !$omp target map(alloc: a) map(tofrom: host_flag) host_flag = merge(1, 0, omp_is_initial_device()) do i = 1, n a(i) = -i end do !$omp end target case (3) !$omp target map(to: a) map(tofrom: host_flag) host_flag = merge(1, 0, omp_is_initial_device()) do i = 1, n a(i) = -i end do !$omp end target case (4) !$omp target map(to: a) map(tofrom: host_flag) host_flag = merge(1, 0, omp_is_initial_device()) do i = 1, n a(i) = -i end do !$omp end target end select print '(a,i0,a,i0,a,i0)', 'region ', k, ': host_flag=', host_flag, & ' host a unchanged: ', count(a == [(i, i = 1, n)]) deallocate(a) end do end program p
Other compilers run it correctly
GCC 16.2.0