1 # RUN: mlir-linalg-ods-yaml-gen %s --o-ods-decl=- | FileCheck %s --check-prefix=ODS
2 # RUN: mlir-linalg-ods-yaml-gen %s --o-impl=- | FileCheck %s --check-prefix=IMPL
4 # @linalg_structured_op
5 # def test1(O=TensorDef(T, S.M, S.N, output=True),
6 # cast=TypeFnAttrDef(default=TypeFn.cast_signed)):
9 # Detailed description.
11 # O[D.m, D.n] = cast(T, const(42)) + cast(T, index(D.n))
14 metadata: !LinalgOpMetadata
16 cpp_class_name: Test1Op
21 structured_op: !LinalgStructuredOpConfig
23 - !LinalgOperandDefConfig
27 shape_map: affine_map<()[s0, s1] -> (s0, s1)>
28 - !LinalgOperandDefConfig
31 default_fn: cast_signed
32 indexing_maps: !LinalgIndexingMapsConfig
34 - affine_map<(d0, d1)[s0, s1] -> (d0, d1)>
41 value: !ScalarExpression
53 scalar_const: '42 : i64'
63 # ODS-LABEL: def Test1Op : LinalgStructuredBase_Op<"test1"
65 # ODS: let summary = [{Title.}];
66 # ODS-NEXT: let description = [{Detailed description.}];
68 # ODS: let arguments =
69 # ODS-NEXT: Variadic<AnyType>:$inputs,
70 # ODS-NEXT: Variadic<AnyShaped>:$outputs,
71 # ODS-NEXT: DefaultValuedOptionalAttr<TypeFnAttr, "TypeFn::cast_signed">:$cast
74 # ODS: (ins "TypeRange":$resultTensorTypes, "ValueRange":$inputs,
75 # ODS-NEXT: "ValueRange":$outputs,
76 # ODS-NEXT: CArg<"ArrayRef<NamedAttribute>", "{}">:$attributes),
78 # ODS: (ins "TypeRange":$resultTensorTypes, "ValueRange":$inputs,
79 # ODS-NEXT: "ValueRange":$outputs, "Attribute":$cast,
80 # ODS-NEXT: CArg<"ArrayRef<NamedAttribute>", "{}">:$attributes),
82 # ODS: buildStructuredOp($_builder, $_state, resultTensorTypes,
83 # ODS-NEXT: attributes, Test1Op::getRegionBuilder())
85 # ODS: MutableOperandRange getDpsInitsMutable() {
86 # ODS-NEXT: return getOutputsMutable()
89 # IMPL-LABEL: void Test1Op::regionBuilder(ImplicitLocOpBuilder &b,
90 # IMPL-NEXT: Block &block, ArrayRef<NamedAttribute> attrs)
91 # IMPL: TypeFn castVal = TypeFn::cast_signed;
92 # IMPL-NEXT: auto castIter = llvm::find_if(attrs, [&](const NamedAttribute &attr) {
93 # IMPL-NEXT: return attr.getName() == "cast"; });
94 # IMPL-NEXT: if (castIter != attrs.end()) {
95 # IMPL-NEXT: if (auto attr = llvm::dyn_cast<TypeFnAttr>(castIter->getValue()))
96 # IMPL-NEXT: castVal = attr.getValue();
99 # IMPL: Value [[VAL0:[a-z0-9]+]] = helper.constant("42 : i64");
100 # IMPL-DAG: Value [[VAL1:[a-z0-9]+]] = helper.buildTypeFn(castVal, block.getArgument(0).getType(), [[VAL0]]);
101 # IMPL-DAG: Value [[VAL2:[a-z0-9]+]] = helper.index(1);
102 # IMPL-DAG: Value [[VAL3:[a-z0-9]+]] = helper.buildTypeFn(castVal, block.getArgument(0).getType(), [[VAL2]]);
103 # IMPL-DAG: Value [[VAL4:[a-z0-9]+]] = helper.buildBinaryFn(BinaryFn::add, [[VAL1]], [[VAL3]]);
106 # @linalg_structured_op
107 # def test2(I=TensorDef(T, S.M, S.N),
108 # O=TensorDef(T, S.M, S.N, output=True),
109 # strides=IndexAttrDef(S.SM, S.SN, default=[1, 2])):
112 # Detailed description.
114 # O[D.m, D.n] = I[D.n * S.SM, D.m * S.SN]
117 metadata: !LinalgOpMetadata
119 cpp_class_name: Test2Op
123 Detailed description.
124 structured_op: !LinalgStructuredOpConfig
126 - !LinalgOperandDefConfig
130 shape_map: affine_map<()[s0, s1, s2, s3] -> (s0, s1)>
131 - !LinalgOperandDefConfig
135 shape_map: affine_map<()[s0, s1, s2, s3] -> (s0, s1)>
136 - !LinalgOperandDefConfig
139 index_attr_map: affine_map<()[s0, s1, s2, s3] -> (s2, s3)>
143 indexing_maps: !LinalgIndexingMapsConfig
144 static_indexing_maps:
145 - affine_map<(d0, d1)[s0, s1, s2, s3] -> (d1 * s2, d0 * s3)>
146 - affine_map<(d0, d1)[s0, s1, s2, s3] -> (d0, d1)>
153 value: !ScalarExpression
156 # ODS-LABEL: def Test2Op : LinalgStructuredBase_Op<"test2"
158 # ODS: let arguments =
159 # ODS-NEXT: Variadic<AnyType>:$inputs,
160 # ODS-NEXT: Variadic<AnyShaped>:$outputs,
161 # ODS-NEXT: DefaultValuedOptionalAttr<RankedI64ElementsAttr<[2]>
162 # ODS-SAME: "{ static_cast<int64_t>(1), static_cast<int64_t>(2) }">:$strides
164 # ODS: "Attribute":$strides
165 # ODS: $_state.addAttribute("strides", strides);
167 # ODS: bool hasDynamicIndexingMaps();
168 # ODS-NEXT: LogicalResult verifyIndexingMapRequiredAttributes();
170 # IMPL: getSymbolBindings(Test2Op self)
171 # IMPL: cst2 = self.getStrides().getValues<int64_t>()[0];
172 # IMPL-NEXT: getAffineConstantExpr(cst2, context)
173 # IMPL: cst3 = self.getStrides().getValues<int64_t>()[1];
174 # IMPL-NEXT: getAffineConstantExpr(cst3, context)
176 # IMPL: Test2Op::getIndexingMaps()
177 # IMPL: = getSymbolBindings(*this);
178 # IMPL: "affine_map<(d0, d1)[s0, s1, s2, s3] -> (d1 * s2, d0 * s3)>"
179 # IMPL: "affine_map<(d0, d1)[s0, s1, s2, s3] -> (d0, d1)>"
181 # IMPL: Test2Op::getNumRegionArgs() { return 2; }
183 # IMPL: Test2Op::hasDynamicIndexingMaps() { return true; }
184 # IMPL: Test2Op::verifyIndexingMapRequiredAttributes()
185 # IMPL: auto attr = op->getAttrOfType<DenseElementsAttr>("strides")
186 # IMPL: "incorrect element type for index attribute 'strides'"
187 # IMPL: "incorrect shape for index attribute 'strides'"
188 # IMPL: void Test2Op::regionBuilder(ImplicitLocOpBuilder &b,
189 # IMPL-NEXT: Block &block, ArrayRef<NamedAttribute> attrs)
190 # IMPL-NEXT: assert(2 > 0 && block.getNumArguments() == 2 &&
192 # IMPL: yields.push_back(block.getArgument(0));
194 # @linalg_structured_op
195 # def test3(value=ScalarDef(T1),
196 # O=TensorDef(U, output=True)):
199 # Detailed description.
201 # O[None] = TypeFn.cast_signed(U, value)
204 metadata: !LinalgOpMetadata
206 cpp_class_name: Test3Op
210 Detailed description.
211 structured_op: !LinalgStructuredOpConfig
213 - !LinalgOperandDefConfig
217 - !LinalgOperandDefConfig
221 shape_map: affine_map<() -> ()>
222 indexing_maps: !LinalgIndexingMapsConfig
223 static_indexing_maps:
224 - affine_map<() -> ()>
225 - affine_map<() -> ()>
230 value: !ScalarExpression
239 # IMPL: Test3Op::getIteratorTypesArray() {
240 # IMPL-NEXT: int64_t rank = getRank(getDpsInitOperand(0));
242 # IMPL: Test3Op::getIndexingMaps() {
243 # IMPL-NEXT: MLIRContext *context = getContext();
244 # IMPL-NEXT: AffineMap scalarMap = AffineMap::get(getNumParallelLoops(), 0, context);
245 # IMPL-NEXT: AffineMap tensorMap = AffineMap::getMultiDimIdentityMap(
247 # @linalg_structured_op
248 # def test4(O=TensorDef(T, S.M, S.N, output=True),
249 # unary_fun=UnaryFnAttrDef(default=UnaryFn.exp),
250 # binary_fun=BinaryFnAttrDef(default=BinaryFn.add)):
253 # Detailed description.
255 # O[D.m, D.n] = binary_fun(unary_fun(O[D.m, D.n]), O[D.m, D.n])
258 metadata: !LinalgOpMetadata
260 cpp_class_name: Test4Op
264 Detailed description.
265 structured_op: !LinalgStructuredOpConfig
267 - !LinalgOperandDefConfig
271 shape_map: affine_map<()[s0, s1] -> (s0, s1)>
272 - !LinalgOperandDefConfig
276 - !LinalgOperandDefConfig
280 indexing_maps: !LinalgIndexingMapsConfig
281 static_indexing_maps:
282 - affine_map<(d0, d1)[s0, s1] -> (d0, d1)>
289 value: !ScalarExpression
292 attr_name: binary_fun
304 # ODS-LABEL: def Test4Op : LinalgStructuredBase_Op<"test4"
306 # ODS: let arguments =
307 # ODS-NEXT: Variadic<AnyType>:$inputs,
308 # ODS-NEXT: Variadic<AnyShaped>:$outputs,
309 # ODS-NEXT: DefaultValuedOptionalAttr<UnaryFnAttr, "UnaryFn::exp">:$unary_fun,
310 # ODS-NEXT: DefaultValuedOptionalAttr<BinaryFnAttr, "BinaryFn::add">:$binary_fun
312 # ODS: "Attribute":$unary_fun, "Attribute":$binary_fun,
314 # ODS: $_state.addAttribute("unary_fun", unary_fun)
315 # ODS-NEXT: $_state.addAttribute("binary_fun", binary_fun)
317 # IMPL-LABEL: void Test4Op::regionBuilder(ImplicitLocOpBuilder &b,
318 # IMPL-NEXT: Block &block, ArrayRef<NamedAttribute> attrs)
319 # IMPL: UnaryFn unary_funVal = UnaryFn::exp
320 # IMPL: BinaryFn binary_funVal = BinaryFn::add
322 # IMPL: Value [[VAL0:[a-z0-9]+]] = helper.buildUnaryFn(unary_funVal, block.getArgument(0))
323 # IMPL-NEXT: Value [[VAL1:[a-z0-9]+]] = helper.buildBinaryFn(binary_funVal, [[VAL0]], block.getArgument(0))
324 # IMPL-NEXT: yields.push_back([[VAL1]])
326 # @linalg_structured_op
327 # def test5(value=ScalarDef(T1), O=TensorDef(U, output=True)):
330 # Detailed description.
332 # implements(FillOpInterface)
333 # defines(Canonicalizer)
334 # O[None] = TypeFn.cast(U, value)
337 metadata: !LinalgOpMetadata
339 cpp_class_name: Test5Op
343 Detailed description.
345 - LinalgFillOpInterface
348 structured_op: !LinalgStructuredOpConfig
350 - !LinalgOperandDefConfig
354 - !LinalgOperandDefConfig
358 shape_map: affine_map<() -> ()>
359 indexing_maps: !LinalgIndexingMapsConfig
360 static_indexing_maps:
361 - affine_map<() -> ()>
362 - affine_map<() -> ()>
367 value: !ScalarExpression
376 # ODS-LABEL: def Test5Op : LinalgStructuredBase_Op<"test5"
377 # ODS-NEXT: /*extraInterfaces=*/[LinalgFillOpInterface])>
379 # ODS: let hasCanonicalizer = 1;