Skip to content

Commit 45daa4f

Browse files
authored
[flang][cuda] Move CUDA Fortran operations to a CUF dialect (#92317)
The number of operations dedicated to CUF grew and where all still in FIR. In order to have a better organization, the CUF operations, attributes and code is moved into their specific dialect and files. CUF dialect is tightly coupled with HLFIR/FIR and their types. The CUF attributes are bundled into their own library since some HLFIR/FIR operations depend on them and the CUF dialect depends on the FIR types. Without having the attributes into a separate library there would be a dependency cycle.
1 parent d90159a commit 45daa4f

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

56 files changed

+1184
-817
lines changed

flang/include/flang/Lower/ConvertVariable.h

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
#include "mlir/IR/Value.h"
2424
#include "llvm/ADT/DenseMap.h"
2525

26+
namespace cuf {
27+
class DataAttributeAttr;
28+
}
29+
2630
namespace fir {
2731
class ExtendedValue;
2832
class FirOpBuilder;
@@ -146,9 +150,9 @@ translateSymbolAttributes(mlir::MLIRContext *mlirContext,
146150

147151
/// Translate the CUDA Fortran attributes of \p sym into the FIR CUDA attribute
148152
/// representation.
149-
fir::CUDADataAttributeAttr
150-
translateSymbolCUDADataAttribute(mlir::MLIRContext *mlirContext,
151-
const Fortran::semantics::Symbol &sym);
153+
cuf::DataAttributeAttr
154+
translateSymbolCUFDataAttribute(mlir::MLIRContext *mlirContext,
155+
const Fortran::semantics::Symbol &sym);
152156

153157
/// Map a symbol to a given fir::ExtendedValue. This will generate an
154158
/// hlfir.declare when lowering to HLFIR and map the hlfir.declare result to the

flang/include/flang/Optimizer/Builder/FIRBuilder.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -254,13 +254,13 @@ class FirOpBuilder : public mlir::OpBuilder, public mlir::OpBuilder::Listener {
254254
mlir::StringAttr linkage = {},
255255
mlir::Attribute value = {}, bool isConst = false,
256256
bool isTarget = false,
257-
fir::CUDADataAttributeAttr cudaAttr = {});
257+
cuf::DataAttributeAttr dataAttr = {});
258258

259259
fir::GlobalOp createGlobal(mlir::Location loc, mlir::Type type,
260260
llvm::StringRef name, bool isConst, bool isTarget,
261261
std::function<void(FirOpBuilder &)> bodyBuilder,
262262
mlir::StringAttr linkage = {},
263-
fir::CUDADataAttributeAttr cudaAttr = {});
263+
cuf::DataAttributeAttr dataAttr = {});
264264

265265
/// Create a global constant (read-only) value.
266266
fir::GlobalOp createGlobalConstant(mlir::Location loc, mlir::Type type,

flang/include/flang/Optimizer/Builder/HLFIRTools.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -239,7 +239,7 @@ genDeclare(mlir::Location loc, fir::FirOpBuilder &builder,
239239
const fir::ExtendedValue &exv, llvm::StringRef name,
240240
fir::FortranVariableFlagsAttr flags,
241241
mlir::Value dummyScope = nullptr,
242-
fir::CUDADataAttributeAttr cudaAttr = {});
242+
cuf::DataAttributeAttr dataAttr = {});
243243

244244
/// Generate an hlfir.associate to build a variable from an expression value.
245245
/// The type of the variable must be provided so that scalar logicals are

flang/include/flang/Optimizer/Dialect/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
add_subdirectory(CUF)
2+
13
# This replicates part of the add_mlir_dialect cmake function from MLIR that
24
# cannot be used her because it expects to be run inside MLIR directory which
35
# is not the case for FIR.
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
set(LLVM_TARGET_DEFINITIONS CUFAttr.td)
2+
mlir_tablegen(CUFEnumAttr.h.inc -gen-enum-decls)
3+
mlir_tablegen(CUFEnumAttr.cpp.inc -gen-enum-defs)
4+
mlir_tablegen(CUFAttr.h.inc --gen-attrdef-decls)
5+
mlir_tablegen(CUFAttr.cpp.inc -gen-attrdef-defs)
6+
7+
add_public_tablegen_target(CUFAttrsIncGen)
Lines changed: 106 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,106 @@
1+
//===-- Optimizer/Dialect/CUF/Attributes/CUFAttr.h -- CUF attributes ------===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef FORTRAN_OPTIMIZER_DIALECT_CUF_CUFATTR_H
14+
#define FORTRAN_OPTIMIZER_DIALECT_CUF_CUFATTR_H
15+
16+
#include "flang/Common/Fortran.h"
17+
#include "mlir/IR/BuiltinAttributes.h"
18+
19+
namespace llvm {
20+
class StringRef;
21+
}
22+
23+
#include "flang/Optimizer/Dialect/CUF/Attributes/CUFEnumAttr.h.inc"
24+
25+
#define GET_ATTRDEF_CLASSES
26+
#include "flang/Optimizer/Dialect/CUF/Attributes/CUFAttr.h.inc"
27+
28+
namespace cuf {
29+
30+
/// Attribute to mark Fortran entities with the CUDA attribute.
31+
static constexpr llvm::StringRef getDataAttrName() { return "cuf.data_attr"; }
32+
static constexpr llvm::StringRef getProcAttrName() { return "cuf.proc_attr"; }
33+
34+
/// Attribute to carry CUDA launch_bounds values.
35+
static constexpr llvm::StringRef getLaunchBoundsAttrName() {
36+
return "cuf.launch_bounds";
37+
}
38+
39+
/// Attribute to carry CUDA cluster_dims values.
40+
static constexpr llvm::StringRef getClusterDimsAttrName() {
41+
return "cuf.cluster_dims";
42+
}
43+
44+
inline cuf::DataAttributeAttr
45+
getDataAttribute(mlir::MLIRContext *mlirContext,
46+
std::optional<Fortran::common::CUDADataAttr> cudaAttr) {
47+
if (cudaAttr) {
48+
cuf::DataAttribute attr;
49+
switch (*cudaAttr) {
50+
case Fortran::common::CUDADataAttr::Constant:
51+
attr = cuf::DataAttribute::Constant;
52+
break;
53+
case Fortran::common::CUDADataAttr::Device:
54+
attr = cuf::DataAttribute::Device;
55+
break;
56+
case Fortran::common::CUDADataAttr::Managed:
57+
attr = cuf::DataAttribute::Managed;
58+
break;
59+
case Fortran::common::CUDADataAttr::Pinned:
60+
attr = cuf::DataAttribute::Pinned;
61+
break;
62+
case Fortran::common::CUDADataAttr::Shared:
63+
attr = cuf::DataAttribute::Shared;
64+
break;
65+
case Fortran::common::CUDADataAttr::Texture:
66+
// Obsolete attribute
67+
return {};
68+
case Fortran::common::CUDADataAttr::Unified:
69+
attr = cuf::DataAttribute::Unified;
70+
break;
71+
}
72+
return cuf::DataAttributeAttr::get(mlirContext, attr);
73+
}
74+
return {};
75+
}
76+
77+
inline cuf::ProcAttributeAttr
78+
getProcAttribute(mlir::MLIRContext *mlirContext,
79+
std::optional<Fortran::common::CUDASubprogramAttrs> cudaAttr) {
80+
if (cudaAttr) {
81+
cuf::ProcAttribute attr;
82+
switch (*cudaAttr) {
83+
case Fortran::common::CUDASubprogramAttrs::Host:
84+
attr = cuf::ProcAttribute::Host;
85+
break;
86+
case Fortran::common::CUDASubprogramAttrs::Device:
87+
attr = cuf::ProcAttribute::Device;
88+
break;
89+
case Fortran::common::CUDASubprogramAttrs::HostDevice:
90+
attr = cuf::ProcAttribute::HostDevice;
91+
break;
92+
case Fortran::common::CUDASubprogramAttrs::Global:
93+
attr = cuf::ProcAttribute::Global;
94+
break;
95+
case Fortran::common::CUDASubprogramAttrs::Grid_Global:
96+
attr = cuf::ProcAttribute::GridGlobal;
97+
break;
98+
}
99+
return cuf::ProcAttributeAttr::get(mlirContext, attr);
100+
}
101+
return {};
102+
}
103+
104+
} // namespace cuf
105+
106+
#endif // FORTRAN_OPTIMIZER_DIALECT_CUF_CUFATTR_H
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
//===- CUFAttr.td - CUF Attributes -------------------------*- tablegen -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// This file declares the CUF dialect attributes.
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef FORTRAN_DIALECT_CUF_CUFATTRS
14+
#define FORTRAN_DIALECT_CUF_CUFATTRS
15+
16+
include "flang/Optimizer/Dialect/CUF/CUFDialect.td"
17+
include "mlir/IR/EnumAttr.td"
18+
19+
class cuf_Attr<string name> : AttrDef<CUFDialect, name>;
20+
21+
def cuf_DataAttribute : I32EnumAttr<
22+
"DataAttribute",
23+
"CUDA Fortran variable attributes",
24+
[
25+
I32EnumAttrCase<"Constant", 0, "constant">,
26+
I32EnumAttrCase<"Device", 1, "device">,
27+
I32EnumAttrCase<"Managed", 2, "managed">,
28+
I32EnumAttrCase<"Pinned", 3, "pinned">,
29+
I32EnumAttrCase<"Shared", 4, "shared">,
30+
I32EnumAttrCase<"Unified", 5, "unified">,
31+
// Texture is omitted since it is obsolete and rejected by semantic.
32+
]> {
33+
let genSpecializedAttr = 0;
34+
let cppNamespace = "::cuf";
35+
}
36+
37+
def cuf_DataAttributeAttr :
38+
EnumAttr<CUFDialect, cuf_DataAttribute, "cuda"> {
39+
let assemblyFormat = [{ ```<` $value `>` }];
40+
}
41+
42+
def cuf_ProcAttribute : I32EnumAttr<
43+
"ProcAttribute", "CUDA Fortran procedure attributes",
44+
[
45+
I32EnumAttrCase<"Host", 0, "host">,
46+
I32EnumAttrCase<"Device", 1, "device">,
47+
I32EnumAttrCase<"HostDevice", 2, "host_device">,
48+
I32EnumAttrCase<"Global", 3, "global">,
49+
I32EnumAttrCase<"GridGlobal", 4, "grid_global">,
50+
]> {
51+
let genSpecializedAttr = 0;
52+
let cppNamespace = "::cuf";
53+
}
54+
55+
def cuf_ProcAttributeAttr :
56+
EnumAttr<CUFDialect, cuf_ProcAttribute, "cuda_proc"> {
57+
let assemblyFormat = [{ ```<` $value `>` }];
58+
}
59+
60+
def cuf_LaunchBoundsAttr : cuf_Attr<"LaunchBounds"> {
61+
let mnemonic = "launch_bounds";
62+
63+
let parameters = (ins
64+
"mlir::IntegerAttr":$maxTPB,
65+
"mlir::IntegerAttr":$minBPM,
66+
OptionalParameter<"mlir::IntegerAttr">:$upperBoundClusterSize
67+
);
68+
69+
let assemblyFormat = "`<` struct(params) `>`";
70+
}
71+
72+
def cuf_ClusterDimsAttr : cuf_Attr<"ClusterDims"> {
73+
let mnemonic = "cluster_dims";
74+
75+
let parameters = (ins
76+
"mlir::IntegerAttr":$x,
77+
"mlir::IntegerAttr":$y,
78+
"mlir::IntegerAttr":$z
79+
);
80+
81+
let assemblyFormat = "`<` struct(params) `>`";
82+
}
83+
84+
def cuf_DataTransferKind : I32EnumAttr<
85+
"DataTransferKind", "CUDA Fortran data transfer kind",
86+
[
87+
I32EnumAttrCase<"DeviceHost", 0, "device_host">,
88+
I32EnumAttrCase<"HostDevice", 1, "host_device">,
89+
I32EnumAttrCase<"DeviceDevice", 2, "device_device">,
90+
]> {
91+
let genSpecializedAttr = 0;
92+
let cppNamespace = "::cuf";
93+
}
94+
95+
def cuf_DataTransferKindAttr :
96+
EnumAttr<CUFDialect, cuf_DataTransferKind, "cuda_transfer"> {
97+
let assemblyFormat = [{ ```<` $value `>` }];
98+
}
99+
100+
#endif // FORTRAN_DIALECT_CUF_CUFATTRS
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
add_subdirectory(Attributes)
2+
3+
set(LLVM_TARGET_DEFINITIONS CUFDialect.td)
4+
mlir_tablegen(CUFDialect.h.inc -gen-dialect-decls -dialect=cuf)
5+
mlir_tablegen(CUFDialect.cpp.inc -gen-dialect-defs -dialect=cuf)
6+
7+
set(LLVM_TARGET_DEFINITIONS CUFOps.td)
8+
mlir_tablegen(CUFOps.h.inc -gen-op-decls)
9+
mlir_tablegen(CUFOps.cpp.inc -gen-op-defs)
10+
11+
add_public_tablegen_target(CUFOpsIncGen)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
//===-- Optimizer/Dialect/CUFDialect.h -- CUF dialect -----------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
//
9+
// Coding style: https://mlir.llvm.org/getting_started/DeveloperGuide/
10+
//
11+
//===----------------------------------------------------------------------===//
12+
13+
#ifndef FORTRAN_OPTIMIZER_DIALECT_CUF_CUFDIALECT_H
14+
#define FORTRAN_OPTIMIZER_DIALECT_CUF_CUFDIALECT_H
15+
16+
#include "mlir/Bytecode/BytecodeOpInterface.h"
17+
#include "mlir/IR/Dialect.h"
18+
#include "mlir/IR/SymbolTable.h"
19+
#include "mlir/Interfaces/CallInterfaces.h"
20+
#include "mlir/Interfaces/FunctionInterfaces.h"
21+
#include "mlir/Interfaces/LoopLikeInterface.h"
22+
#include "mlir/Interfaces/SideEffectInterfaces.h"
23+
24+
#include "flang/Optimizer/Dialect/CUF/CUFDialect.h.inc"
25+
26+
#endif // FORTRAN_OPTIMIZER_DIALECT_CUF_CUFDIALECT_H
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
//===-- CUFDialect.td - CUF dialect base definitions -------*- tablegen -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
///
9+
/// \file
10+
/// Definition of the CUDA Fortran dialect
11+
///
12+
//===----------------------------------------------------------------------===//
13+
14+
#ifndef FORTRAN_DIALECT_CUF_CUFDIALECT
15+
#define FORTRAN_DIALECT_CUF_CUFDIALECT
16+
17+
include "mlir/IR/AttrTypeBase.td"
18+
include "mlir/IR/EnumAttr.td"
19+
include "mlir/IR/OpBase.td"
20+
21+
def CUFDialect : Dialect {
22+
let name = "cuf";
23+
24+
let summary = "CUDA Fortran dialect";
25+
26+
let description = [{
27+
This dialect models CUDA Fortran operations. The CUF dialect operations use
28+
the FIR types and are tightly coupled with FIR and HLFIR.
29+
}];
30+
31+
let useDefaultAttributePrinterParser = 1;
32+
let usePropertiesForAttributes = 1;
33+
let cppNamespace = "::cuf";
34+
let dependentDialects = ["fir::FIROpsDialect"];
35+
36+
let extraClassDeclaration = [{
37+
private:
38+
// Register the CUF Attributes.
39+
void registerAttributes();
40+
}];
41+
}
42+
43+
#endif // FORTRAN_DIALECT_CUF_CUFDIALECT
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
//===-- Optimizer/Dialect/CUF/CUFOps.h - CUF operations ---------*- C++ -*-===//
2+
//
3+
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4+
// See https://llvm.org/LICENSE.txt for license information.
5+
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6+
//
7+
//===----------------------------------------------------------------------===//
8+
9+
#ifndef FORTRAN_OPTIMIZER_DIALECT_CUF_CUFOPS_H
10+
#define FORTRAN_OPTIMIZER_DIALECT_CUF_CUFOPS_H
11+
12+
#include "flang/Optimizer/Dialect/CUF/Attributes/CUFAttr.h"
13+
#include "flang/Optimizer/Dialect/CUF/CUFDialect.h"
14+
#include "flang/Optimizer/Dialect/FIRType.h"
15+
#include "mlir/IR/OpDefinition.h"
16+
17+
#define GET_OP_CLASSES
18+
#include "flang/Optimizer/Dialect/CUF/CUFOps.h.inc"
19+
20+
#endif // FORTRAN_OPTIMIZER_DIALECT_CUF_CUFOPS_H

0 commit comments

Comments
 (0)