Skip to content

Commit abd9534

Browse files
authored
Reimplementing target description concept using DLTI attribute (#92138)
and Interfaces. This is a newer implementation of PR #85141 and [RFC](https://discourse.llvm.org/t/rfc-target-description-and-cost-model-in-mlir/76990) by considering reviews and comments on the original PR. As an example of attributes supported by this commit: ``` module attributes { dlti.target_system_spec = #dlti.target_device_spec< #dlti.dl_entry<"dlti.device_id", 0: ui32>, #dlti.dl_entry<"dlti.device_type", "CPU">, #dlti.dl_entry<"dlti.L1_cache_size_in_bytes", 8192 : ui32>>, #dlti.target_device_spec < #dlti.dl_entry<"dlti.device_id", 1: ui32>, #dlti.dl_entry<"dlti.device_type", "GPU">, #dlti.dl_entry<"dlti.max_vector_op_width", 64 : ui32>>, #dlti.target_device_spec < #dlti.dl_entry<"dlti.device_id", 2: ui32>, #dlti.dl_entry<"dlti.device_type", "XPU">>> } ```
1 parent 24335e4 commit abd9534

File tree

16 files changed

+964
-215
lines changed

16 files changed

+964
-215
lines changed
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,8 @@
11
add_mlir_dialect(DLTI dlti)
22
add_mlir_doc(DLTI DLTIDialect Dialects/ -gen-dialect-doc)
3+
4+
set(LLVM_TARGET_DEFINITIONS DLTIAttrs.td)
5+
mlir_tablegen(DLTIAttrs.h.inc -gen-attrdef-decls -attrdefs-dialect=dlti)
6+
mlir_tablegen(DLTIAttrs.cpp.inc -gen-attrdef-defs -attrdefs-dialect=dlti)
7+
add_public_tablegen_target(MLIRDLTIAttrsIncGen)
8+
add_dependencies(mlir-headers MLIRDLTIAttrsIncGen)

mlir/include/mlir/Dialect/DLTI/DLTI.h

Lines changed: 5 additions & 106 deletions
Original file line numberDiff line numberDiff line change
@@ -18,114 +18,13 @@
1818
#include "mlir/Interfaces/DataLayoutInterfaces.h"
1919

2020
namespace mlir {
21-
namespace impl {
22-
class DataLayoutEntryStorage;
23-
class DataLayoutSpecStorage;
24-
} // namespace impl
25-
26-
//===----------------------------------------------------------------------===//
27-
// DataLayoutEntryAttr
28-
//===----------------------------------------------------------------------===//
29-
30-
/// A data layout entry attribute is a key-value pair where the key is a type or
31-
/// an identifier and the value is another attribute. These entries form a data
32-
/// layout specification.
33-
class DataLayoutEntryAttr
34-
: public Attribute::AttrBase<DataLayoutEntryAttr, Attribute,
35-
impl::DataLayoutEntryStorage,
36-
DataLayoutEntryInterface::Trait> {
37-
public:
38-
using Base::Base;
39-
40-
/// The keyword used for this attribute in custom syntax.
41-
constexpr const static llvm::StringLiteral kAttrKeyword = "dl_entry";
42-
43-
/// Returns the entry with the given key and value.
44-
static DataLayoutEntryAttr get(StringAttr key, Attribute value);
45-
static DataLayoutEntryAttr get(Type key, Attribute value);
46-
47-
/// Returns the key of this entry.
48-
DataLayoutEntryKey getKey() const;
49-
50-
/// Returns the value of this entry.
51-
Attribute getValue() const;
52-
53-
/// Parses an instance of this attribute.
54-
static DataLayoutEntryAttr parse(AsmParser &parser);
55-
56-
/// Prints this attribute.
57-
void print(AsmPrinter &os) const;
58-
59-
static constexpr StringLiteral name = "builtin.data_layout_entry";
60-
};
61-
62-
//===----------------------------------------------------------------------===//
63-
// DataLayoutSpecAttr
64-
//===----------------------------------------------------------------------===//
65-
66-
/// A data layout specification is a list of entries that specify (partial) data
67-
/// layout information. It is expected to be attached to operations that serve
68-
/// as scopes for data layout requests.
69-
class DataLayoutSpecAttr
70-
: public Attribute::AttrBase<DataLayoutSpecAttr, Attribute,
71-
impl::DataLayoutSpecStorage,
72-
DataLayoutSpecInterface::Trait> {
73-
public:
74-
using Base::Base;
75-
76-
/// The keyword used for this attribute in custom syntax.
77-
constexpr const static StringLiteral kAttrKeyword = "dl_spec";
78-
79-
/// Returns the specification containing the given list of keys.
80-
static DataLayoutSpecAttr get(MLIRContext *ctx,
81-
ArrayRef<DataLayoutEntryInterface> entries);
82-
83-
/// Returns the specification containing the given list of keys. If the list
84-
/// contains duplicate keys or is otherwise invalid, reports errors using the
85-
/// given callback and returns null.
86-
static DataLayoutSpecAttr
87-
getChecked(function_ref<InFlightDiagnostic()> emitError, MLIRContext *context,
88-
ArrayRef<DataLayoutEntryInterface> entries);
89-
90-
/// Checks that the given list of entries does not contain duplicate keys.
91-
static LogicalResult verify(function_ref<InFlightDiagnostic()> emitError,
92-
ArrayRef<DataLayoutEntryInterface> entries);
93-
94-
/// Combines this specification with `specs`, enclosing specifications listed
95-
/// from outermost to innermost. This overwrites the older entries with the
96-
/// same key as the newer entries if the entries are compatible. Returns null
97-
/// if the specifications are not compatible.
98-
DataLayoutSpecAttr combineWith(ArrayRef<DataLayoutSpecInterface> specs) const;
99-
100-
/// Returns the list of entries.
101-
DataLayoutEntryListRef getEntries() const;
102-
103-
/// Returns the endiannes identifier.
104-
StringAttr getEndiannessIdentifier(MLIRContext *context) const;
105-
106-
/// Returns the alloca memory space identifier.
107-
StringAttr getAllocaMemorySpaceIdentifier(MLIRContext *context) const;
108-
109-
/// Returns the program memory space identifier.
110-
StringAttr getProgramMemorySpaceIdentifier(MLIRContext *context) const;
111-
112-
/// Returns the global memory space identifier.
113-
StringAttr getGlobalMemorySpaceIdentifier(MLIRContext *context) const;
114-
115-
/// Returns the stack alignment identifier.
116-
StringAttr getStackAlignmentIdentifier(MLIRContext *context) const;
117-
118-
/// Parses an instance of this attribute.
119-
static DataLayoutSpecAttr parse(AsmParser &parser);
120-
121-
/// Prints this attribute.
122-
void print(AsmPrinter &os) const;
123-
124-
static constexpr StringLiteral name = "builtin.data_layout_spec";
125-
};
126-
21+
namespace detail {
22+
class DataLayoutEntryAttrStorage;
23+
} // namespace detail
12724
} // namespace mlir
12825

26+
#define GET_ATTRDEF_CLASSES
27+
#include "mlir/Dialect/DLTI/DLTIAttrs.h.inc"
12928
#include "mlir/Dialect/DLTI/DLTIDialect.h.inc"
13029

13130
#endif // MLIR_DIALECT_DLTI_DLTI_H
Lines changed: 188 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,188 @@
1+
//===- DLTIAttrs.td - DLTI dialect attributes definition --*- 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+
#ifndef MLIR_DIALECT_DLTI_DLTIATTRS_TD
10+
#define MLIR_DIALECT_DLTI_DLTIATTRS_TD
11+
12+
include "mlir/Dialect/DLTI/DLTI.td"
13+
include "mlir/IR/AttrTypeBase.td"
14+
15+
class DLTIAttr<string name, list<Trait> traits = [],
16+
string baseCppClass = "::mlir::Attribute">
17+
: AttrDef<DLTI_Dialect, name, traits, baseCppClass> { }
18+
19+
//===----------------------------------------------------------------------===//
20+
// DataLayoutEntryAttr
21+
//===----------------------------------------------------------------------===//
22+
23+
def DataLayoutEntryTrait
24+
: NativeAttrTrait<"DataLayoutEntryInterface::Trait"> {
25+
let cppNamespace = "::mlir";
26+
}
27+
28+
def DLTI_DataLayoutEntryAttr :
29+
DLTIAttr<"DataLayoutEntry", [DataLayoutEntryTrait]> {
30+
let summary = [{
31+
An attribute to represent an entry of a data layout specification.
32+
}];
33+
let description = [{
34+
A data layout entry attribute is a key-value pair where the key is a type or
35+
an identifier and the value is another attribute. These entries form a data
36+
layout specification.
37+
}];
38+
let parameters = (ins
39+
"DataLayoutEntryKey":$key, "Attribute":$value
40+
);
41+
// TODO: We do not generate storage class because llvm::PointerUnion
42+
// does not work with hash_key method.
43+
let genStorageClass = 0;
44+
let mnemonic = "dl_entry";
45+
let genVerifyDecl = 0;
46+
let hasCustomAssemblyFormat = 1;
47+
let extraClassDeclaration = [{
48+
/// Returns the entry with the given key and value.
49+
static DataLayoutEntryAttr get(StringAttr key, Attribute value);
50+
static DataLayoutEntryAttr get(MLIRContext *context, Type key, Attribute value);
51+
static DataLayoutEntryAttr get(Type key, Attribute value);
52+
}];
53+
}
54+
55+
//===----------------------------------------------------------------------===//
56+
// DataLayoutSpecAttr
57+
//===----------------------------------------------------------------------===//
58+
def DataLayoutSpecTrait
59+
: NativeAttrTrait<"DataLayoutSpecInterface::Trait"> {
60+
let cppNamespace = "::mlir";
61+
}
62+
63+
def DLTI_DataLayoutSpecAttr :
64+
DLTIAttr<"DataLayoutSpec", [DataLayoutSpecTrait]> {
65+
let summary = [{
66+
An attribute to represent a data layout specification.
67+
}];
68+
let description = [{
69+
A data layout specification is a list of entries that specify (partial) data
70+
layout information. It is expected to be attached to operations that serve
71+
as scopes for data layout requests.
72+
}];
73+
let parameters = (ins
74+
ArrayRefParameter<"DataLayoutEntryInterface", "">:$entries
75+
);
76+
let mnemonic = "dl_spec";
77+
let genVerifyDecl = 1;
78+
let hasCustomAssemblyFormat = 1;
79+
let extraClassDeclaration = [{
80+
/// Combines this specification with `specs`, enclosing specifications listed
81+
/// from outermost to innermost. This overwrites the older entries with the
82+
/// same key as the newer entries if the entries are compatible. Returns null
83+
/// if the specifications are not compatible.
84+
DataLayoutSpecAttr combineWith(ArrayRef<DataLayoutSpecInterface> specs) const;
85+
86+
/// Returns the endiannes identifier.
87+
StringAttr getEndiannessIdentifier(MLIRContext *context) const;
88+
89+
/// Returns the alloca memory space identifier.
90+
StringAttr getAllocaMemorySpaceIdentifier(MLIRContext *context) const;
91+
92+
/// Returns the program memory space identifier.
93+
StringAttr getProgramMemorySpaceIdentifier(MLIRContext *context) const;
94+
95+
/// Returns the global memory space identifier.
96+
StringAttr getGlobalMemorySpaceIdentifier(MLIRContext *context) const;
97+
98+
/// Returns the stack alignment identifier.
99+
StringAttr getStackAlignmentIdentifier(MLIRContext *context) const;
100+
}];
101+
}
102+
103+
//===----------------------------------------------------------------------===//
104+
// TargetSystemSpecAttr
105+
//===----------------------------------------------------------------------===//
106+
107+
def TargetSystemSpecTrait
108+
: NativeAttrTrait<"TargetSystemSpecInterface::Trait"> {
109+
let cppNamespace = "::mlir";
110+
}
111+
112+
def DLTI_TargetSystemSpecAttr :
113+
DLTIAttr<"TargetSystemSpec", [TargetSystemSpecTrait]> {
114+
let summary = [{
115+
An attribute to represent target system specification.
116+
}];
117+
let description = [{
118+
A system specification describes the overall system containing
119+
multiple devices, with each device having a unique ID (string)
120+
and its corresponding TargetDeviceSpec object.
121+
122+
Example:
123+
dlti.target_system_spec =
124+
#dlti.target_system_spec<
125+
"CPU": #dlti.target_device_spec<
126+
#dlti.dl_entry<"dlti.L1_cache_size_in_bytes", 4096: ui32>>,
127+
"GPU": #dlti.target_device_spec<
128+
#dlti.dl_entry<"dlti.max_vector_op_width", 64 : ui32>>,
129+
"XPU": #dlti.target_device_spec<
130+
#dlti.dl_entry<"dlti.max_vector_op_width", 4096 : ui32>>>
131+
}];
132+
let parameters = (ins
133+
ArrayRefParameter<"DeviceIDTargetDeviceSpecPair", "">:$entries
134+
);
135+
let mnemonic = "target_system_spec";
136+
let genVerifyDecl = 1;
137+
let assemblyFormat = "`<` $entries `>`";
138+
let extraClassDeclaration = [{
139+
/// Return the device specification that matches the given device ID
140+
std::optional<TargetDeviceSpecInterface>
141+
getDeviceSpecForDeviceID(
142+
TargetSystemSpecInterface::DeviceID deviceID);
143+
}];
144+
let extraClassDefinition = [{
145+
std::optional<TargetDeviceSpecInterface>
146+
$cppClass::getDeviceSpecForDeviceID(
147+
TargetSystemSpecInterface::DeviceID deviceID) {
148+
for (const auto& entry : getEntries()) {
149+
if (entry.first == deviceID)
150+
return entry.second;
151+
}
152+
return std::nullopt;
153+
}
154+
}];
155+
}
156+
157+
//===----------------------------------------------------------------------===//
158+
// TargetDeviceSpecAttr
159+
//===----------------------------------------------------------------------===//
160+
161+
def TargetDeviceSpecTrait
162+
: NativeAttrTrait<"TargetDeviceSpecInterface::Trait"> {
163+
let cppNamespace = "::mlir";
164+
}
165+
166+
def DLTI_TargetDeviceSpecAttr :
167+
DLTIAttr<"TargetDeviceSpec", [TargetDeviceSpecTrait]> {
168+
let summary = [{
169+
An attribute to represent target device specification.
170+
}];
171+
let description = [{
172+
Each device specification describes a single device and its
173+
hardware properties. Each device specification can contain any number
174+
of optional hardware properties (e.g., max_vector_op_width below).
175+
176+
Example:
177+
#dlti.target_device_spec<
178+
#dlti.dl_entry<"dlti.max_vector_op_width", 64 : ui32>>
179+
}];
180+
let parameters = (ins
181+
ArrayRefParameter<"DataLayoutEntryInterface", "">:$entries
182+
);
183+
let mnemonic = "target_device_spec";
184+
let genVerifyDecl = 1;
185+
let assemblyFormat = "`<` $entries `>`";
186+
}
187+
188+
#endif // MLIR_DIALECT_DLTI_DLTIATTRS_TD

mlir/include/mlir/Dialect/DLTI/DLTIBase.td

Lines changed: 7 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,13 @@ def DLTI_Dialect : Dialect {
2727
constexpr const static ::llvm::StringLiteral
2828
kDataLayoutAttrName = "dlti.dl_spec";
2929

30+
// Top level attribute name for target system description
31+
constexpr const static ::llvm::StringLiteral
32+
kTargetSystemDescAttrName = "dlti.target_system_spec";
33+
34+
constexpr const static ::llvm::StringLiteral
35+
kTargetDeviceDescAttrName = "dlti.target_device_spec";
36+
3037
// Constants used in entries.
3138
constexpr const static ::llvm::StringLiteral
3239
kDataLayoutEndiannessKey = "dlti.endianness";
@@ -53,24 +60,6 @@ def DLTI_Dialect : Dialect {
5360
let useDefaultAttributePrinterParser = 1;
5461
}
5562

56-
def DLTI_DataLayoutEntryAttr : DialectAttr<
57-
DLTI_Dialect,
58-
CPred<"::llvm::isa<::mlir::DataLayoutEntryAttr>($_self)">,
59-
"Target data layout entry"> {
60-
let storageType = "::mlir::DataLayoutEntryAttr";
61-
let returnType = "::mlir::DataLayoutEntryAttr";
62-
let convertFromStorage = "$_self";
63-
}
64-
65-
def DLTI_DataLayoutSpecAttr : DialectAttr<
66-
DLTI_Dialect,
67-
CPred<"::llvm::isa<::mlir::DataLayoutSpecAttr>($_self)">,
68-
"Target data layout specification"> {
69-
let storageType = "::mlir::DataLayoutSpecAttr";
70-
let returnType = "::mlir::DataLayoutSpecAttr";
71-
let convertFromStorage = "$_self";
72-
}
73-
7463
def HasDefaultDLTIDataLayout : NativeOpTrait<"HasDefaultDLTIDataLayout"> {
7564
let cppNamespace = "::mlir";
7665
}

mlir/include/mlir/Dialect/DLTI/Traits.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class DataLayoutSpecAttr;
1818
namespace impl {
1919
LogicalResult verifyHasDefaultDLTIDataLayoutTrait(Operation *op);
2020
DataLayoutSpecInterface getDataLayoutSpec(Operation *op);
21+
TargetSystemSpecInterface getTargetSystemSpec(Operation *op);
2122
} // namespace impl
2223

2324
/// Trait to be used by operations willing to use the implementation of the
@@ -37,6 +38,12 @@ class HasDefaultDLTIDataLayout
3738
DataLayoutSpecInterface getDataLayoutSpec() {
3839
return impl::getDataLayoutSpec(this->getOperation());
3940
}
41+
42+
/// Returns the target system description specification as provided by DLTI
43+
/// dialect
44+
TargetSystemSpecInterface getTargetSystemSpec() {
45+
return impl::getTargetSystemSpec(this->getOperation());
46+
}
4047
};
4148
} // namespace mlir
4249

mlir/include/mlir/IR/BuiltinOps.td

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,7 @@ def ModuleOp : Builtin_Op<"module", [
7878
//===------------------------------------------------------------------===//
7979

8080
DataLayoutSpecInterface getDataLayoutSpec();
81+
TargetSystemSpecInterface getTargetSystemSpec();
8182

8283
//===------------------------------------------------------------------===//
8384
// OpAsmOpInterface Methods

0 commit comments

Comments
 (0)