@@ -88,11 +88,15 @@ def DLTI_DataLayoutSpecAttr :
88
88
89
89
/// Returns the attribute associated with the key.
90
90
FailureOr<Attribute> query(DataLayoutEntryKey key) {
91
- return llvm::cast<mlir::DataLayoutSpecInterface>(*this).queryHelper(key);
91
+ return :: llvm::cast<mlir::DataLayoutSpecInterface>(*this).queryHelper(key);
92
92
}
93
93
}];
94
94
}
95
95
96
+ //===----------------------------------------------------------------------===//
97
+ // MapAttr
98
+ //===----------------------------------------------------------------------===//
99
+
96
100
def DLTI_MapAttr : DLTIAttr<"Map", [DLTIQueryInterface]> {
97
101
let summary = "A mapping of DLTI-information by way of key-value pairs";
98
102
let description = [{
@@ -106,18 +110,16 @@ def DLTI_MapAttr : DLTIAttr<"Map", [DLTIQueryInterface]> {
106
110
107
111
Consider the following flat encoding of a single-key dictionary
108
112
```
109
- #dlti.map<#dlti.dl_entry< "CPU::cache::L1::size_in_bytes", 65536 : i32>>
113
+ #dlti.map<"CPU::cache::L1::size_in_bytes" = 65536 : i32>>
110
114
```
111
115
versus nested maps, which make it possible to obtain sub-dictionaries of
112
116
related information (with the following example making use of other
113
117
attributes that also implement the `DLTIQueryInterface`):
114
118
```
115
- #dlti.target_system_spec<"CPU":
116
- #dlti.target_device_spec<#dlti.dl_entry<"cache",
117
- #dlti.map<#dlti.dl_entry<"L1",
118
- #dlti.map<#dlti.dl_entry<"size_in_bytes", 65536 : i32>>>,
119
- #dlti.dl_entry<"L1d",
120
- #dlti.map<#dlti.dl_entry<"size_in_bytes", 32768 : i32>>> >>>>
119
+ #dlti.target_system_spec<"CPU" =
120
+ #dlti.target_device_spec<"cache" =
121
+ #dlti.map<"L1" = #dlti.map<"size_in_bytes" = 65536 : i32>,
122
+ "L1d" = #dlti.map<"size_in_bytes" = 32768 : i32> >>>
121
123
```
122
124
123
125
With the flat encoding, the implied structure of the key is ignored, that is
@@ -132,14 +134,13 @@ def DLTI_MapAttr : DLTIAttr<"Map", [DLTIQueryInterface]> {
132
134
`transform.dlti.query ["CPU","cache","L1","size_in_bytes"] at %op` gives
133
135
back the first leaf value contained. To access the other leaf, we need to do
134
136
`transform.dlti.query ["CPU","cache","L1d","size_in_bytes"] at %op`.
135
- ```
136
137
}];
137
138
let parameters = (ins
138
139
ArrayRefParameter<"DataLayoutEntryInterface", "">:$entries
139
140
);
140
141
let mnemonic = "map";
141
142
let genVerifyDecl = 1;
142
- let assemblyFormat = "`<` $entries `>`" ;
143
+ let hasCustomAssemblyFormat = 1 ;
143
144
let extraClassDeclaration = [{
144
145
/// Returns the attribute associated with the key.
145
146
FailureOr<Attribute> query(DataLayoutEntryKey key) {
@@ -167,20 +168,23 @@ def DLTI_TargetSystemSpecAttr :
167
168
```
168
169
dlti.target_system_spec =
169
170
#dlti.target_system_spec<
170
- "CPU": #dlti.target_device_spec<
171
- #dlti.dl_entry<"dlti. L1_cache_size_in_bytes", 4096: ui32> >,
172
- "GPU": #dlti.target_device_spec<
173
- #dlti.dl_entry<"dlti. max_vector_op_width", 64 : ui32> >,
174
- "XPU": #dlti.target_device_spec<
175
- #dlti.dl_entry<"dlti. max_vector_op_width", 4096 : ui32> >>
171
+ "CPU" = #dlti.target_device_spec<
172
+ " L1_cache_size_in_bytes" = 4096: ui32>,
173
+ "GPU" = #dlti.target_device_spec<
174
+ " max_vector_op_width" = 64 : ui32>,
175
+ "XPU" = #dlti.target_device_spec<
176
+ " max_vector_op_width" = 4096 : ui32>>
176
177
```
178
+
179
+ The verifier checks that keys are strings and pointed to values implement
180
+ DLTI's TargetDeviceSpecInterface.
177
181
}];
178
182
let parameters = (ins
179
- ArrayRefParameter<"DeviceIDTargetDeviceSpecPair", " ">:$entries
183
+ ArrayRefParameter<"DataLayoutEntryInterface ">:$entries
180
184
);
181
185
let mnemonic = "target_system_spec";
182
186
let genVerifyDecl = 1;
183
- let assemblyFormat = "`<` $entries `>`" ;
187
+ let hasCustomAssemblyFormat = 1 ;
184
188
let extraClassDeclaration = [{
185
189
/// Return the device specification that matches the given device ID
186
190
std::optional<TargetDeviceSpecInterface>
@@ -189,16 +193,18 @@ def DLTI_TargetSystemSpecAttr :
189
193
190
194
/// Returns the attribute associated with the key.
191
195
FailureOr<Attribute> query(DataLayoutEntryKey key) const {
192
- return llvm::cast<mlir::TargetSystemSpecInterface>(*this).queryHelper(key);
196
+ return :: llvm::cast<mlir::TargetSystemSpecInterface>(*this).queryHelper(key);
193
197
}
194
198
}];
195
199
let extraClassDefinition = [{
196
200
std::optional<TargetDeviceSpecInterface>
197
201
$cppClass::getDeviceSpecForDeviceID(
198
202
TargetSystemSpecInterface::DeviceID deviceID) {
199
203
for (const auto& entry : getEntries()) {
200
- if (entry.first == deviceID)
201
- return entry.second;
204
+ if (entry.getKey() == DataLayoutEntryKey(deviceID))
205
+ if (auto deviceSpec =
206
+ ::llvm::dyn_cast<TargetDeviceSpecInterface>(entry.getValue()))
207
+ return deviceSpec;
202
208
}
203
209
return std::nullopt;
204
210
}
@@ -219,21 +225,20 @@ def DLTI_TargetDeviceSpecAttr :
219
225
220
226
Example:
221
227
```
222
- #dlti.target_device_spec<
223
- #dlti.dl_entry<"dlti.max_vector_op_width", 64 : ui32>>
228
+ #dlti.target_device_spec<"max_vector_op_width" = 64 : ui32>
224
229
```
225
230
}];
226
231
let parameters = (ins
227
- ArrayRefParameter<"DataLayoutEntryInterface", "" >:$entries
232
+ ArrayRefParameter<"DataLayoutEntryInterface">:$entries
228
233
);
229
234
let mnemonic = "target_device_spec";
230
235
let genVerifyDecl = 1;
231
- let assemblyFormat = "`<` $entries `>`" ;
236
+ let hasCustomAssemblyFormat = 1 ;
232
237
233
238
let extraClassDeclaration = [{
234
239
/// Returns the attribute associated with the key.
235
240
FailureOr<Attribute> query(DataLayoutEntryKey key) const {
236
- return llvm::cast<mlir::TargetDeviceSpecInterface>(*this).queryHelper(key);
241
+ return :: llvm::cast<mlir::TargetDeviceSpecInterface>(*this).queryHelper(key);
237
242
}
238
243
}];
239
244
}
0 commit comments