Observed issues › oop/cce-class-is-device-link
a CLASS IS guard of SELECT TYPE in device code fails at the link
Legality: independently confirmed. 2 independent readings find the program legal and the result required. How this is checked
SELECT TYPE with a CLASS IS guard in a declare target subroutine called in a target region fails at the device link on CCE 19, 20 and 21 (undefined _EXTENDS_TYPE_OF). AFAR runs it correctly.
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 | not supported | not supported | unknown not run | unknown not run | unknown not run | n/a | n/a |
| CCE 20.0.2 | not supported | not supported | unknown not run | unknown not run | unknown not run | n/a | n/a |
| CCE 21.0.3 | not supported | not supported | unknown not run | unknown not run | unknown not run | n/a | n/a |
| CCE 21.0.4 | not supported | not supported | 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 | 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 19.0.0, MI300A unified CCE 19.0.0, MI300A copy | showWarning: Headers and libraries from cray-libsci/25.03.0 will be ignored because depends on PE_MPICH which is unavailable.. lld: error: undefined symbol: _EXTENDS_TYPE_OF >>> referenced by <dir>:(oop_$ck_L61_2) >>> referenced by <dir>:(oop_$ck_L61_2) >>> referenced by <dir>:(oop_$ck_L61_2) >>> referenced 3 more times |
| not supported | CCE 20.0.2, MI300A unified CCE 20.0.2, MI300A copy | showWarning: Headers and libraries from cray-libsci/25.09.0 will be ignored because depends on PE_MPICH which is unavailable.. lld: error: undefined symbol: _EXTENDS_TYPE_OF >>> referenced by <dir>:(oop_$ck_L61_2) >>> referenced by <dir>:(oop_$ck_L61_2) >>> referenced by <dir>:(oop_$ck_L61_2) >>> referenced 3 more times |
| 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: _EXTENDS_TYPE_OF >>> referenced by <dir>//cooltmpdir-y9hUzu/repro-cce-openmppost_lld.amdgpu.lto.o:(oop_$ck_L61_2) >>> referenced by <dir>//cooltmpdir-y9hUzu/repro-cce-openmppost_lld.amdgpu.lto.o:(oop_$ck_L61_2) >>> referenced by <dir>//cooltmpdir-y9hUzu/repro-cce-openmppost_lld.amdgpu.lto.o:(oop_$ck_L61_2) >>> referenced 3 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: _EXTENDS_TYPE_OF >>> referenced by <dir>//cooltmpdir-oSh743/repro-cce-openmppost_lld.amdgpu.lto.o:(oop_$ck_L61_2) >>> referenced by <dir>//cooltmpdir-oSh743/repro-cce-openmppost_lld.amdgpu.lto.o:(oop_$ck_L61_2) >>> referenced by <dir>//cooltmpdir-oSh743/repro-cce-openmppost_lld.amdgpu.lto.o:(oop_$ck_L61_2) >>> referenced 3 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-1058-Call to Compiler runtime function not supported - pgf90_same_type_as_i8 (site-oop--cce-class-is-device-link.f90: 37) 0 inform, 0 warnings, 1 severes, 0 fatal for tag |
| fails another way | GCC 16.2.0, MI300A unified GCC 16.2.0, MI300A copy GCC 16.2.0, MI250X | showsite-oop--cce-class-is-device-link.f90:44:16: error: variable ‘__vtab_oop_m_Ext2’ has been referenced in offloaded code but hasn’t been marked to be included in the offloaded code
44 | end module oop_m
| ^
site-oop--cce-class-is-device-link.f90:44:16: error: variable ‘__vtab_oop_m_Base_t’ has been referenced in offloaded code but hasn’t been marked to be included in the offloaded code
lto1: fatal error: errors during merging of translation units
compilation terminated.
gcn mkoffload: fatal error: <home>/gcc-16.2/bin/x86_64-pc-linux-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status
compilation terminated. |
| fails another way | GCC 16.2.0, MI300X GCC 16.2.0, MI350X | showsite-oop--cce-class-is-device-link.f90:44:16: error: variable ‘__vtab_oop_m_Ext2’ has been referenced in offloaded code but hasn’t been marked to be included in the offloaded code
44 | end module oop_m
| ^
site-oop--cce-class-is-device-link.f90:44:16: error: variable ‘__vtab_oop_m_Base_t’ has been referenced in offloaded code but hasn’t been marked to be included in the offloaded code
lto1: fatal error: errors during merging of translation units
compilation terminated.
gcn mkoffload: fatal error: <home>/<user>/gcc-16.2/bin/x86_64-pc-linux-gnu-accel-amdgcn-amdhsa-gcc returned 1 exit status
compilation terminated. |
| fails another way | GCC 16.2.0, A100 separate | showsite-oop--cce-class-is-device-link.f90:44:16: error: variable ‘__vtab_oop_m_Ext2’ has been referenced in offloaded code but hasn’t been marked to be included in the offloaded code
44 | end module oop_m
| ^
site-oop--cce-class-is-device-link.f90:44:16: error: variable ‘__vtab_oop_m_Base_t’ has been referenced in offloaded code but hasn’t been marked to be included in the offloaded code
lto1: fatal error: errors during merging of translation units
compilation terminated.
nvptx mkoffload: fatal error: <home>/gcc-16.2/bin/x86_64-pc-linux-gnu-accel-nvptx-none-gcc returned 1 exit status
compilation terminated. |
Reproduce
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
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 (81 lines)
! # Finding (fortran-oop): SELECT TYPE with a CLASS IS guard in device code fails to link (_EXTENDS_TYPE_OF)
!
! - toolchains and modes that fail: cce19 (CCE 19.0.0: copy, unified), cce20 (CCE 20.0.2: copy, unified), cce21 (CCE 21.0.3: copy,
! unified), cce21_4 (CCE 21.0.4: copy, unified); -O2
! - build: ftn -fopenmp -O2 (module load cce/<v> craype-accel-amd-gfx942 rocm/<r>; OpenACC: ftn -h acc)
! - failure: rejected (link_undefined_symbol, the program's own object); OMP_TARGET_OFFLOAD=mandatory
! - observed: `lld: error: undefined symbol: _EXTENDS_TYPE_OF`, every CCE release, both modes
! - expected: compiles; `r1= 121`
! - rule: Fortran 2018 11.1.11 (CLASS IS guards); no OpenMP restriction on SELECT TYPE in device procedures
! (section 6)
! - same-compiler control: TYPE IS guards only (oop-poly-select-type) link (and then take the wrong branch:
! cce-select-type-guard-not-taken.f90)
! - other families: AFAR correct; GCC 16.2 rejects it (gcc-vtab-not-marked-for-offload.f90)
! - gate and confirmer: 8 cells, 8 confirmed in the gate's four environments (a-d; results/oop/main/gate_reruns*.jsonl); confirmer
! (results/oop/main/confirm.jsonl): compiler_bug (R10b-own-link-or-hang) 8
! - programs (1): oop-poly-class-is (offload/engine/oop_gen.py; this file is the first one)
! - legality: for the cce cells: the rules (offload.engine.rules, with the fortran-oop restrictions) and AFAR's flang front end
! (-fsyntax-only) (tools/campaigns/oop.py legality, results/oop/main/legality.json)
module oop_m
implicit none
integer, parameter :: n = 64
type base_t
integer :: a = 0
end type base_t
type, extends(base_t) :: ext1
integer :: u = 0
end type ext1
type, extends(base_t) :: ext2
integer :: v = 0
end type ext2
contains
subroutine tag(s, t)
!$omp declare target
class(base_t), intent(in) :: s
integer, intent(out) :: t
t = 0
select type (s)
class is (base_t)
t = 1
type is (ext2)
t = 2
end select
end subroutine tag
end module oop_m
program oop
use omp_lib
use oop_m
implicit none
integer :: host_flag
logical :: ok
integer :: r1
type(ext1) :: e1
type(ext2) :: e2
type(base_t) :: b0
integer :: t1, t2, t3
host_flag = 1
!$omp target map(from: host_flag)
host_flag = merge(1, 0, omp_is_initial_device())
!$omp end target
!$omp target map(tofrom: e1, e2, b0) map(from: t1, t2, t3)
call tag(e1, t1)
call tag(e2, t2)
call tag(b0, t3)
!$omp end target
r1 = 100 * t1 + 10 * t2 + t3
ok = .true.
ok = ok .and. (r1 == 121)
print '(a,i0)', 'r1= ', r1
print '(a,i0,a,a)', 'RESULT ran_on_host=', host_flag, ' check=', merge('pass', 'fail', ok)
end program oop
! spec (requirement): the base language is Fortran 2003, 2008 and 2018, and only the few Fortran features listed in the
! base-language section have unspecified behavior (SELECT TYPE with a CLASS IS guard is not one of them; its semantics are the
! Fortran standard's, with no OpenMP text of its own); a declare target procedure must be executable on a device.
! "While future versions of the OpenMP specification are expected to address the following features, currently their use may
! result in unspecified behavior." (5.2 §1.7 p.36 l.6-8)
! "Declare target directives apply to procedures and/or variables to ensure that they can be executed or accessed on a device."
! (5.2 §7.8 p.204 l.16-17)
! spec (this program): the declare target subroutine tag uses SELECT TYPE with a CLASS IS guard and is called in a target
! region; CCE 19, 20 and 21 build it but fail at the link (undefined symbol _EXTENDS_TYPE_OF), so the procedure cannot be
! executed on the device.
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/25.03.0 will be ignored because depends on PE_MPICH which is unavailable.. lld: error: undefined symbol: _EXTENDS_TYPE_OF >>> referenced by <dir>:(oop_$ck_L61_2) >>> referenced by <dir>:(oop_$ck_L61_2) >>> referenced by <dir>:(oop_$ck_L61_2) >>> referenced 3 more times
What the specification requires
The specification text this program relies on and the compiler is expected to support.
OpenMP 5.2 §1.7 p.36 l.6-8
While future versions of the OpenMP specification are expected to address the following features, currently their use may result in unspecified behavior.
OpenMP 5.2 §7.8 p.204 l.16-17
Declare target directives apply to procedures and/or variables to ensure that they can be executed or accessed on a device.
Evidence
Other compilers run it correctly
AFAR 24.3.0