Skip to content

Commit

Permalink
[flang][cuda] Propagate data attribute to global with initialization (#…
Browse files Browse the repository at this point in the history
…95504)

Global with initial value were missing the CUDA data attribute.
  • Loading branch information
clementval authored Jun 14, 2024
1 parent 6f538f6 commit 3a47d94
Show file tree
Hide file tree
Showing 4 changed files with 37 additions and 18 deletions.
3 changes: 2 additions & 1 deletion flang/include/flang/Lower/ConvertConstant.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ fir::GlobalOp tryCreatingDenseGlobal(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Type symTy,
llvm::StringRef globalName,
mlir::StringAttr linkage, bool isConst,
const Fortran::lower::SomeExpr &initExpr);
const Fortran::lower::SomeExpr &initExpr,
cuf::DataAttributeAttr dataAttr = {});

/// Lower a StructureConstructor that must be lowered in read only data although
/// it may not be wrapped into a Constant<T> (this may be the case for derived
Expand Down
23 changes: 13 additions & 10 deletions flang/lib/Lower/ConvertConstant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,8 @@ class DenseGlobalBuilder {
mlir::Location loc, mlir::Type symTy,
llvm::StringRef globalName,
mlir::StringAttr linkage, bool isConst,
const Fortran::lower::SomeExpr &initExpr) {
const Fortran::lower::SomeExpr &initExpr,
cuf::DataAttributeAttr dataAttr) {
DenseGlobalBuilder globalBuilder;
std::visit(
Fortran::common::visitors{
Expand All @@ -119,19 +120,20 @@ class DenseGlobalBuilder {
},
initExpr.u);
return globalBuilder.tryCreatingGlobal(builder, loc, symTy, globalName,
linkage, isConst);
linkage, isConst, dataAttr);
}

template <Fortran::common::TypeCategory TC, int KIND>
static fir::GlobalOp tryCreating(
fir::FirOpBuilder &builder, mlir::Location loc, mlir::Type symTy,
llvm::StringRef globalName, mlir::StringAttr linkage, bool isConst,
const Fortran::evaluate::Constant<Fortran::evaluate::Type<TC, KIND>>
&constant) {
&constant,
cuf::DataAttributeAttr dataAttr) {
DenseGlobalBuilder globalBuilder;
globalBuilder.tryConvertingToAttributes(builder, constant);
return globalBuilder.tryCreatingGlobal(builder, loc, symTy, globalName,
linkage, isConst);
linkage, isConst, dataAttr);
}

