Skip to content

Commit 9fa7b9e

Browse files
committed
[mlir][gpu] Add target attribute to GPU modules.
**For an explanation of these patches see D154153.** Commit message: Adds support for Target attributes in GPU modules. This change enables attaching an optional non empty array of GPU target attributes to the module. Depends on D154104 Reviewed By: mehdi_amini Differential Revision: https://reviews.llvm.org/D154113
1 parent 96e1032 commit 9fa7b9e

File tree

3 files changed

+91
-13
lines changed

3 files changed

+91
-13
lines changed

mlir/include/mlir/Dialect/GPU/IR/GPUOps.td

Lines changed: 26 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
include "mlir/Dialect/DLTI/DLTIBase.td"
1717
include "mlir/Dialect/GPU/IR/GPUBase.td"
18+
include "mlir/Dialect/GPU/IR/CompilationAttrInterfaces.td"
1819
include "mlir/Dialect/GPU/IR/ParallelLoopMapperAttr.td"
1920
include "mlir/Dialect/GPU/TransformOps/GPUDeviceMappingAttr.td"
2021
include "mlir/IR/EnumAttr.td"
@@ -998,10 +999,9 @@ def GPU_BarrierOp : GPU_Op<"barrier"> {
998999
}
9991000

10001001
def GPU_GPUModuleOp : GPU_Op<"module", [
1001-
DataLayoutOpInterface, HasDefaultDLTIDataLayout, IsolatedFromAbove,
1002-
SymbolTable, Symbol,
1003-
SingleBlockImplicitTerminator<"ModuleEndOp">
1004-
]> {
1002+
DataLayoutOpInterface, HasDefaultDLTIDataLayout, IsolatedFromAbove,
1003+
SymbolTable, Symbol, SingleBlockImplicitTerminator<"ModuleEndOp">
1004+
]>, Arguments<(ins OptionalAttr<GPUNonEmptyTargetArrayAttr>:$targets)> {
10051005
let summary = "A top level compilation unit containing code to be run on a GPU.";
10061006
let description = [{
10071007
GPU module contains code that is intended to be run on a GPU. A host device
@@ -1018,22 +1018,41 @@ def GPU_GPUModuleOp : GPU_Op<"module", [
10181018
allows filtering of code regions to execute passes on only code intended to
10191019
or not intended to be run on the separate device.
10201020

1021+
Modules can contain zero or more target attributes. These attributes encode
1022+
how to transform modules into binary strings and are used by the
1023+
`gpu-module-to-binary` pass to transform modules into GPU binaries.
1024+
10211025
```
1022-
gpu.module @symbol_name {
1026+
gpu.module @symbol_name {
1027+
gpu.func {}
1028+
...
1029+
gpu.module_end
1030+
}
1031+
gpu.module @symbol_name2 [#nvvm.target, #rocdl.target<chip = "gfx90a">] {
10231032
gpu.func {}
10241033
...
10251034
gpu.module_end
10261035
}
1027-
10281036
```
10291037
}];
1030-
let builders = [OpBuilder<(ins "StringRef":$name)>];
1038+
let builders = [
1039+
OpBuilder<(ins "StringRef":$name, CArg<"ArrayAttr", "{}">:$targets)>,
1040+
OpBuilder<(ins "StringRef":$name, "ArrayRef<Attribute>":$targets)>
1041+
];
10311042
let regions = (region SizedRegion<1>:$bodyRegion);
10321043
let hasCustomAssemblyFormat = 1;
10331044

10341045
// We need to ensure the block inside the region is properly terminated;
10351046
// the auto-generated builders do not guarantee that.
10361047
let skipDefaultBuilders = 1;
1048+
1049+
let extraClassDeclaration = [{
1050+
/// Checks if `target` is in the `targets` list.
1051+
bool hasTarget(Attribute target);
1052+
1053+
/// Sets the targets of the module.
1054+
void setTargets(ArrayRef<TargetAttrInterface> targets);
1055+
}];
10371056
}
10381057

10391058
def GPU_ModuleEndOp : GPU_Op<"module_end", [

mlir/lib/Dialect/GPU/IR/GPUDialect.cpp

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1508,18 +1508,41 @@ LogicalResult gpu::ReturnOp::verify() {
15081508
//===----------------------------------------------------------------------===//
15091509

15101510
void GPUModuleOp::build(OpBuilder &builder, OperationState &result,
1511-
StringRef name) {
1511+
StringRef name, ArrayAttr targets) {
15121512
ensureTerminator(*result.addRegion(), builder, result.location);
15131513
result.attributes.push_back(builder.getNamedAttr(
15141514
::mlir::SymbolTable::getSymbolAttrName(), builder.getStringAttr(name)));
1515+
1516+
if (targets)
1517+
result.getOrAddProperties<Properties>().targets = targets;
1518+
}
1519+
1520+
void GPUModuleOp::build(OpBuilder &builder, OperationState &result,
1521+
StringRef name, ArrayRef<Attribute> targets) {
1522+
build(builder, result, name,
1523+
targets.size() > 0 ? builder.getArrayAttr(targets) : ArrayAttr());
15151524
}
15161525

15171526
ParseResult GPUModuleOp::parse(OpAsmParser &parser, OperationState &result) {
15181527
StringAttr nameAttr;
1528+
ArrayAttr targetsAttr;
1529+
15191530
if (parser.parseSymbolName(nameAttr, mlir::SymbolTable::getSymbolAttrName(),
1520-
result.attributes) ||
1521-
// If module attributes are present, parse them.
1522-
parser.parseOptionalAttrDictWithKeyword(result.attributes))
1531+
result.attributes))
1532+
return failure();
1533+
1534+
// Parse the optional array of target attributes.
1535+
OptionalParseResult targetsAttrResult =
1536+
parser.parseOptionalAttribute(targetsAttr, Type{});
1537+
if (targetsAttrResult.has_value()) {
1538+
if (failed(*targetsAttrResult)) {
1539+
return failure();
1540+
}
1541+
result.getOrAddProperties<Properties>().targets = targetsAttr;
1542+
}
1543+
1544+
// If module attributes are present, parse them.
1545+
if (parser.parseOptionalAttrDictWithKeyword(result.attributes))
15231546
return failure();
15241547

15251548
// Parse the module body.
@@ -1535,13 +1558,33 @@ ParseResult GPUModuleOp::parse(OpAsmParser &parser, OperationState &result) {
15351558
void GPUModuleOp::print(OpAsmPrinter &p) {
15361559
p << ' ';
15371560
p.printSymbolName(getName());
1538-
p.printOptionalAttrDictWithKeyword((*this)->getAttrs(),
1539-
{mlir::SymbolTable::getSymbolAttrName()});
1561+
1562+
if (Attribute attr = getTargetsAttr()) {
1563+
p << ' ';
1564+
p.printAttribute(attr);
1565+
p << ' ';
1566+
}
1567+
1568+
p.printOptionalAttrDictWithKeyword(
1569+
(*this)->getAttrs(),
1570+
{mlir::SymbolTable::getSymbolAttrName(), getTargetsAttrName()});
15401571
p << ' ';
15411572
p.printRegion(getRegion(), /*printEntryBlockArgs=*/false,
15421573
/*printBlockTerminators=*/false);
15431574
}
15441575

1576+
bool GPUModuleOp::hasTarget(Attribute target) {
1577+
if (ArrayAttr targets = getTargetsAttr())
1578+
return llvm::count(targets.getValue(), target);
1579+
return false;
1580+
}
1581+
1582+
void GPUModuleOp::setTargets(ArrayRef<TargetAttrInterface> targets) {
1583+
ArrayAttr &targetsAttr = getProperties().targets;
1584+
SmallVector<Attribute> targetsVector(targets);
1585+
targetsAttr = ArrayAttr::get(getContext(), targetsVector);
1586+
}
1587+
15451588
//===----------------------------------------------------------------------===//
15461589
// GPUMemcpyOp
15471590
//===----------------------------------------------------------------------===//

mlir/test/Dialect/GPU/invalid.mlir

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -610,3 +610,19 @@ module attributes {gpu.container_module} {
610610
}
611611
}
612612
}
613+
614+
// -----
615+
616+
module {
617+
// expected-error @+1 {{'gpu.module' op attribute 'targets' failed to satisfy constraint: array of GPU target attributes with at least 1 elements}}
618+
gpu.module @gpu_funcs [] {
619+
}
620+
}
621+
622+
// -----
623+
624+
module {
625+
// expected-error @+1 {{'gpu.module' op attribute 'targets' failed to satisfy constraint: array of GPU target attributes with at least 1 elements}}
626+
gpu.module @gpu_funcs [1] {
627+
}
628+
}

0 commit comments

Comments
 (0)