CodeQL / Analyze (actions) (push) Canceled after 0s
CodeQL / Analyze (python) (push) Canceled after 0s
pre-commit / pre-commit (push) Canceled after 0s
Multi-Arch CI / setup (push) Canceled after 0s
Publish build_manylinux_x86_64 images / publish_build_manylinux_x86_64 (push) Canceled after 0s
Setup (Multi-Arch) / setup (push) Canceled after 0s
Multi-Arch CI / Linux::${{ fromJSON(needs.setup.outputs.linux_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubi10 image / publish_no_rocm_image_ubi10 (push) Canceled after 0s
Multi-Arch CI / Windows::${{ fromJSON(needs.setup.outputs.windows_build_config || '{}').build_variant_label || 'skip' }} (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Multi-Arch CI / Manifest Diff (push) Canceled after 0s
TheRock Manifest Diff Report / Generate Manifest Diff Report (push) Canceled after 0s
Multi-Arch CI / CI Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_ocl_rt images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04_rocgdb images / publish_no_rocm_image_ubuntu24_04_rocgdb (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_ocl_rt (push) Canceled after 0s
Publish TheRock Docker image / build-and-push-image (push) Canceled after 0s
Unit Tests / Unit Tests :: ubuntu-24.04 (push) Canceled after 0s
Unit Tests / Unit Tests :: windows-2022 (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_media (push) Canceled after 0s
Unit Tests / Unit Tests Summary (push) Canceled after 0s
Publish no_rocm_image_ubuntu24_04 images / publish_no_rocm_image_ubuntu24_04_openmpi (push) Canceled after 0s
260 lines
18 KiB
Fortran
260 lines
18 KiB
Fortran
// RUN: fir-opt --split-input-file --cuf-add-constructor %s | FileCheck %s
|
|
// RUN: fir-opt --split-input-file --cuf-add-constructor="cuda-unified=true" %s | FileCheck %s --check-prefixes=CHECK,UNIFIED
|
|
|
|
module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<!llvm.ptr, dense<64> : vector<4xi64>>, #dlti.dl_entry<!llvm.ptr<271>, dense<32> : vector<4xi64>>, #dlti.dl_entry<!llvm.ptr<270>, dense<32> : vector<4xi64>>, #dlti.dl_entry<f128, dense<128> : vector<2xi64>>, #dlti.dl_entry<f64, dense<64> : vector<2xi64>>, #dlti.dl_entry<f80, dense<128> : vector<2xi64>>, #dlti.dl_entry<f16, dense<16> : vector<2xi64>>, #dlti.dl_entry<i32, dense<32> : vector<2xi64>>, #dlti.dl_entry<i16, dense<16> : vector<2xi64>>, #dlti.dl_entry<i128, dense<128> : vector<2xi64>>, #dlti.dl_entry<i8, dense<8> : vector<2xi64>>, #dlti.dl_entry<!llvm.ptr<272>, dense<64> : vector<4xi64>>, #dlti.dl_entry<i64, dense<64> : vector<2xi64>>, #dlti.dl_entry<i1, dense<8> : vector<2xi64>>, #dlti.dl_entry<"dlti.endianness", "little">, #dlti.dl_entry<"dlti.stack_alignment", 128 : i64>>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", gpu.container_module, llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 20.0.0 (https://github.com/llvm/llvm-project.git cae351f3453a0a26ec8eb2ddaf773c24a29d929e)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
|
|
|
|
fir.global @_QMmtestsEn(dense<[3, 4, 5, 6, 7]> : tensor<5xi32>) {data_attr = #cuf.cuda<device>} : !fir.array<5xi32>
|
|
fir.global @_QMmtestsEndev {data_attr = #cuf.cuda<device>} : !fir.box<!fir.heap<!fir.array<?xi32>>> {
|
|
%c0 = arith.constant 0 : index
|
|
%0 = fir.zero_bits !fir.heap<!fir.array<?xi32>>
|
|
%1 = fircg.ext_embox %0(%c0) {allocator_idx = 2 : i32} : (!fir.heap<!fir.array<?xi32>>, index) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
|
|
fir.has_value %1 : !fir.box<!fir.heap<!fir.array<?xi32>>>
|
|
}
|
|
|
|
// A kernel and the device globals must be present in the gpu.module
|
|
// for the constructor to register them (it skips modules without kernels
|
|
// and globals not in the gpu.module's symbol table).
|
|
gpu.module @cuda_device_mod {
|
|
gpu.func @_QMmtestsPkernel() kernel {
|
|
gpu.return
|
|
}
|
|
fir.global @_QMmtestsEn(dense<[3, 4, 5, 6, 7]> : tensor<5xi32>) {data_attr = #cuf.cuda<device>} : !fir.array<5xi32>
|
|
fir.global @_QMmtestsEndev {data_attr = #cuf.cuda<device>} : !fir.box<!fir.heap<!fir.array<?xi32>>> {
|
|
%c0 = arith.constant 0 : index
|
|
%0 = fir.zero_bits !fir.heap<!fir.array<?xi32>>
|
|
%1 = fircg.ext_embox %0(%c0) {allocator_idx = 2 : i32} : (!fir.heap<!fir.array<?xi32>>, index) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
|
|
fir.has_value %1 : !fir.box<!fir.heap<!fir.array<?xi32>>>
|
|
}
|
|
}
|
|
}
|
|
|
|
// CHECK: gpu.module @cuda_device_mod
|
|
|
|
// CHECK: llvm.func internal @__cudaFortranConstructor() {
|
|
// CHECK-DAG: %[[MODULE:.*]] = cuf.register_module @cuda_device_mod -> !llvm.ptr
|
|
// CHECK-DAG: %[[VAR_NAME:.*]] = fir.address_of(@_QQ{{.*}}) : !fir.ref<!fir.char<1,12>>
|
|
// CHECK-DAG: %[[VAR_ADDR:.*]] = fir.address_of(@_QMmtestsEn) : !fir.ref<!fir.array<5xi32>>
|
|
// CHECK-DAG: %[[MODULE2:.*]] = fir.convert %[[MODULE]] : (!llvm.ptr) -> !fir.ref<!fir.llvm_ptr<i8>>
|
|
// CHECK-DAG: %[[VAR_ADDR2:.*]] = fir.convert %[[VAR_ADDR]] : (!fir.ref<!fir.array<5xi32>>) -> !fir.ref<i8>
|
|
// CHECK-DAG: %[[VAR_NAME2:.*]] = fir.convert %[[VAR_NAME]] : (!fir.ref<!fir.char<1,12>>) -> !fir.ref<i8>
|
|
// CHECK-DAG: %[[CST:.*]] = arith.constant 20 : index
|
|
// CHECK-DAG: %[[CST2:.*]] = fir.convert %[[CST]] : (index) -> i64
|
|
// CHECK-DAG: fir.call @_FortranACUFRegisterVariable(%[[MODULE2]], %[[VAR_ADDR2]], %[[VAR_NAME2]], %[[CST2]]) : (!fir.ref<!fir.llvm_ptr<i8>>, !fir.ref<i8>, !fir.ref<i8>, i64) -> ()
|
|
// CHECK-DAG: %[[BOX:.*]] = fir.address_of(@_QMmtestsEndev) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
|
// CHECK-DAG: %[[BOXREF:.*]] = fir.convert %[[BOX]] : (!fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>) -> !fir.ref<i8>
|
|
// CHECK-DAG: fir.call @_FortranACUFRegisterVariable(%[[MODULE:.*]], %[[BOXREF]], %{{.*}}, %{{.*}})
|
|
// CHECK-NOT: fir.call @_FortranACUFInitModule
|
|
|
|
// -----
|
|
|
|
// Checking that constant global variables are not registered
|
|
|
|
// CHECK: @_FortranACUFRegisterAllocator
|
|
// CHECK-NOT: fir.call @_FortranACUFRegisterVariable
|
|
|
|
module attributes {dlti.dl_spec = #dlti.dl_spec<i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i1 = dense<8> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, f80 = dense<128> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, i64 = dense<64> : vector<2xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, f128 = dense<128> : vector<2xi64>, !llvm.ptr<270> = dense<32> : vector<4xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, "dlti.stack_alignment" = 128 : i64, "dlti.endianness" = "little">, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", gpu.container_module, llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 20.0.0 (https://github.com/llvm/llvm-project.git 3372303188df0f7f8ac26e7ab610cf8b0f716d42)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
|
|
fir.global @_QMiso_c_bindingECc_int constant : i32
|
|
|
|
|
|
fir.type_info @_QM__fortran_builtinsT__builtin_c_ptr noinit nodestroy nofinal : !fir.type<_QM__fortran_builtinsT__builtin_c_ptr{__address:i64}>
|
|
gpu.module @cuda_device_mod {
|
|
fir.global @_QMiso_c_bindingECc_int {data_attr = #cuf.cuda<constant>} constant : i32
|
|
gpu.func @_QMdevmodPdevsub(%arg0: !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>) -> i32 {
|
|
%c0 = arith.constant 0 : index
|
|
%c4_i32 = arith.constant 4 : i32
|
|
%0 = fir.alloca i32 {bindc_name = "devsub", uniq_name = "_QMdevmodFdevsubEdevsub"}
|
|
%1 = fir.alloca i32 {bindc_name = "__builtin_warpsize", uniq_name = "_QM__fortran_builtinsEC__builtin_warpsize"}
|
|
%2 = fir.load %arg0 : !fir.ref<!fir.box<!fir.heap<!fir.array<?xf32>>>>
|
|
%3:3 = fir.box_dims %2, %c0 : (!fir.box<!fir.heap<!fir.array<?xf32>>>, index) -> (index, index, index)
|
|
%4 = fir.convert %3#1 : (index) -> i32
|
|
%5 = arith.muli %4, %c4_i32 : i32
|
|
fir.store %5 to %0 : !fir.ref<i32>
|
|
%6 = fir.load %0 : !fir.ref<i32>
|
|
gpu.return %6 : i32
|
|
}
|
|
}
|
|
}
|
|
|
|
// -----
|
|
|
|
module attributes {dlti.dl_spec = #dlti.dl_spec<i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i1 = dense<8> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, f80 = dense<128> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, i64 = dense<64> : vector<2xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, f128 = dense<128> : vector<2xi64>, !llvm.ptr<270> = dense<32> : vector<4xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, "dlti.stack_alignment" = 128 : i64, "dlti.endianness" = "little">, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", gpu.container_module, llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.ident = "flang version 20.0.0 (https://github.com/llvm/llvm-project.git 3372303188df0f7f8ac26e7ab610cf8b0f716d42)", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
|
|
fir.global @_QMmEa00 {data_attr = #cuf.cuda<managed>} : !fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>> {
|
|
%c0 = arith.constant 0 : index
|
|
%0 = fir.zero_bits !fir.heap<!fir.array<?x?x?x?x?xf64>>
|
|
%1 = fir.shape %c0, %c0, %c0, %c0, %c0 : (index, index, index, index, index) -> !fir.shape<5>
|
|
%2 = fir.embox %0(%1) {allocator_idx = 3 : i32} : (!fir.heap<!fir.array<?x?x?x?x?xf64>>, !fir.shape<5>) -> !fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>>
|
|
fir.has_value %2 : !fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>>
|
|
}
|
|
// A kernel and the managed global must be in the gpu.module for
|
|
// the constructor to register them.
|
|
gpu.module @cuda_device_mod {
|
|
gpu.func @_QMmPkernel() kernel {
|
|
gpu.return
|
|
}
|
|
fir.global @_QMmEa00 {data_attr = #cuf.cuda<managed>} : !fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>> {
|
|
%c0 = arith.constant 0 : index
|
|
%0 = fir.zero_bits !fir.heap<!fir.array<?x?x?x?x?xf64>>
|
|
%1 = fir.shape %c0, %c0, %c0, %c0, %c0 : (index, index, index, index, index) -> !fir.shape<5>
|
|
%2 = fir.embox %0(%1) {allocator_idx = 3 : i32} : (!fir.heap<!fir.array<?x?x?x?x?xf64>>, !fir.shape<5>) -> !fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>>
|
|
fir.has_value %2 : !fir.box<!fir.heap<!fir.array<?x?x?x?x?xf64>>>
|
|
}
|
|
}
|
|
}
|
|
|
|
// CHECK: llvm.func internal @__cudaFortranConstructor()
|
|
// CHECK: fir.address_of(@_QMmEa00)
|
|
// CHECK: fir.call @_FortranACUFRegisterVariable
|
|
// CHECK-NOT: fir.call @_FortranACUFInitModule
|
|
|
|
// -----
|
|
|
|
// Non-allocatable managed global: should create pointer global in
|
|
// __nv_managed_data__ and register with CUFRegisterManagedVariable.
|
|
//
|
|
// Fortran source:
|
|
// module test
|
|
// integer*4, managed :: manx(100)
|
|
// contains
|
|
// attributes(global) subroutine kernel()
|
|
// end subroutine
|
|
// end module
|
|
|
|
module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<!llvm.ptr, dense<64> : vector<4xi64>>, #dlti.dl_entry<i64, dense<64> : vector<2xi64>>, #dlti.dl_entry<i32, dense<32> : vector<2xi64>>, #dlti.dl_entry<i8, dense<8> : vector<2xi64>>, #dlti.dl_entry<i1, dense<8> : vector<2xi64>>, #dlti.dl_entry<f64, dense<64> : vector<2xi64>>, #dlti.dl_entry<f32, dense<32> : vector<2xi64>>, #dlti.dl_entry<"dlti.endianness", "little">, #dlti.dl_entry<"dlti.stack_alignment", 128 : i64>>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", gpu.container_module, llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
|
|
|
|
fir.global @_QMtestEmanx {data_attr = #cuf.cuda<managed>} : !fir.array<100xi32> {
|
|
%0 = fir.zero_bits !fir.array<100xi32>
|
|
fir.has_value %0 : !fir.array<100xi32>
|
|
}
|
|
|
|
// A kernel and the managed global must be in the gpu.module for
|
|
// the constructor to register them.
|
|
gpu.module @cuda_device_mod {
|
|
gpu.func @_QMtestPkernel() kernel {
|
|
gpu.return
|
|
}
|
|
fir.global @_QMtestEmanx {data_attr = #cuf.cuda<managed>} : !fir.array<100xi32> {
|
|
%0 = fir.zero_bits !fir.array<100xi32>
|
|
fir.has_value %0 : !fir.array<100xi32>
|
|
}
|
|
}
|
|
}
|
|
|
|
// Pointer global should be created with section attribute.
|
|
// CHECK: fir.global internal @_QMtestEmanx.managed.ptr {section = "__nv_managed_data__"} : !fir.llvm_ptr<i8>
|
|
// CHECK: fir.zero_bits !fir.llvm_ptr<i8>
|
|
|
|
// Constructor should register with CUFRegisterManagedVariable then init module.
|
|
// CHECK: llvm.func internal @__cudaFortranConstructor()
|
|
// CHECK: fir.address_of(@_QMtestEmanx.managed.ptr) : !fir.ref<!fir.llvm_ptr<i8>>
|
|
// CHECK: fir.call @_FortranACUFRegisterManagedVariable
|
|
// CHECK: fir.call @_FortranACUFInitModule
|
|
|
|
// -----
|
|
|
|
// Test that when the gpu.module has no kernels (e.g., host TU that USEs
|
|
// a kernel module), the constructor registers allocators but skips module
|
|
// registration.
|
|
|
|
module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<!llvm.ptr, dense<64> : vector<4xi64>>, #dlti.dl_entry<!llvm.ptr<271>, dense<32> : vector<4xi64>>, #dlti.dl_entry<!llvm.ptr<270>, dense<32> : vector<4xi64>>, #dlti.dl_entry<f128, dense<128> : vector<2xi64>>, #dlti.dl_entry<f64, dense<64> : vector<2xi64>>, #dlti.dl_entry<f80, dense<128> : vector<2xi64>>, #dlti.dl_entry<f16, dense<16> : vector<2xi64>>, #dlti.dl_entry<i32, dense<32> : vector<2xi64>>, #dlti.dl_entry<i16, dense<16> : vector<2xi64>>, #dlti.dl_entry<i128, dense<128> : vector<2xi64>>, #dlti.dl_entry<i8, dense<8> : vector<2xi64>>, #dlti.dl_entry<!llvm.ptr<272>, dense<64> : vector<4xi64>>, #dlti.dl_entry<i64, dense<64> : vector<2xi64>>, #dlti.dl_entry<i1, dense<8> : vector<2xi64>>, #dlti.dl_entry<"dlti.endianness", "little">, #dlti.dl_entry<"dlti.stack_alignment", 128 : i64>>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", gpu.container_module, llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
|
|
|
|
fir.global @_QMkernels_mEdev_var {data_attr = #cuf.cuda<device>} : f32 {
|
|
%0 = arith.constant 0.0 : f32
|
|
fir.has_value %0 : f32
|
|
}
|
|
|
|
gpu.module @cuda_device_mod {
|
|
gpu.func @_QMkernels_mPnot_a_kernel() {
|
|
gpu.return
|
|
}
|
|
}
|
|
}
|
|
|
|
// CHECK: llvm.func internal @__cudaFortranConstructor()
|
|
// CHECK-NEXT: llvm.call @_FortranACUFRegisterAllocator()
|
|
// CHECK-NEXT: llvm.return
|
|
// CHECK: llvm.mlir.global_ctors ctors = [@__cudaFortranConstructor]
|
|
|
|
// -----
|
|
|
|
// Test that when the gpu.module has no kernels but a device global, the
|
|
// constructor registers the global.
|
|
|
|
module attributes {dlti.dl_spec = #dlti.dl_spec<#dlti.dl_entry<!llvm.ptr, dense<64> : vector<4xi64>>, #dlti.dl_entry<!llvm.ptr<271>, dense<32> : vector<4xi64>>, #dlti.dl_entry<!llvm.ptr<270>, dense<32> : vector<4xi64>>, #dlti.dl_entry<f128, dense<128> : vector<2xi64>>, #dlti.dl_entry<f64, dense<64> : vector<2xi64>>, #dlti.dl_entry<f80, dense<128> : vector<2xi64>>, #dlti.dl_entry<f16, dense<16> : vector<2xi64>>, #dlti.dl_entry<i32, dense<32> : vector<2xi64>>, #dlti.dl_entry<i16, dense<16> : vector<2xi64>>, #dlti.dl_entry<i128, dense<128> : vector<2xi64>>, #dlti.dl_entry<i8, dense<8> : vector<2xi64>>, #dlti.dl_entry<!llvm.ptr<272>, dense<64> : vector<4xi64>>, #dlti.dl_entry<i64, dense<64> : vector<2xi64>>, #dlti.dl_entry<i1, dense<8> : vector<2xi64>>, #dlti.dl_entry<"dlti.endianness", "little">, #dlti.dl_entry<"dlti.stack_alignment", 128 : i64>>, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", gpu.container_module, llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
|
|
|
|
fir.global @_QMkernels_mEdev_var {data_attr = #cuf.cuda<device>} : f32 {
|
|
%0 = arith.constant 0.0 : f32
|
|
fir.has_value %0 : f32
|
|
}
|
|
|
|
gpu.module @cuda_device_mod {
|
|
gpu.func @_QMkernels_mPnot_a_kernel() {
|
|
gpu.return
|
|
}
|
|
fir.global @_QMkernels_mEdev_var {data_attr = #cuf.cuda<device>} : f32 {
|
|
%0 = arith.constant 0.0 : f32
|
|
fir.has_value %0 : f32
|
|
}
|
|
}
|
|
}
|
|
|
|
// CHECK: llvm.func internal @__cudaFortranConstructor()
|
|
// CHECK: llvm.call @_FortranACUFRegisterAllocator()
|
|
// CHECK: cuf.register_module @cuda_device_mod -> !llvm.ptr
|
|
// CHECK: fir.address_of(@_QMkernels_mEdev_var) : !fir.ref<f32>
|
|
// CHECK: fir.call @_FortranACUFRegisterVariable(%3, %4, %5, %6) : (!fir.ref<!fir.llvm_ptr<i8>>, !fir.ref<i8>, !fir.ref<i8>, i64) -> ()
|
|
|
|
// -----
|
|
|
|
// Under -gpu=mem:unified, a non-allocatable host module global referenced from
|
|
// device code (mirrored as an external-linkage clone in the GPU module by the
|
|
// CUFDeviceGlobal pass) must be registered with
|
|
// _FortranACUFRegisterExternalVariable so the device-side `.extern` symbol
|
|
// resolves to the host pointer at module-load time.
|
|
|
|
module attributes {dlti.dl_spec = #dlti.dl_spec<i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i1 = dense<8> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, f80 = dense<128> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, i64 = dense<64> : vector<2xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, f128 = dense<128> : vector<2xi64>, !llvm.ptr<270> = dense<32> : vector<4xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, "dlti.stack_alignment" = 128 : i64, "dlti.endianness" = "little">, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", gpu.container_module, llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
|
|
fir.global @_QMmtestsEm(dense<[1, 2, 3, 4, 5]> : tensor<5xi32>) : !fir.array<5xi32>
|
|
gpu.module @cuda_device_mod {
|
|
gpu.func @_QMmtestsPg1() kernel {
|
|
gpu.return
|
|
}
|
|
// External declaration: no body, no init value -- lowers to PTX
|
|
// `.extern .global ...`. CUFAddConstructor must register it so the
|
|
// CUDA runtime maps it to the host pointer at module-load time.
|
|
fir.global @_QMmtestsEm : !fir.array<5xi32>
|
|
}
|
|
}
|
|
|
|
// UNIFIED: llvm.func internal @__cudaFortranConstructor()
|
|
// UNIFIED: cuf.register_module @cuda_device_mod -> !llvm.ptr
|
|
// UNIFIED: fir.address_of(@_QMmtestsEm) : !fir.ref<!fir.array<5xi32>>
|
|
// UNIFIED: fir.call @_FortranACUFRegisterExternalVariable
|
|
// UNIFIED-NOT: fir.call @_FortranACUFInitModule
|
|
|
|
// -----
|
|
|
|
// Under -gpu=mem:unified, an allocatable host module global also gets
|
|
// registered via _FortranACUFRegisterExternalVariable; the registered symbol
|
|
// is the descriptor (fir.box<fir.heap<...>>). The host runtime allocates the
|
|
// data buffer in HMM/ATS-accessible memory.
|
|
|
|
module attributes {dlti.dl_spec = #dlti.dl_spec<i8 = dense<8> : vector<2xi64>, i16 = dense<16> : vector<2xi64>, i1 = dense<8> : vector<2xi64>, !llvm.ptr = dense<64> : vector<4xi64>, f80 = dense<128> : vector<2xi64>, i128 = dense<128> : vector<2xi64>, i64 = dense<64> : vector<2xi64>, !llvm.ptr<271> = dense<32> : vector<4xi64>, !llvm.ptr<272> = dense<64> : vector<4xi64>, f128 = dense<128> : vector<2xi64>, !llvm.ptr<270> = dense<32> : vector<4xi64>, f16 = dense<16> : vector<2xi64>, f64 = dense<64> : vector<2xi64>, i32 = dense<32> : vector<2xi64>, "dlti.stack_alignment" = 128 : i64, "dlti.endianness" = "little">, fir.defaultkind = "a1c4d8i4l4r4", fir.kindmap = "", gpu.container_module, llvm.data_layout = "e-m:e-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128", llvm.target_triple = "x86_64-unknown-linux-gnu"} {
|
|
fir.global @_QMmtestsEma : !fir.box<!fir.heap<!fir.array<?xi32>>> {
|
|
%c0 = arith.constant 0 : index
|
|
%0 = fir.zero_bits !fir.heap<!fir.array<?xi32>>
|
|
%1 = fircg.ext_embox %0(%c0) {allocator_idx = 2 : i32} : (!fir.heap<!fir.array<?xi32>>, index) -> !fir.box<!fir.heap<!fir.array<?xi32>>>
|
|
fir.has_value %1 : !fir.box<!fir.heap<!fir.array<?xi32>>>
|
|
}
|
|
gpu.module @cuda_device_mod {
|
|
gpu.func @_QMmtestsPg1() kernel {
|
|
gpu.return
|
|
}
|
|
fir.global @_QMmtestsEma : !fir.box<!fir.heap<!fir.array<?xi32>>>
|
|
}
|
|
}
|
|
|
|
// UNIFIED: llvm.func internal @__cudaFortranConstructor()
|
|
// UNIFIED: cuf.register_module @cuda_device_mod -> !llvm.ptr
|
|
// UNIFIED: fir.address_of(@_QMmtestsEma) : !fir.ref<!fir.box<!fir.heap<!fir.array<?xi32>>>>
|
|
// UNIFIED: fir.call @_FortranACUFRegisterExternalVariable
|
|
// UNIFIED-NOT: fir.call @_FortranACUFInitModule
|