@@ -88,11 +88,15 @@ def DLTI_DataLayoutSpecAttr :
8888
8989 /// Returns the attribute associated with the key.
9090 FailureOr<Attribute> query(DataLayoutEntryKey key) {
91- return llvm::cast<mlir::DataLayoutSpecInterface>(*this).queryHelper(key);
91+ return :: llvm::cast<mlir::DataLayoutSpecInterface>(*this).queryHelper(key);
9292 }
9393 }];
9494}
9595
96+ //===----------------------------------------------------------------------===//
97+ // MapAttr
98+ //===----------------------------------------------------------------------===//
99+
96100def DLTI_MapAttr : DLTIAttr<"Map", [DLTIQueryInterface]> {
97101 let summary = "A mapping of DLTI-information by way of key-value pairs";
98102 let description = [{
@@ -106,18 +110,16 @@ def DLTI_MapAttr : DLTIAttr<"Map", [DLTIQueryInterface]> {
106110
107111 Consider the following flat encoding of a single-key dictionary
108112 ```
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>>
110114 ```
111115 versus nested maps, which make it possible to obtain sub-dictionaries of
112116 related information (with the following example making use of other
113117 attributes that also implement the `DLTIQueryInterface`):
114118 ```
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> >>>
121123 ```
122124
123125 With the flat encoding, the implied structure of the key is ignored, that is
@@ -132,14 +134,13 @@ def DLTI_MapAttr : DLTIAttr<"Map", [DLTIQueryInterface]> {
132134 `transform.dlti.query ["CPU","cache","L1","size_in_bytes"] at %op` gives
133135 back the first leaf value contained. To access the other leaf, we need to do
134136 `transform.dlti.query ["CPU","cache","L1d","size_in_bytes"] at %op`.
135- ```
136137 }];
137138 let parameters = (ins
138139 ArrayRefParameter<"DataLayoutEntryInterface", "">:$entries
139140 );
140141 let mnemonic = "map";
141142 let genVerifyDecl = 1;
142- let assemblyFormat = "`<` $entries `>`" ;
143+ let hasCustomAssemblyFormat = 1 ;
143144 let extraClassDeclaration = [{
144145 /// Returns the attribute associated with the key.
145146 FailureOr<Attribute> query(DataLayoutEntryKey key) {
@@ -167,20 +168,23 @@ def DLTI_TargetSystemSpecAttr :
167168 ```
168169 dlti.target_system_spec =
169170 #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>>
176177 ```
178+
179+ The verifier checks that keys are strings and pointed to values implement
180+ DLTI's TargetDeviceSpecInterface.
177181 }];
178182 let parameters = (ins
179- ArrayRefParameter<"DeviceIDTargetDeviceSpecPair", " ">:$entries
183+ ArrayRefParameter<"DataLayoutEntryInterface ">:$entries
180184 );
181185 let mnemonic = "target_system_spec";
182186 let genVerifyDecl = 1;
183- let assemblyFormat = "`<` $entries `>`" ;
187+ let hasCustomAssemblyFormat = 1 ;
184188 let extraClassDeclaration = [{
185189 /// Return the device specification that matches the given device ID
186190 std::optional<TargetDeviceSpecInterface>
@@ -189,16 +193,18 @@ def DLTI_TargetSystemSpecAttr :
189193
190194 /// Returns the attribute associated with the key.
191195 FailureOr<Attribute> query(DataLayoutEntryKey key) const {
192- return llvm::cast<mlir::TargetSystemSpecInterface>(*this).queryHelper(key);
196+ return :: llvm::cast<mlir::TargetSystemSpecInterface>(*this).queryHelper(key);
193197 }
194198 }];
195199 let extraClassDefinition = [{
196200 std::optional<TargetDeviceSpecInterface>
197201 $cppClass::getDeviceSpecForDeviceID(
198202 TargetSystemSpecInterface::DeviceID deviceID) {
199203 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;
202208 }
203209 return std::nullopt;
204210 }
@@ -219,21 +225,20 @@ def DLTI_TargetDeviceSpecAttr :
219225
220226 Example:
221227 ```
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>
224229 ```
225230 }];
226231 let parameters = (ins
227- ArrayRefParameter<"DataLayoutEntryInterface", "" >:$entries
232+ ArrayRefParameter<"DataLayoutEntryInterface">:$entries
228233 );
229234 let mnemonic = "target_device_spec";
230235 let genVerifyDecl = 1;
231- let assemblyFormat = "`<` $entries `>`" ;
236+ let hasCustomAssemblyFormat = 1 ;
232237
233238 let extraClassDeclaration = [{
234239 /// Returns the attribute associated with the key.
235240 FailureOr<Attribute> query(DataLayoutEntryKey key) const {
236- return llvm::cast<mlir::TargetDeviceSpecInterface>(*this).queryHelper(key);
241+ return :: llvm::cast<mlir::TargetDeviceSpecInterface>(*this).queryHelper(key);
237242 }
238243 }];
239244}
0 commit comments