// RUN: fir-opt --split-input-file --cuf-convert --cuf-convert-late %s | FileCheck %s module attributes {gpu.container_module, dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry, dense<64> : vector<4xi64>>, #dlti.dl_entry, dense<32> : vector<4xi64>>, #dlti.dl_entry, dense<32> : vector<4xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<4xi64>>, #dlti.dl_entry<"dlti.endianness", "little">, #dlti.dl_entry<"dlti.stack_alignment", 128 : i64>>} { gpu.module @cuda_device_mod { gpu.func @_QPsub_device1() kernel { cf.br ^bb1 ^bb1: // pred: ^bb0 gpu.return } gpu.func @_QPsub_device2(%arg0: !fir.ref) kernel { cf.br ^bb1(%arg0 : !fir.ref) ^bb1(%0: !fir.ref): // pred: ^bb0 %1 = fir.declare %0 {uniq_name = "_QFsub1Ei"} : (!fir.ref) -> !fir.ref %cst = arith.constant 2.000000e+00 : f32 fir.store %cst to %1 : !fir.ref gpu.return } } func.func @_QQmain() attributes {fir.bindc_name = "main"} { %0 = fir.alloca f32 // CHECK: %[[ALLOCA:.*]] = fir.alloca f32 %c1 = arith.constant 1 : index %c11_i32 = arith.constant 11 : i32 %c1024_i32 = arith.constant 1024 : i32 %c6_i32 = arith.constant 6 : i32 %c1_i32 = arith.constant 1 : i32 // CHECK: gpu.launch_func @cuda_device_mod::@_QPsub_device1 blocks in (%{{.*}}, %{{.*}}, %{{.*}}) threads in (%{{.*}}, %{{.*}}, %{{.*}}) dynamic_shared_memory_size %c0{{.*}} {cuf.proc_attr = #cuf.cuda_proc} cuf.kernel_launch @cuda_device_mod::@_QPsub_device1<<<%c1_i32, %c1_i32, %c1_i32, %c1_i32, %c1_i32, %c1_i32>>>() // CHECK: gpu.launch_func @cuda_device_mod::@_QPsub_device1 blocks in (%{{.*}}, %{{.*}}, %{{.*}}) threads in (%{{.*}}, %{{.*}}, %{{.*}}) dynamic_shared_memory_size %c1024{{.*}} {cuf.proc_attr = #cuf.cuda_proc} cuf.kernel_launch @cuda_device_mod::@_QPsub_device1<<<%c1_i32, %c1_i32, %c1_i32, %c1_i32, %c1_i32, %c1_i32, %c1024_i32>>>() // CHECK: gpu.launch_func @cuda_device_mod::@_QPsub_device2 blocks in (%{{.*}}, %{{.*}}, %{{.*}}) threads in (%{{.*}}, %{{.*}}, %{{.*}}) dynamic_shared_memory_size %c0{{.*}} args(%[[ALLOCA]] : !fir.ref) {cuf.proc_attr = #cuf.cuda_proc} cuf.kernel_launch @cuda_device_mod::@_QPsub_device2<<<%c1_i32, %c1_i32, %c1_i32, %c1_i32, %c1_i32, %c1_i32>>>(%0) : (!fir.ref) return } } // ----- module attributes {gpu.container_module, dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry, dense<64> : vector<4xi64>>, #dlti.dl_entry, dense<32> : vector<4xi64>>, #dlti.dl_entry, dense<32> : vector<4xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<4xi64>>, #dlti.dl_entry<"dlti.endianness", "little">, #dlti.dl_entry<"dlti.stack_alignment", 128 : i64>>} { gpu.module @cuda_device_mod { gpu.func @_QMmod1Psub1(%arg0: !fir.ref>) kernel { gpu.return } } func.func @_QMmod1Psub1(%arg0: !fir.ref> {cuf.data_attr = #cuf.cuda, fir.bindc_name = "adev"}) attributes {cuf.cluster_dims = #cuf.cluster_dims, cuf.proc_attr = #cuf.cuda_proc} { return } func.func @_QMmod1Phost_sub() { %c10 = arith.constant 10 : index %0 = cuf.alloc !fir.array<10xi32> {bindc_name = "adev", data_attr = #cuf.cuda, uniq_name = "_QMmod1Fhost_subEadev"} -> !fir.ref> %1 = fir.shape %c10 : (index) -> !fir.shape<1> %2:2 = hlfir.declare %0(%1) {data_attr = #cuf.cuda, uniq_name = "_QMmod1Fhost_subEadev"} : (!fir.ref>, !fir.shape<1>) -> (!fir.ref>, !fir.ref>) %c1_i32 = arith.constant 1 : i32 %c10_i32 = arith.constant 10 : i32 cuf.kernel_launch @_QMmod1Psub1<<<%c1_i32, %c1_i32, %c1_i32, %c10_i32, %c1_i32, %c1_i32>>>(%2#1) : (!fir.ref>) return } } // CHECK-LABEL: func.func @_QMmod1Phost_sub() // CHECK: gpu.launch_func @cuda_device_mod::@_QMmod1Psub1 clusters in (%c2{{.*}}, %c2{{.*}}, %c1{{.*}}) {cuf.proc_attr = #cuf.cuda_proc} // ----- module attributes {gpu.container_module, dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry, dense<64> : vector<4xi64>>, #dlti.dl_entry, dense<32> : vector<4xi64>>, #dlti.dl_entry, dense<32> : vector<4xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<4xi64>>, #dlti.dl_entry<"dlti.endianness", "little">, #dlti.dl_entry<"dlti.stack_alignment", 128 : i64>>} { gpu.module @cuda_device_mod { gpu.func @_QMdevptrPtest(%arg0: !fir.ref>>>) kernel { gpu.return } } fir.global @_QMdevptrEdev_ptr {data_attr = #cuf.cuda} : !fir.box>> { %c0 = arith.constant 0 : index %0 = fir.zero_bits !fir.ptr> %1 = fir.shape %c0 : (index) -> !fir.shape<1> %2 = fir.embox %0(%1) {allocator_idx = 2 : i32} : (!fir.ptr>, !fir.shape<1>) -> !fir.box>> fir.has_value %2 : !fir.box>> } func.func @_QMdevptrPtest(%arg0: !fir.ref>>> {cuf.data_attr = #cuf.cuda, fir.bindc_name = "dp"}) attributes {cuf.proc_attr = #cuf.cuda_proc} { return } func.func @_QQmain() { %c1_i32 = arith.constant 1 : i32 %c4 = arith.constant 4 : index %0 = cuf.alloc !fir.array<4xf32> {bindc_name = "a_dev", data_attr = #cuf.cuda, uniq_name = "_QFEa_dev"} -> !fir.ref> %1 = fir.shape %c4 : (index) -> !fir.shape<1> %2 = fir.declare %0(%1) {data_attr = #cuf.cuda, fortran_attrs = #fir.var_attrs, uniq_name = "_QFEa_dev"} : (!fir.ref>, !fir.shape<1>) -> !fir.ref> %3 = fir.address_of(@_QMdevptrEdev_ptr) : !fir.ref>>> %4 = fir.declare %3 {data_attr = #cuf.cuda, fortran_attrs = #fir.var_attrs, uniq_name = "_QMdevptrEdev_ptr"} : (!fir.ref>>>) -> !fir.ref>>> %5 = fir.embox %2(%1) : (!fir.ref>, !fir.shape<1>) -> !fir.box>> fir.store %5 to %4 : !fir.ref>>> cuf.sync_descriptor @_QMdevptrEdev_ptr cuf.kernel_launch @_QMdevptrPtest<<<%c1_i32, %c1_i32, %c1_i32, %c1_i32, %c1_i32, %c1_i32>>>(%4) : (!fir.ref>>>) cuf.free %2 : !fir.ref> {data_attr = #cuf.cuda} return } } // CHECK-LABEL: func.func @_QQmain() // CHECK: _FortranACUFSyncGlobalDescriptor // CHECK: %[[ADDROF:.*]] = fir.address_of(@_QMdevptrEdev_ptr) : !fir.ref>>> // CHECK: %[[CONV_ADDR:.*]] = fir.convert %[[ADDROF]] : (!fir.ref>>>) -> !fir.llvm_ptr // CHECK: %[[DEVADDR:.*]] = fir.call @_FortranACUFGetDeviceAddress(%[[CONV_ADDR]], %{{.*}}, %{{.*}}) : (!fir.llvm_ptr, !fir.ref, i32) -> !fir.llvm_ptr // CHECK: %[[CONV_DEVADDR:.*]] = fir.convert %[[DEVADDR]] : (!fir.llvm_ptr) -> !fir.ref>>> // CHECK: gpu.launch_func @cuda_device_mod::@_QMdevptrPtest blocks in (%{{.*}}, %{{.*}}, %{{.*}}) threads in (%{{.*}}, %{{.*}}, %{{.*}}) dynamic_shared_memory_size %{{.*}} args(%[[CONV_DEVADDR]] : !fir.ref>>>) {cuf.proc_attr = #cuf.cuda_proc} // ----- module attributes {gpu.container_module, dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry, dense<64> : vector<4xi64>>, #dlti.dl_entry, dense<32> : vector<4xi64>>, #dlti.dl_entry, dense<32> : vector<4xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<4xi64>>, #dlti.dl_entry<"dlti.endianness", "little">, #dlti.dl_entry<"dlti.stack_alignment", 128 : i64>>} { gpu.module @cuda_device_mod { gpu.func @_QMdevptrPtest() kernel { gpu.return } } func.func @_QMdevptrPtest() attributes {cuf.proc_attr = #cuf.cuda_proc} { return } func.func @_QQmain() { %c1_i32 = arith.constant 1 : i32 cuf.kernel_launch @_QMdevptrPtest<<<%c1_i32, %c1_i32, %c1_i32, %c1_i32, %c1_i32, %c1_i32>>>() return } } // CHECK-LABEL: func.func @_QQmain() // CHECK: gpu.launch_func @cuda_device_mod::@_QMdevptrPtest blocks in (%{{.*}}, %{{.*}}, %{{.*}}) threads in (%{{.*}}, %{{.*}}, %{{.*}}) dynamic_shared_memory_size %{{.*}} {cuf.proc_attr = #cuf.cuda_proc} // ----- module attributes {gpu.container_module, dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry, dense<64> : vector<4xi64>>, #dlti.dl_entry, dense<32> : vector<4xi64>>, #dlti.dl_entry, dense<32> : vector<4xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<2xi64>>, #dlti.dl_entry : vector<4xi64>>, #dlti.dl_entry<"dlti.endianness", "little">, #dlti.dl_entry<"dlti.stack_alignment", 128 : i64>>} { gpu.module @cuda_device_mod { gpu.func @_QMdevptrPtest() kernel { gpu.return } } func.func @_QMdevptrPtest() attributes {cuf.proc_attr = #cuf.cuda_proc} { return } func.func @_QQmain() { %0 = fir.alloca i64 {bindc_name = "stream", uniq_name = "_QMtest_callFhostEstream"} %1:2 = hlfir.declare %0 {uniq_name = "_QMtest_callFhostEstream"} : (!fir.ref) -> (!fir.ref, !fir.ref) %c1_i32 = arith.constant 1 : i32 %c0_i32 = arith.constant 0 : i32 cuf.kernel_launch @_QMdevptrPtest<<<%c1_i32, %c1_i32, %c1_i32, %c1_i32, %c1_i32, %c1_i32, %c0_i32, %1#0 : !fir.ref>>>() return } } // CHECK-LABEL: func.func @_QQmain() // CHECK: %[[STREAM:.*]] = fir.alloca i64 {bindc_name = "stream", uniq_name = "_QMtest_callFhostEstream"} // CHECK: %[[DECL_STREAM:.*]]:2 = hlfir.declare %[[STREAM]] {uniq_name = "_QMtest_callFhostEstream"} : (!fir.ref) -> (!fir.ref, !fir.ref) // CHECK: %[[TOKEN:.*]] = cuf.stream_cast %[[DECL_STREAM]]#0 : !fir.ref // CHECK: gpu.launch_func [%[[TOKEN]]] @cuda_device_mod::@_QMdevptrPtest