Observed issues › cce21-in-reduction-taskwait-link
Appears not to supportRefused at link time · Fortran · OpenMP · Open · regression
ftn: in_reduction on a target construct fails to link (undefined _cray$mt_taskwait in the device code)
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 | correct | correct | correct | n/a | n/a |
| CCE 19.0.0 | correct | correct | correct | unknown not run | unknown not run | n/a | n/a |
| CCE 20.0.2 | correct | correct | correct | unknown not run | unknown not run | n/a | n/a |
| CCE 21.0.3 | not supported | not supported | not supported | unknown not run | unknown not run | n/a | n/a |
| CCE 21.0.4 | not supported | not supported | not supported | unknown not run | unknown not run | n/a | n/a |
| NVHPC 25.11 | n/a | n/a | n/a | n/a | n/a | fails another way | fails another way |
| NVHPC 26.9 | n/a | n/a | n/a | n/a | n/a | fails another way | fails another way |
| GCC 16.2.0 | fails another way | fails another way | fails another way | fails another way | fails another way | fails another way | 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 |
|---|---|---|
| not supported | CCE 21.0.3, MI300A unified CCE 21.0.3, MI300A copy | showWarning: Headers and libraries from cray-libsci/26.03.0 will be ignored because depends on PE_MPICH which is unavailable.. lld: error: undefined symbol: _cray$mt_taskwait >>> referenced by <dir>/pe_3067603//cooltmpdir-svH0y5/repro-cce-openmppost_lld.amdgpu.lto.o:(gen_prog_$ck_L23_1) >>> referenced by <dir>/pe_3067603//cooltmpdir-svH0y5/repro-cce-openmppost_lld.amdgpu.lto.o:(gen_prog_$ck_L23_1) >>> referenced by <dir>/pe_3067603//cooltmpdir-svH0y5/repro-cce-openmppost_lld.amdgpu.lto.o:(gen_prog_$ck_L23_1) >>> referenced 1 more times |
| not supported | CCE 21.0.3, MI250X | showWarning: Headers and libraries from cray-libsci/26.03.0 will be ignored because depends on PE_MPICH which is unavailable.. lld: error: undefined symbol: _cray$mt_taskwait >>> referenced by <dir>/pe_3622278//cooltmpdir-Sd7tFy/repro-cce-openmppost_lld.amdgpu.lto.o:(gen_prog_$ck_L23_1) >>> referenced by <dir>/pe_3622278//cooltmpdir-Sd7tFy/repro-cce-openmppost_lld.amdgpu.lto.o:(gen_prog_$ck_L23_1) >>> referenced by <dir>/pe_3622278//cooltmpdir-Sd7tFy/repro-cce-openmppost_lld.amdgpu.lto.o:(gen_prog_$ck_L23_1) >>> referenced 1 more times |
| not supported | CCE 21.0.4, MI300A unified CCE 21.0.4, MI300A copy | showWarning: Headers and libraries from cray-libsci/26.03.0 will be ignored because depends on PE_MPICH which is unavailable.. lld: error: undefined symbol: _cray$mt_taskwait >>> referenced by <dir>/pe_2824163//cooltmpdir-J4EMz6/repro-cce-openmppost_lld.amdgpu.lto.o:(gen_prog_$ck_L23_1) >>> referenced by <dir>/pe_2824163//cooltmpdir-J4EMz6/repro-cce-openmppost_lld.amdgpu.lto.o:(gen_prog_$ck_L23_1) >>> referenced by <dir>/pe_2824163//cooltmpdir-J4EMz6/repro-cce-openmppost_lld.amdgpu.lto.o:(gen_prog_$ck_L23_1) >>> referenced 1 more times |
| not supported | CCE 21.0.4, MI250X | showWarning: Headers and libraries from cray-libsci/26.03.0 will be ignored because depends on PE_MPICH which is unavailable.. lld: error: undefined symbol: _cray$mt_taskwait >>> referenced by <dir>/pe_3695362//cooltmpdir-ZYn3xp/repro-cce-openmppost_lld.amdgpu.lto.o:(gen_prog_$ck_L23_1) >>> referenced by <dir>/pe_3695362//cooltmpdir-ZYn3xp/repro-cce-openmppost_lld.amdgpu.lto.o:(gen_prog_$ck_L23_1) >>> referenced by <dir>/pe_3695362//cooltmpdir-ZYn3xp/repro-cce-openmppost_lld.amdgpu.lto.o:(gen_prog_$ck_L23_1) >>> referenced 1 more times |
| fails another way | NVHPC 25.11, A100 separate NVHPC 25.11, A100 managed NVHPC 26.9, A100 separate NVHPC 26.9, A100 managed | showNVFORTRAN-S-0034-Syntax error at or near identifier task_reduction (cce21-in-reduction-taskwait-link.f90: 22) NVFORTRAN-S-0034-Syntax error at or near identifier in_reduction (cce21-in-reduction-taskwait-link.f90: 23) 0 inform, 0 warnings, 2 severes, 0 fatal for gen_prog |
| fails another way | 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 GCC 16.2.0, A100 separate | showlibgomp: OMP_TARGET_OFFLOAD is set to MANDATORY, but device not found |
Reproduce
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
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 (53 lines)
! Generated by compliance.gen (OpenMP 5.2, free-form Fortran). Do not edit.
! id: omp52-clause-in_reduction-and
! primary atom: omp.clause.in_reduction.and
! legal: yes
! observable: yes
! ran_on_host: inside the target region of interest
! evidence: construct
! needs: none
! std: f2008
program gen_prog
use omp_lib, only: omp_is_initial_device
implicit none
integer, parameter :: n = 64
integer, allocatable, target :: a(:), b(:)
integer :: ref(n)
integer :: i, host_flag
logical :: ok
logical :: ls, lsref
allocate(a(n), b(n))
do i = 1, n
a(i) = i
b(i) = 0
ref(i) = 2*i + 1
end do
host_flag = 1
ls = .true.
lsref = .true.
do i = 1, n
lsref = lsref .and. (a(i) /= 17)
end do
!$omp taskgroup task_reduction(.and.: ls)
!$omp target map(to: a) map(from: b) map(tofrom: host_flag) in_reduction(.and.: ls)
host_flag = merge(1, 0, omp_is_initial_device())
do i = 1, n
b(i) = 2*a(i) + 1
ls = ls .and. (a(i) /= 17)
end do
!$omp end target
!$omp end taskgroup
ok = all(b == ref) .and. (ls .eqv. lsref)
print '(a,i0,a,a)', 'RESULT ran_on_host=', host_flag, ' check=', merge('pass', 'fail', ok)
deallocate(a, b)
end program gen_prog
! spec (requirement): An in_reduction clause on a target construct makes the target task a participant in the task
! reduction defined by an enclosing taskgroup with a matching task_reduction clause.
! "For the target construct, the target task becomes the participating task." (5.2 §5.5.10 p.138 l.21-22)
! spec (requirement): The private copy of an in_reduction list item on a target construct is implicitly mapped into
! the device data environment and combined at the end of the task region.
! "This private copy will be implicitly mapped into the device data environment of the target device, if the target
! device is not the parent device." (5.2 §5.5.10 p.138 l.23-24)
! spec (this program): The target construct lists in_reduction(.and.: ls) inside a taskgroup with
! task_reduction(.and.: ls), which matches in operator and list item; the compiler fails to link the device code
! (undefined _cray$mt_taskwait) instead of performing the reduction.
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
Warning: Headers and libraries from cray-libsci/26.03.0 will be ignored because depends on PE_MPICH which is unavailable.. lld: error: undefined symbol: _cray$mt_taskwait >>> referenced by <dir>/pe_3067603//cooltmpdir-svH0y5/repro-cce-openmppost_lld.amdgpu.lto.o:(gen_prog_$ck_L23_1) >>> referenced by <dir>/pe_3067603//cooltmpdir-svH0y5/repro-cce-openmppost_lld.amdgpu.lto.o:(gen_prog_$ck_L23_1) >>> referenced by <dir>/pe_3067603//cooltmpdir-svH0y5/repro-cce-openmppost_lld.amdgpu.lto.o:(gen_prog_$ck_L23_1) >>> referenced 1 more times
What the specification requires
The specification text this program relies on and the compiler is expected to support.
OpenMP 5.2 §5.5.10 p.138 l.21-22
For the target construct, the target task becomes the participating task.
OpenMP 5.2 §5.5.10 p.138 l.23-24
This private copy will be implicitly mapped into the device data environment of the target device, if the target device is not the parent device.
Evidence
Same compiler, one change
- in_reduction(.and.: ls) on the target replaced by map(tofrom: ls), without the enclosing taskgroup: 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
Control program
program gen_prog use omp_lib, only: omp_is_initial_device implicit none integer, parameter :: n = 64 integer, allocatable, target :: a(:), b(:) integer :: ref(n) integer :: i, host_flag logical :: ok logical :: ls, lsref allocate(a(n), b(n)) do i = 1, n a(i) = i b(i) = 0 ref(i) = 2*i + 1 end do host_flag = 1 ls = .true. lsref = .true. do i = 1, n lsref = lsref .and. (a(i) /= 17) end do !$omp target map(to: a) map(from: b) map(tofrom: host_flag) map(tofrom: ls) host_flag = merge(1, 0, omp_is_initial_device()) do i = 1, n b(i) = 2*a(i) + 1 ls = ls .and. (a(i) /= 17) end do !$omp end target ok = all(b == ref) .and. (ls .eqv. lsref) print '(a,i0,a,a)', 'RESULT ran_on_host=', host_flag, ' check=', merge('pass', 'fail', ok) deallocate(a, b) end program gen_prog
Other compilers run it correctly
AFAR 24.3.0