private:
Expand Down Expand Up @@ -178,8 +180,8 @@ class DenseGlobalBuilder {
fir::GlobalOp tryCreatingGlobal(fir::FirOpBuilder &builder,
mlir::Location loc, mlir::Type symTy,
llvm::StringRef globalName,
mlir::StringAttr linkage,
bool isConst) const {
mlir::StringAttr linkage, bool isConst,
cuf::DataAttributeAttr dataAttr) const {
// Not a "trivial" intrinsic constant array, or empty array.
if (!attributeElementType || attributes.empty())
return {};
Expand All @@ -191,7 +193,8 @@ class DenseGlobalBuilder {
auto tensorTy =
mlir::RankedTensorType::get(tensorShape, attributeElementType);
auto init = mlir::DenseElementsAttr::get(tensorTy, attributes);
return builder.createGlobal(loc, symTy, globalName, linkage, init, isConst);
return builder.createGlobal(loc, symTy, globalName, linkage, init, isConst,
/*isTarget=*/false, dataAttr);
}

llvm::SmallVector<mlir::Attribute> attributes;
Expand All @@ -202,9 +205,9 @@ class DenseGlobalBuilder {
fir::GlobalOp Fortran::lower::tryCreatingDenseGlobal(
fir::FirOpBuilder &builder, mlir::Location loc, mlir::Type symTy,
llvm::StringRef globalName, mlir::StringAttr linkage, bool isConst,
const Fortran::lower::SomeExpr &initExpr) {
const Fortran::lower::SomeExpr &initExpr, cuf::DataAttributeAttr dataAttr) {
return DenseGlobalBuilder::tryCreating(builder, loc, symTy, globalName,
linkage, isConst, initExpr);
linkage, isConst, initExpr, dataAttr);
}

//===----------------------------------------------------------------------===//
Expand Down Expand Up @@ -661,7 +664,7 @@ genOutlineArrayLit(Fortran::lower::AbstractConverter &converter,
T::category == Fortran::common::TypeCategory::Complex) {
global = DenseGlobalBuilder::tryCreating(
builder, loc, arrayTy, globalName, builder.createInternalLinkage(),
true, constant);
true, constant, {});
}
if (!global)
// If the number of elements of the array is huge, the compilation may
Expand Down
12 changes: 6 additions & 6 deletions flang/lib/Lower/ConvertVariable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -165,12 +165,15 @@ static fir::GlobalOp declareGlobal(Fortran::lower::AbstractConverter &converter,
fir::FirOpBuilder &builder = converter.getFirOpBuilder();
if (fir::GlobalOp global = builder.getNamedGlobal(globalName))
return global;
const Fortran::semantics::Symbol &sym = var.getSymbol();
cuf::DataAttributeAttr dataAttr =
Fortran::lower::translateSymbolCUFDataAttribute(
converter.getFirOpBuilder().getContext(), sym);
// Always define linkonce data since it may be optimized out from the module
// that actually owns the variable if it does not refers to it.
if (linkage == builder.createLinkOnceODRLinkage() ||
linkage == builder.createLinkOnceLinkage())
return defineGlobal(converter, var, globalName, linkage);
const Fortran::semantics::Symbol &sym = var.getSymbol();
return defineGlobal(converter, var, globalName, linkage, dataAttr);
mlir::Location loc = genLocation(converter, sym);
// Resolve potential host and module association before checking that this
// symbol is an object of a function pointer.
Expand All @@ -179,9 +182,6 @@ static fir::GlobalOp declareGlobal(Fortran::lower::AbstractConverter &converter,
!Fortran::semantics::IsProcedurePointer(ultimate))
mlir::emitError(loc, "processing global declaration: symbol '")
<< toStringRef(sym.name()) << "' has unexpected details\n";
cuf::DataAttributeAttr dataAttr =
Fortran::lower::translateSymbolCUFDataAttribute(
converter.getFirOpBuilder().getContext(), sym);
return builder.createGlobal(loc, converter.genType(var), globalName, linkage,
mlir::Attribute{}, isConstant(ultimate),
var.isTarget(), dataAttr);
Expand Down Expand Up @@ -510,7 +510,7 @@ static fir::GlobalOp defineGlobal(Fortran::lower::AbstractConverter &converter,
if (details->init()) {
global = Fortran::lower::tryCreatingDenseGlobal(
builder, loc, symTy, globalName, linkage, isConst,
details->init().value());
details->init().value(), dataAttr);
if (global) {
global.setVisibility(mlir::SymbolTable::Visibility::Public);
return global;
Expand Down
17 changes: 16 additions & 1 deletion flang/test/Lower/CUDA/cuda-data-attribute.cuf
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,30 @@
! Test lowering of CUDA attribute on variables.

module cuda_var

type :: t1
integer :: a
end type

real, constant :: mod_a_rc
! CHECK: fir.global @_QMcuda_varEmod_a_rc {data_attr = #cuf.cuda<constant>} : f32
real, device :: mod_b_ra
! CHECK: fir.global @_QMcuda_varEmod_b_ra {data_attr = #cuf.cuda<device>} : f32
real, allocatable, managed :: mod_c_rm
! CHECK: fir.global @_QMcuda_varEmod_c_rm {data_attr = #cuf.cuda<managed>} : !fir.box<!fir.heap<f32>>

integer, device, dimension(10) :: mod_d_i_init = (/ (i, i = 1, 10) /)
! CHECK: fir.global @_QMcuda_varEmod_d_i_init(dense<[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]> : tensor<10xi32>) {data_attr = #cuf.cuda<device>} : !fir.array<10xi32>

real, device, dimension(10) :: mod_d_rinit = (/ (i, i = 1, 10) /)
! CHECK: fir.global @_QMcuda_varEmod_d_rinit(dense<[{{.*}}]> : tensor<10xf32>) {data_attr = #cuf.cuda<device>} : !fir.array<10xf32>

real, allocatable, pinned :: mod_d_rp
! CHECK: fir.global @_QMcuda_varEmod_d_rp {data_attr = #cuf.cuda<pinned>} : !fir.box<!fir.heap<f32>>

type(t1), device :: mod_d_t(2)
! CHECK: fir.global @_QMcuda_varEmod_d_t {data_attr = #cuf.cuda<device>} : !fir.array<2x!fir.type<_QMcuda_varTt1{a:i32}>>

contains

subroutine local_var_attrs
Expand Down Expand Up @@ -71,7 +86,7 @@ end

! CHECK-LABEL: func.func @_QMcuda_varPcuda_alloc_free
! CHECK: %[[ALLOC_A:.*]] = cuf.alloc !fir.array<10xf32> {bindc_name = "a", data_attr = #cuf.cuda<device>, uniq_name = "_QMcuda_varFcuda_alloc_freeEa"} -> !fir.ref<!fir.array<10xf32>>
! CHECK: %[[SHAPE:.*]] = fir.shape %c10 : (index) -> !fir.shape<1>
! CHECK: %[[SHAPE:.*]] = fir.shape %c10{{.*}} : (index) -> !fir.shape<1>
! CHECK: %[[DECL_A:.*]]:2 = hlfir.declare %[[ALLOC_A]](%[[SHAPE]]) {data_attr = #cuf.cuda<device>, uniq_name = "_QMcuda_varFcuda_alloc_freeEa"} : (!fir.ref<!fir.array<10xf32>>, !fir.shape<1>) -> (!fir.ref<!fir.array<10xf32>>, !fir.ref<!fir.array<10xf32>>)

! CHECK: %[[ALLOC_U:.*]] = cuf.alloc i32 {bindc_name = "u", data_attr = #cuf.cuda<unified>, uniq_name = "_QMcuda_varFcuda_alloc_freeEu"} -> !fir.ref<i32>
Expand Down

0 comments on commit 3a47d94

Please sign in to comment.