blob: bc34f30402f6cbd71a93eb51cf5a0558de7d89aa [file] [edit]
! RUN: bbc -emit-hlfir -fcuda %s -o - | FileCheck %s
! Test that allocating a component of a CUDA-attributed derived type variable
! routes through the CUF allocator, not the default (host) allocator.
! This ensures the component data lives in the same memory space as its parent.
module m
type :: chunk_type
real(8), dimension(:,:), allocatable :: arr
end type
type :: outer_device_type
type(chunk_type), device, allocatable :: inner(:)
end type
end module
! Explicit managed attribute on variable with allocatable component.
subroutine managed_component()
use m
type(chunk_type), managed, allocatable :: chunks(:)
allocate(chunks(1))
allocate(chunks(1)%arr(10,10))
deallocate(chunks)
end subroutine
! CHECK-LABEL: func.func @_QPmanaged_component()
! CHECK: cuf.allocate %{{.*}} : {{.*}} {data_attr = #cuf.cuda<managed>} -> i32
! CHECK: hlfir.designate %{{.*}}{"arr"} {{.*}} : {{.*}} -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf64>>>>
! CHECK: fir.embox %{{.*}} {allocator_idx = 3 : i32}
! CHECK: cuf.allocate %{{.*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf64>>>> {data_attr = #cuf.cuda<managed>} -> i32
! Device attribute on variable with allocatable component.
subroutine device_component()
use m
type(chunk_type), device, allocatable :: chunks(:)
allocate(chunks(1))
allocate(chunks(1)%arr(10,10))
deallocate(chunks)
end subroutine
! CHECK-LABEL: func.func @_QPdevice_component()
! CHECK: cuf.allocate %{{.*}} : {{.*}} {data_attr = #cuf.cuda<device>} -> i32
! CHECK: hlfir.designate %{{.*}}{"arr"} {{.*}} : {{.*}} -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf64>>>>
! CHECK: fir.embox %{{.*}} {allocator_idx = 2 : i32}
! CHECK: cuf.allocate %{{.*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf64>>>> {data_attr = #cuf.cuda<device>} -> i32
! Managed component with source allocation.
subroutine managed_component_source()
use m
type(chunk_type), managed, allocatable :: chunks(:)
real(8), allocatable :: src(:,:)
allocate(chunks(1))
allocate(src(10,10))
allocate(chunks(1)%arr, source=src)
deallocate(chunks)
end subroutine
! CHECK-LABEL: func.func @_QPmanaged_component_source()
! CHECK: cuf.allocate %{{.*}} : {{.*}} {data_attr = #cuf.cuda<managed>} -> i32
! CHECK: hlfir.designate %{{.*}}{"arr"} {{.*}} : {{.*}} -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf64>>>>
! CHECK: fir.embox %{{.*}} {allocator_idx = 3 : i32}
! CHECK: cuf.allocate %{{.*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf64>>>> source({{.*}}) {data_attr = #cuf.cuda<managed>} -> i32
! Intermediate component has device attribute, outermost variable does not.
subroutine intermediate_device_component()
use m
type(outer_device_type), allocatable :: outer(:)
allocate(outer(1))
allocate(outer(1)%inner(1))
allocate(outer(1)%inner(1)%arr(10,10))
deallocate(outer)
end subroutine
! CHECK-LABEL: func.func @_QPintermediate_device_component()
! CHECK: hlfir.designate %{{.*}}{"arr"} {{.*}} : {{.*}} -> !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf64>>>>
! CHECK: fir.embox %{{.*}} {allocator_idx = 2 : i32}
! CHECK: cuf.allocate %{{.*}} : !fir.ref<!fir.box<!fir.heap<!fir.array<?x?xf64>>>> {data_attr = #cuf.cuda<device>} -> i32