brintos

brintos / llvm-project-archived public Read only

0
0
Text · 26.1 KiB · 0159474 Raw
562 lines · plain
1! RUN: bbc -emit-hlfir -fopenacc -fcuda %s -o - | FileCheck %s2 3! Test CUDA Fortran data transfer using assignment statements.4 5module mod16  type :: t17    integer :: i8  end type9 10  type :: t211    integer, device, allocatable, dimension(:) :: x12  end type13 14  integer, device, dimension(11:20) :: cdev15 16  real(kind=8), device, allocatable, dimension(:) :: p17 18  interface19    function __sum(a_d) result(res_h)20      integer(4), managed, intent(in) :: a_d(:,:,:,:)21      integer(4), allocatable, managed :: res_h(:,:,:)22    end function23  end interface24 25contains26  function dev1(a)27    integer, device :: a(:)28    integer :: dev129    dev1 = 130  end function31end32 33subroutine sub1()34  use mod135  integer, device :: m36  integer, device :: adev(10)37  integer :: i, ahost(10), bhost(10)38 39  m = 1 + i40 41  m = 142 43  adev = ahost44 45  adev = ahost + 146 47  adev(1:5) = ahost(1:5)48 49  adev = ahost + bhost50 51  adev = 1052 53  cdev = 054end55 56! CHECK-LABEL: func.func @_QPsub1()57 58! CHECK: %[[ADEV:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) {data_attr = #cuf.cuda<device>, uniq_name = "_QFsub1Eadev"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)59! CHECK: %[[AHOST:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) {uniq_name = "_QFsub1Eahost"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)60! CHECK: %[[I:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsub1Ei"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)61! CHECK: %[[M:.*]]:2 = hlfir.declare %{{.*}} {data_attr = #cuf.cuda<device>, uniq_name = "_QFsub1Em"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)62 63! CHECK: %[[C1:.*]] = arith.constant 1 : i3264! CHECK: %[[LOADED_I:.*]] = fir.load %[[I]]#0 : !fir.ref<i32>65! CHECK: %[[ADD:.*]] = arith.addi %[[C1]], %[[LOADED_I]] : i3266! CHECK: %[[ASSOC:.*]]:3 = hlfir.associate %[[ADD]] {uniq_name = ".cuf_host_tmp"} : (i32) -> (!fir.ref<i32>, !fir.ref<i32>, i1)67! CHECK: cuf.data_transfer %[[ASSOC]]#0 to %[[M]]#0 {transfer_kind = #cuf.cuda_transfer<host_device>} : !fir.ref<i32>, !fir.ref<i32>68! CHECK: hlfir.end_associate %[[ASSOC]]#1, %[[ASSOC]]#2 : !fir.ref<i32>, i169 70! CHECK: cuf.data_transfer %c1{{.*}} to %[[M]]#0 {transfer_kind = #cuf.cuda_transfer<host_device>} : i32, !fir.ref<i32>71 72! CHECK: cuf.data_transfer %[[AHOST]]#0 to %[[ADEV]]#0 {transfer_kind = #cuf.cuda_transfer<host_device>} : !fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>73 74! CHECK: %[[ELEMENTAL:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<10xi32> {75! CHECK: %[[ASSOC:.*]]:3 = hlfir.associate %[[ELEMENTAL]](%{{.*}}) {uniq_name = ".cuf_host_tmp"} : (!hlfir.expr<10xi32>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>, i1)76! CHECK: cuf.data_transfer %[[ASSOC]]#0 to %[[ADEV]]#0 {transfer_kind = #cuf.cuda_transfer<host_device>} : !fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>77! CHECK: hlfir.end_associate %[[ASSOC]]#1, %[[ASSOC]]#2 : !fir.ref<!fir.array<10xi32>>, i178 79! CHECK: %[[DES_AHOST:.*]] = hlfir.designate %[[AHOST]]#0 (%c1{{.*}}:%c5{{.*}}:%c1{{.*}})  shape %{{.*}} : (!fir.ref<!fir.array<10xi32>>, index, index, index, !fir.shape<1>) -> !fir.ref<!fir.array<5xi32>>80! CHECK: %[[DES_ADEV:.*]] = hlfir.designate %[[ADEV]]#0 (%c1{{.*}}:%c5{{.*}}:%c1{{.*}})  shape %{{.*}} : (!fir.ref<!fir.array<10xi32>>, index, index, index, !fir.shape<1>) -> !fir.ref<!fir.array<5xi32>>81! CHECK: cuf.data_transfer %[[DES_AHOST]] to %[[DES_ADEV]] {transfer_kind = #cuf.cuda_transfer<host_device>} : !fir.ref<!fir.array<5xi32>>, !fir.ref<!fir.array<5xi32>>82 83! CHECK: %[[ELEMENTAL:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<10xi32>84! CHECK: %[[ASSOC:.*]]:3 = hlfir.associate %[[ELEMENTAL]](%{{.*}}) {uniq_name = ".cuf_host_tmp"} : (!hlfir.expr<10xi32>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>, i1)85! CHECK: cuf.data_transfer %[[ASSOC]]#0 to %[[ADEV]]#0 {transfer_kind = #cuf.cuda_transfer<host_device>} : !fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>86! CHECK: hlfir.end_associate %[[ASSOC]]#1, %[[ASSOC]]#2 : !fir.ref<!fir.array<10xi32>>, i187 88! CHECK: cuf.data_transfer %c10{{.*}} to %[[ADEV]]#0 {transfer_kind = #cuf.cuda_transfer<host_device>} : i32, !fir.ref<!fir.array<10xi32>>89 90! CHECK: cuf.data_transfer %c0{{.*}} to %{{.*}}#1, %{{.*}} : !fir.shapeshift<1> {transfer_kind = #cuf.cuda_transfer<host_device>} : i32, !fir.ref<!fir.array<10xi32>>91 92subroutine sub2()93  integer, device :: m94  integer, device :: adev(10), bdev(10)95  integer :: i, ahost(10), bhost(10)96 97  ahost = adev98 99  i = m100 101  ahost(1:5) = adev(1:5)102 103  bdev = adev104 105  ! Implicit data transfer of adev before evaluation.106  bhost = ahost + adev107 108end109 110! CHECK-LABEL: func.func @_QPsub2()111! CHECK: %[[ADEV:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) {data_attr = #cuf.cuda<device>, uniq_name = "_QFsub2Eadev"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)112! CHECK: %[[AHOST:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) {uniq_name = "_QFsub2Eahost"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)113! CHECK: %[[BDEV:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) {data_attr = #cuf.cuda<device>, uniq_name = "_QFsub2Ebdev"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)114! CHECK: %[[BHOST:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) {uniq_name = "_QFsub2Ebhost"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)115! CHECK: %[[I:.*]]:2 = hlfir.declare %{{.*}} {uniq_name = "_QFsub2Ei"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)116! CHECK: %[[M:.*]]:2 = hlfir.declare %{{.*}} {data_attr = #cuf.cuda<device>, uniq_name = "_QFsub2Em"} : (!fir.ref<i32>) -> (!fir.ref<i32>, !fir.ref<i32>)117! CHECK: cuf.data_transfer %[[ADEV]]#0 to %[[AHOST]]#0 {transfer_kind = #cuf.cuda_transfer<device_host>} : !fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>118! CHECK: cuf.data_transfer %[[M]]#0 to %[[I]]#0 {transfer_kind = #cuf.cuda_transfer<device_host>} : !fir.ref<i32>, !fir.ref<i32>119 120! CHECK: %[[DES_ADEV:.*]] = hlfir.designate %[[ADEV]]#0 (%{{.*}}:%{{.*}}:%{{.*}})  shape %{{.*}} : (!fir.ref<!fir.array<10xi32>>, index, index, index, !fir.shape<1>) -> !fir.ref<!fir.array<5xi32>>121! CHECK: %[[DES_AHOST:.*]] = hlfir.designate %[[AHOST]]#0 (%{{.*}}:%{{.*}}:%{{.*}})  shape %{{.*}} : (!fir.ref<!fir.array<10xi32>>, index, index, index, !fir.shape<1>) -> !fir.ref<!fir.array<5xi32>>122! CHECK: cuf.data_transfer %[[DES_ADEV]] to %[[DES_AHOST]] {transfer_kind = #cuf.cuda_transfer<device_host>} : !fir.ref<!fir.array<5xi32>>, !fir.ref<!fir.array<5xi32>>123 124! CHECK: cuf.data_transfer %[[ADEV]]#0 to %[[BDEV]]#0 {transfer_kind = #cuf.cuda_transfer<device_device>} : !fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>125 126! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array<10xi32> {bindc_name = ".tmp", uniq_name = ""}127! CHECK: %[[DECL_TEMP:.*]]:2 = hlfir.declare %[[TEMP]](%{{.*}}) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.heap<!fir.array<10xi32>>, !fir.heap<!fir.array<10xi32>>)128! CHECK: %[[ADEV_TEMP:.*]]:2 = hlfir.declare %[[DECL_TEMP]]#0(%{{.*}}) {data_attr = #cuf.cuda<device>, uniq_name = "_QFsub2Eadev"} : (!fir.heap<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.heap<!fir.array<10xi32>>, !fir.heap<!fir.array<10xi32>>)129! CHECK: cuf.data_transfer %[[ADEV]]#0 to %[[DECL_TEMP]]#0 {transfer_kind = #cuf.cuda_transfer<device_host>} : !fir.ref<!fir.array<10xi32>>, !fir.heap<!fir.array<10xi32>>130! CHECK: %[[ELEMENTAL:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<1>) -> !hlfir.expr<10xi32>131! CHECK: hlfir.assign %[[ELEMENTAL]] to %[[BHOST]]#0 : !hlfir.expr<10xi32>, !fir.ref<!fir.array<10xi32>>132! CHECK: fir.freemem %[[TEMP]] : !fir.heap<!fir.array<10xi32>>133 134subroutine sub3()135  use mod1136  type(t1), device :: t137  integer :: ahost(10), bhost(10)138 139  bhost = ahost + t%i140end141 142! CHECK-LABEL: func.func @_QPsub3()143! CHECK: %[[TMP:.*]] = fir.alloca !fir.type<_QMmod1Tt1{i:i32}> {bindc_name = ".tmp"}144! CHECK: %[[AHOST:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) {uniq_name = "_QFsub3Eahost"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)145! CHECK: %[[BHOST:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) {uniq_name = "_QFsub3Ebhost"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)146! CHECK: %[[T:.*]]:2 = hlfir.declare %{{.*}} {data_attr = #cuf.cuda<device>, uniq_name = "_QFsub3Et"} : (!fir.ref<!fir.type<_QMmod1Tt1{i:i32}>>) -> (!fir.ref<!fir.type<_QMmod1Tt1{i:i32}>>, !fir.ref<!fir.type<_QMmod1Tt1{i:i32}>>)147! CHECK: %[[TMP_DECL:.*]]:2 = hlfir.declare %0 {uniq_name = ".tmp"} : (!fir.ref<!fir.type<_QMmod1Tt1{i:i32}>>) -> (!fir.ref<!fir.type<_QMmod1Tt1{i:i32}>>, !fir.ref<!fir.type<_QMmod1Tt1{i:i32}>>)148! CHECK: cuf.data_transfer %[[T]]#0 to %[[TMP_DECL]]#0 {transfer_kind = #cuf.cuda_transfer<device_host>} : !fir.ref<!fir.type<_QMmod1Tt1{i:i32}>>, !fir.ref<!fir.type<_QMmod1Tt1{i:i32}>>149 150 151! Check that cuf.data_transfer are not generated within cuf kernel152subroutine sub4()153  integer, parameter :: n = 10154  real, device :: adev(n)155  real :: ahost(n)156  real, managed :: b157  integer :: i158 159  adev = ahost160  !$cuf kernel do <<<*,*>>>161  do i = 1, n162    adev(i) = adev(i) + b163  enddo164end subroutine165 166! CHECK-LABEL: func.func @_QPsub4()167! CHECK: cuf.data_transfer168! CHECK: cuf.kernel<<<*, *>>>169! CHECK-NOT: cuf.data_transfer170! CHECK: hlfir.assign171 172attributes(global) subroutine sub5(a)173  integer, device :: a174  integer :: i175  a = i176end subroutine177 178! CHECK-LABEL: func.func @_QPsub5179! CHECK-NOT: cuf.data_transfer180 181attributes(host,device) subroutine sub6(a)182  integer, device :: a183  integer :: i184  a = i185end subroutine186 187! CHECK-LABEL: func.func @_QPsub6188! CHECK: cuf.data_transfer189 190subroutine sub7(a, b, c)191  integer, device, allocatable :: a(:), c(:)192  integer, allocatable :: b(:)193  b = a194 195  a = b196 197  c = a198end subroutine199 200! CHECK-LABEL: func.func @_QPsub7(201! CHECK-SAME:  %[[ARG0:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {cuf.data_attr = #cuf.cuda<device>, fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {fir.bindc_name = "b"}, %[[ARG2:.*]]: !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>> {cuf.data_attr = #cuf.cuda<device>, fir.bindc_name = "c"}) {202! CHECK: %[[A:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %{{.*}} arg {{[0-9]+}} {data_attr = #cuf.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub7Ea"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)203! CHECK: %[[B:.*]]:2 = hlfir.declare %[[ARG1]] dummy_scope %{{.*}} arg {{[0-9]+}} {fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub7Eb"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)204! CHECK: %[[C:.*]]:2 = hlfir.declare %[[ARG2]] dummy_scope %0 arg {{[0-9]+}} {data_attr = #cuf.cuda<device>, fortran_attrs = #fir.var_attrs<allocatable>, uniq_name = "_QFsub7Ec"} : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.dscope) -> (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>)205! CHECK: cuf.data_transfer %[[A]]#0 to %[[B]]#0 {transfer_kind = #cuf.cuda_transfer<device_host>} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>206! CHECK: cuf.data_transfer %[[B]]#0 to %[[A]]#0 {transfer_kind = #cuf.cuda_transfer<host_device>} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>207! CHECK: cuf.data_transfer %[[A]]#0 to %[[C]]#0 {transfer_kind = #cuf.cuda_transfer<device_device>} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>, !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>208 209subroutine sub8(a, b, n)210  integer :: n211  integer, device :: a(n)212  integer :: b(10)213  b = a214  a = b215end subroutine216 217! CHECK-LABEL: func.func @_QPsub8(218! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xi32>> {cuf.data_attr = #cuf.cuda<device>, fir.bindc_name = "a"}, %[[ARG1:.*]]: !fir.ref<!fir.array<10xi32>> {fir.bindc_name = "b"}, %[[ARG2:.*]]: !fir.ref<i32> {fir.bindc_name = "n"})219! CHECK: %[[B:.*]]:2 = hlfir.declare %[[ARG1]](%{{.*}}) dummy_scope %{{.*}} {{.*}} {uniq_name = "_QFsub8Eb"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>, !fir.dscope) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)220! CHECK: %[[A:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) dummy_scope %{{.*}} {{.*}} {data_attr = #cuf.cuda<device>, uniq_name = "_QFsub8Ea"} : (!fir.ref<!fir.array<?xi32>>, !fir.shape<1>, !fir.dscope) -> (!fir.box<!fir.array<?xi32>>, !fir.ref<!fir.array<?xi32>>)221! CHECK: cuf.data_transfer %[[A]]#1 to %[[B]]#0, %{{.*}} : !fir.shape<1> {transfer_kind = #cuf.cuda_transfer<device_host>} : !fir.ref<!fir.array<?xi32>>, !fir.ref<!fir.array<10xi32>>222! CHECK: cuf.data_transfer %[[B]]#0 to %[[A]]#1, %{{.*}} : !fir.shape<1> {transfer_kind = #cuf.cuda_transfer<host_device>} : !fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<?xi32>>223 224subroutine sub9(a)225  integer, pinned, allocatable :: a(:)226  do concurrent (i = 1 : 10)227    a(i) = 10 + a(i)228  end do229end subroutine230 231! CHECK-LABEL: func.func @_QPsub9232! CHECK-NOT: cuf.data_transfer233 234subroutine sub10(a, b)235  integer, device :: a236  integer, allocatable, pinned :: b237  integer :: res238 239  res = a + b240end subroutine241 242! CHECK-LABEL: func.func @_QPsub10(243! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<i32> {cuf.data_attr = #cuf.cuda<device>, fir.bindc_name = "a"}244 245! CHECK: %[[A:.*]]:2 = hlfir.declare %[[ARG0]] dummy_scope %1 {{.*}} {data_attr = #cuf.cuda<device>, uniq_name = "_QFsub10Ea"} : (!fir.ref<i32>, !fir.dscope) -> (!fir.ref<i32>, !fir.ref<i32>)246! CHECK: cuf.data_transfer %[[A]]#0 to %{{.*}}#0 {transfer_kind = #cuf.cuda_transfer<device_host>} : !fir.ref<i32>, !fir.ref<i32>247! CHECK-NOT: cuf.data_transfer248 249subroutine sub11(n)250  integer :: n251  real, dimension(10) :: h252  real, dimension(n), device :: d253  do i=1,10254    h(i) = d(i)255  end do256end subroutine257 258! CHECK-LABEL: func.func @_QPsub11259! CHECK: %[[RHS:.*]] = hlfir.designate %{{.*}} (%{{.*}})  : (!fir.box<!fir.array<?xf32>>, i64) -> !fir.ref<f32>260! CHECK: %[[LHS:.*]] = hlfir.designate %{{.*}} (%{{.*}})  : (!fir.ref<!fir.array<10xf32>>, i64) -> !fir.ref<f32>261! CHECK: cuf.data_transfer %[[RHS]] to %[[LHS]] {transfer_kind = #cuf.cuda_transfer<device_host>} : !fir.ref<f32>, !fir.ref<f32>262 263subroutine sub12()264  use mod1265  integer, device :: a(10)266  integer :: x267  x = dev1(a)268end subroutine269 270! CHECK-LABEL: func.func @_QPsub12271! CHECK: %{{.*}} = fir.call @_QMmod1Pdev1272! CHECK: hlfir.assign273! CHECK-NOT: cuf.data_transfer274 275subroutine sub13(a, b, n)276  integer :: n277  integer :: a(n)278  integer, allocatable, device :: b(:)279  integer :: res(10)280 281  res = a + b282end subroutine283 284! CHECK-LABEL: func.func @_QPsub13285! CHECK: %[[TEMP:.*]] = fir.allocmem !fir.array<?xi32>, %14#1 {bindc_name = ".tmp", uniq_name = ""}286! CHECK: cuf.data_transfer287! CHECK: fir.freemem %[[TEMP]] : !fir.heap<!fir.array<?xi32>>288 289subroutine sub14()290  logical(4), device :: log(10)291  log = .true.292end subroutine293 294! CHECK-LABEL: func.func @_QPsub14()295! CHECK: %[[TRUE:.*]] = arith.constant true296! CHECK: cuf.data_transfer %[[TRUE]] to %{{.*}}#0 {transfer_kind = #cuf.cuda_transfer<host_device>} : i1, !fir.ref<!fir.array<10x!fir.logical<4>>>297 298subroutine sub15(a_dev, a_host, n, m)299  integer, intent(in) :: n, m300  real, device :: a_dev(n*m)301  real :: a_host(n*m)302 303  a_dev = a_host304end subroutine305 306! CHECK-LABEL: func.func @_QPsub15(307! CHECK-SAME: %[[ARG0:.*]]: !fir.ref<!fir.array<?xf32>> {cuf.data_attr = #cuf.cuda<device>, fir.bindc_name = "a_dev"}, %[[ARG1:.*]]: !fir.ref<!fir.array<?xf32>> {fir.bindc_name = "a_host"}308! CHECK: %[[ADEV:.*]]:2 = hlfir.declare %[[ARG0]](%{{.*}}) dummy_scope %{{.*}} {{.*}} {data_attr = #cuf.cuda<device>, uniq_name = "_QFsub15Ea_dev"} : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>, !fir.dscope) -> (!fir.box<!fir.array<?xf32>>, !fir.ref<!fir.array<?xf32>>)309! CHECK: %[[SHAPE:.*]] = fir.shape %{{.*}} : (index) -> !fir.shape<1>310! CHECK: %[[AHOST:.*]]:2 = hlfir.declare %[[ARG1]](%{{.*}}) dummy_scope %{{.*}} {{.*}} {uniq_name = "_QFsub15Ea_host"} : (!fir.ref<!fir.array<?xf32>>, !fir.shape<1>, !fir.dscope) -> (!fir.box<!fir.array<?xf32>>, !fir.ref<!fir.array<?xf32>>)311! CHECK: cuf.data_transfer %[[AHOST]]#1 to %[[ADEV]]#1, %[[SHAPE]] : !fir.shape<1> {transfer_kind = #cuf.cuda_transfer<host_device>} : !fir.ref<!fir.array<?xf32>>, !fir.ref<!fir.array<?xf32>>312 313! Check that cuf.data_transfer are not generated within OpenACC region314subroutine sub16()315  integer, parameter :: n = 10316  real, device :: adev(n)317  real :: ahost(n)318  real, managed :: b319  integer :: i320 321  adev = ahost322  !$acc parallel loop deviceptr(adev) 323  do i = 1, n324    adev(i) = adev(i) + b325  enddo326 327  !$acc kernels deviceptr(adev) 328  do i = 1, n329    adev(i) = adev(i) + b330  enddo331  !$acc end kernels332 333 334  !$acc serial deviceptr(adev) 335  do i = 1, n336    adev(i) = adev(i) + b337  enddo338  !$acc end serial339end subroutine340 341! CHECK-LABEL: func.func @_QPsub16()342! CHECK: cuf.data_transfer343! CHECK: acc.parallel344! CHECK-NOT: cuf.data_transfer345! CHECK: hlfir.assign346 347! CHECK: acc.kernels348! CHECK-NOT: cuf.data_transfer349! CHECK: hlfir.assign350 351! CHECK: acc.serial352! CHECK-NOT: cuf.data_transfer353! CHECK: hlfir.assign354 355! Check that cuf.data_transfer are not generated within cuf kernel and do not356! trigger semantic error.357subroutine sub17()358  integer, parameter :: n = 10359  real, device :: adev(n)360  real, device :: bdev(n)361  real :: ahost362  real, managed :: b363  integer :: i364 365  adev = ahost366  !$cuf kernel do <<<*,*>>>367  do i = 1, n368    ahost = adev(i) * bdev(i) + b369  enddo370end subroutine371 372! CHECK-LABEL: func.func @_QPsub17()373! CHECK: cuf.kernel<<<*, *>>>374! CHECK-NOT: cuf.data_transfer375 376subroutine sub18(o)377  integer, device, optional, allocatable :: o(:)378  integer, device, allocatable :: a(:)379  integer, device, pointer :: p(:)380  integer :: b381  integer :: s(1)382  logical :: l383 384  b = size(a)385  b = lbound(a, dim=1)386  b = ubound(a, dim=1)387  s = shape(a)388  l = allocated(a)389  l = associated(p)390  b = kind(a)391  l = present(o)392end subroutine393 394! CHECK-LABEL: func.func @_QPsub18395! CHECK-NOT: cuf.data_transfer396 397subroutine sub19()398  integer, device :: adev(10)399  integer :: ahost(10)400  ! Implicit data transfer of adev and then addition on the host401  ahost = adev + 2402end subroutine403 404! CHECK-LABEL: func.func @_QPsub19()405! CHECK: %[[ADEV_DECL:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) {data_attr = #cuf.cuda<device>, uniq_name = "_QFsub19Eadev"} : (!fir.ref<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xi32>>, !fir.ref<!fir.array<10xi32>>)406! CHECK: %[[ALLOC_TMP:.*]] = fir.allocmem !fir.array<10xi32> {bindc_name = ".tmp", uniq_name = ""}407! CHECK: %[[TMP:.*]]:2 = hlfir.declare %[[ALLOC_TMP]](%{{.*}}) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<10xi32>>, !fir.shape<1>) -> (!fir.heap<!fir.array<10xi32>>, !fir.heap<!fir.array<10xi32>>)408! CHECK: cuf.data_transfer %[[ADEV_DECL]]#0 to %[[TMP]]#0 {transfer_kind = #cuf.cuda_transfer<device_host>} : !fir.ref<!fir.array<10xi32>>, !fir.heap<!fir.array<10xi32>>409! CHECK: hlfir.assign 410 411subroutine sub20()412  integer, managed :: a(10)413  a = a + 2 ! ok. No data transfer. Assignment on the host.414end subroutine415 416! CHECK-LABEL: func.func @_QPsub20()417! CHECK-NOT: cuf.data_transfer418! CHECK: hlfir.assign419 420subroutine sub21()421  real, allocatable,device:: a(:,:), b(:,:)422  real:: s423  integer:: i,j,N=16424  allocate(a(N,N),b(N,N))425  do concurrent(i=1:N, j=1:N) reduce(+:s)426    b(i,j)=a(i,j)**2427    s=s+b(i,j)428  end do429end subroutine430 431! CHECK-LABEL: func.func @_QPsub21()432! CHECK: fir.do_concurrent.loop433! CHECK-NOT: cuf.data_transfer434! CHECK: hlfir.assign435 436 437subroutine sub22()438  use mod1439  type(t2) :: a440  integer :: b(100)441  allocate(a%x(100))442 443  b = a%x444end subroutine445 446! CHECK-LABEL: func.func @_QPsub22()447! CHECK: cuf.data_transfer448 449subroutine sub23(n)450  integer :: n451  real(8), device :: d(n,n), x(n)452  x = sum(d,dim=2) ! Was triggering Unsupported CUDA data transfer453end subroutine454 455! CHECK-LABEL: func.func @_QPsub23456 457subroutine sub24()458  real, managed :: m459  real, device :: d(4)460  m = d(1)461end462 463! CHECK-LABEL: func.func @_QPsub24()464! CHECK: %[[D:.*]]:2 = hlfir.declare %1(%2) {data_attr = #cuf.cuda<device>, uniq_name = "_QFsub24Ed"} : (!fir.ref<!fir.array<4xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<4xf32>>, !fir.ref<!fir.array<4xf32>>)465! CHECK: %[[M:.*]]:2 = hlfir.declare %4 {data_attr = #cuf.cuda<managed>, uniq_name = "_QFsub24Em"} : (!fir.ref<f32>) -> (!fir.ref<f32>, !fir.ref<f32>)466! CHECK: %[[D1:.*]] = hlfir.designate %[[D]]#0 (%c1{{.*}})  : (!fir.ref<!fir.array<4xf32>>, index) -> !fir.ref<f32>467! CHECK: cuf.data_transfer %[[D1]] to %[[M]]#0 {transfer_kind = #cuf.cuda_transfer<device_device>} : !fir.ref<f32>, !fir.ref<f32>468 469subroutine sub25()470  use mod1471  integer :: i472  real(8) :: c473 474  do i = 1, 10475    c = c + p(i)476  end do477end478 479! CHECK-LABEL: func.func @_QPsub25()480! CHECK: fir.allocmem !fir.array<?xf64>, %15#1 {bindc_name = ".tmp", uniq_name = ""}481! CHECK: cuf.data_transfer %{{.*}} to %{{.*}} {transfer_kind = #cuf.cuda_transfer<device_host>} : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf64>>>>, !fir.box<!fir.array<?xf64>>482! CHECK: hlfir.assign %{{.*}} to %{{.*}} : f64, !fir.ref<f64>483! CHECK: fir.freemem %{{.*}} : !fir.heap<!fir.array<?xf64>>484 485subroutine sub26(i, j, k)486  integer :: i, j, k487  real(2), dimension(i,j,k), device :: d488  real(4), dimension(i,j,k) :: hd489 490  hd = d491end subroutine492 493! CHECK-LABEL: func.func @_QPsub26494! CHECK: %[[ALLOC_D:.*]] = cuf.alloc !fir.array<?x?x?xf16>, %{{.*}}, %{{.*}}, %{{.*}} : index, index, index {bindc_name = "d", data_attr = #cuf.cuda<device>, uniq_name = "_QFsub26Ed"} -> !fir.ref<!fir.array<?x?x?xf16>>495! CHECK: %[[D:.*]]:2 = hlfir.declare %[[ALLOC_D]](%{{.*}}) {data_attr = #cuf.cuda<device>, uniq_name = "_QFsub26Ed"} : (!fir.ref<!fir.array<?x?x?xf16>>, !fir.shape<3>) -> (!fir.box<!fir.array<?x?x?xf16>>, !fir.ref<!fir.array<?x?x?xf16>>)496! CHECK: %[[HD:.*]]:2 = hlfir.declare %{{.*}}(%{{.*}}) {uniq_name = "_QFsub26Ehd"} : (!fir.ref<!fir.array<?x?x?xf32>>, !fir.shape<3>) -> (!fir.box<!fir.array<?x?x?xf32>>, !fir.ref<!fir.array<?x?x?xf32>>)497! CHECK: %[[ALLOC:.*]] = fir.allocmem !fir.array<?x?x?xf16>, %8, %13, %18 {bindc_name = ".tmp", uniq_name = ""}498! CHECK: %[[TEMP:.*]]:2 = hlfir.declare %[[ALLOC]](%{{.*}}) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?x?x?xf16>>, !fir.shape<3>) -> (!fir.box<!fir.array<?x?x?xf16>>, !fir.heap<!fir.array<?x?x?xf16>>)499! CHECK: cuf.data_transfer %[[D]]#0 to %[[TEMP]]#0 {transfer_kind = #cuf.cuda_transfer<device_host>} : !fir.box<!fir.array<?x?x?xf16>>, !fir.box<!fir.array<?x?x?xf16>>500! CHECK: %[[ELE:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<3>) -> !hlfir.expr<?x?x?xf32> {501! CHECK: ^bb0(%{{.*}}: index, %{{.*}}: index, %{{.*}}: index):502! CHECK: %[[DESIGNATE:.*]] = hlfir.designate %[[TEMP]]#0 (%{{.*}}, %{{.*}}, %{{.*}})  : (!fir.box<!fir.array<?x?x?xf16>>, index, index, index) -> !fir.ref<f16>503! CHECK: %[[LOAD:.*]] = fir.load %[[DESIGNATE]] : !fir.ref<f16>504! CHECK: %[[CONV:.*]] = fir.convert %[[LOAD]] : (f16) -> f32505! CHECK: hlfir.yield_element %[[CONV]] : f32506! CHECK: }507! CHECK: hlfir.assign %[[ELE]] to %[[HD]]#0 : !hlfir.expr<?x?x?xf32>, !fir.box<!fir.array<?x?x?xf32>> 508 509subroutine sub27()510  real(2), dimension(10, 20, 30), device :: d511  real(4), dimension(10, 20, 30) :: hd512 513  hd = d514end subroutine515 516! CHECK-LABEL: func.func @_QPsub27()517! CHECK: %[[ALLOC_D:.*]] = cuf.alloc !fir.array<10x20x30xf16> {bindc_name = "d", data_attr = #cuf.cuda<device>, uniq_name = "_QFsub27Ed"} -> !fir.ref<!fir.array<10x20x30xf16>>518! CHECK: %[[D:.*]]:2 = hlfir.declare %[[ALLOC_D]](%{{.*}}) {data_attr = #cuf.cuda<device>, uniq_name = "_QFsub27Ed"} : (!fir.ref<!fir.array<10x20x30xf16>>, !fir.shape<3>) -> (!fir.ref<!fir.array<10x20x30xf16>>, !fir.ref<!fir.array<10x20x30xf16>>)519! CHECK: %[[ALLOC_HD:.*]] = fir.alloca !fir.array<10x20x30xf32> {bindc_name = "hd", uniq_name = "_QFsub27Ehd"}520! CHECK: %[[HD:.*]]:2 = hlfir.declare %[[ALLOC_HD]](%{{.*}}) {uniq_name = "_QFsub27Ehd"} : (!fir.ref<!fir.array<10x20x30xf32>>, !fir.shape<3>) -> (!fir.ref<!fir.array<10x20x30xf32>>, !fir.ref<!fir.array<10x20x30xf32>>)521! CHECK: %[[ALLOC_TEMP:.*]] = fir.allocmem !fir.array<10x20x30xf16> {bindc_name = ".tmp", uniq_name = ""}522! CHECK: %[[TEMP:.*]]:2 = hlfir.declare %[[ALLOC_TEMP]](%{{.*}}) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<10x20x30xf16>>, !fir.shape<3>) -> (!fir.heap<!fir.array<10x20x30xf16>>, !fir.heap<!fir.array<10x20x30xf16>>)523! CHECK: cuf.data_transfer %[[D]]#0 to %[[TEMP]]#0 {transfer_kind = #cuf.cuda_transfer<device_host>} : !fir.ref<!fir.array<10x20x30xf16>>, !fir.heap<!fir.array<10x20x30xf16>>524! CHECK: %[[ELE:.*]] = hlfir.elemental %{{.*}} unordered : (!fir.shape<3>) -> !hlfir.expr<10x20x30xf32> {525! CHECK: ^bb0(%{{.*}}: index, %{{.*}}: index, %{{.*}}: index):526! CHECK: %[[DESIGNATE:.*]] = hlfir.designate %[[TEMP]]#0 (%{{.*}}, %{{.*}}, %{{.*}})  : (!fir.heap<!fir.array<10x20x30xf16>>, index, index, index) -> !fir.ref<f16>527! CHECK: %[[LOAD:.*]] = fir.load %[[DESIGNATE]] : !fir.ref<f16>528! CHECK: %[[CONV:.*]] = fir.convert %[[LOAD]] : (f16) -> f32529! CHECK: hlfir.yield_element %[[CONV]] : f32530! CHECK: }531! CHECKL: hlfir.assign %[[ELE]] to %[[HD]]#0 : !hlfir.expr<10x20x30xf32>, !fir.ref<!fir.array<10x20x30xf32>>532 533subroutine sub28(N1,N2,N3,N4)534  use mod1535  integer(4), managed :: a(N1,N2,N3,N4) 536  integer(4), managed :: bres(N1,N2,N3)537  bres = __sum(a)538end subroutine539 540! CHECK-LABEL: func.func @_QPsub28541! CHECK: fir.call @_QP__sum542! CHECK-NOT: cuf.data_transfer543! CHECK: hlfir.assign544! CHECK-NOT: cuf.data_transfer545 546! Data transfer with conversion with more complex elemental547! Check that the data transfer is placed before the elemental op.548subroutine sub29()549  real(2), device, allocatable :: a(:)550  real(4), allocatable :: ha(:)551  allocate(a(10))552  allocate(ha(10))553  ha = a554  deallocate(a)555end subroutine556 557! CHECK-LABEL:  func.func @_QPsub29()558! CHECK: %[[TMP:.*]] = fir.allocmem !fir.array<?xf16>, %24#1 {bindc_name = ".tmp", uniq_name = ""}559! CHECK: %[[TMP_BUFFER:.*]]:2 = hlfir.declare %[[TMP]](%{{.*}}) {uniq_name = ".tmp"} : (!fir.heap<!fir.array<?xf16>>, !fir.shape<1>) -> (!fir.box<!fir.array<?xf16>>, !fir.heap<!fir.array<?xf16>>)560! CHECK: cuf.data_transfer %{{.*}} to %[[TMP_BUFFER]]#0 {transfer_kind = #cuf.cuda_transfer<device_host>} : !fir.box<!fir.heap<!fir.array<?xf16>>>, !fir.box<!fir.array<?xf16>>561! CHECK: hlfir.elemental 562