Mercurial > hg > CbC > CbC_llvm
diff mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc @ 207:2e18cbf3894f
LLVM12
author | Shinji KONO <kono@ie.u-ryukyu.ac.jp> |
---|---|
date | Tue, 08 Jun 2021 06:07:14 +0900 |
parents | 0572611fdcc8 |
children | 5f17cb93ff66 |
line wrap: on
line diff
--- a/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc Mon May 25 11:55:54 2020 +0900 +++ b/mlir/test/mlir-linalg-ods-gen/test-linalg-ods-gen.tc Tue Jun 08 06:07:14 2021 +0900 @@ -1,77 +1,208 @@ // RUN: mlir-linalg-ods-gen %s -gen-ods-decl=1 | FileCheck %s --check-prefix=ODS // RUN: mlir-linalg-ods-gen %s -gen-impl=1 | FileCheck %s --check-prefix=IMPL -// ODS-LABEL: def Test1Op : LinalgNamedStructured_Op<"test1", [ -// ODS-NEXT: NInputs<2> -// ODS-NEXT: NOutputs<1> -// ODS-NEXT: NamedStructuredOpTraits +// ODS-LABEL: def Test1Op : LinalgStructuredBase_Op<"test1", [ +// ODS-NEXT: AttrSizedOperandSegments +// ODS-NEXT: DeclareOpInterfaceMethods<MemoryEffectsOpInterface>, // ODS-NEXT: SingleBlockImplicitTerminator<"YieldOp"> // -// IMPL-LABEL: SmallVector<StringRef, 8> Test1Op::referenceIterators +// IMPL-LABEL: ArrayAttr Test1Op::iterator_types() { // IMPL: { {{.*}}Parallel{{.*}}, {{.*}}Reduction{{.*}} } // -// IMPL: SmallVector<AffineMap, 8> Test1Op::referenceIndexingMaps -// IMPL: AffineMap::get(2, 0, {d0, d1}, context), -// IMPL-NEXT: AffineMap::get(2, 0, {d1}, context), -// IMPL-NEXT: AffineMap::get(2, 0, {d0}, context) }; +// IMPL: ArrayAttr Test1Op::indexing_maps() { +// IMPL: auto s0 = getAffineSymbolExpr(0, context); (void)s0; +// IMPL-NEXT: auto s1 = getAffineSymbolExpr(1, context); (void)s1; +// IMPL-NEXT: auto map0 = AffineMap::get(2, 2, {d0, d1}, context); +// IMPL-NEXT: map0 = map0.replaceDimsAndSymbols({}, { s0, s1 }, 2, 0); +// IMPL-NEXT: map0 = simplifyAffineMap(map0); +// IMPL-NEXT: auto map1 = AffineMap::get(2, 2, {d1}, context); +// IMPL-NEXT: map1 = map1.replaceDimsAndSymbols({}, { s0, s1 }, 2, 0); +// IMPL-NEXT: map1 = simplifyAffineMap(map1); +// IMPL-NEXT: auto map2 = AffineMap::get(2, 2, {d0}, context); +// IMPL-NEXT: map2 = map2.replaceDimsAndSymbols({}, { s0, s1 }, 2, 0); +// IMPL-NEXT: map2 = simplifyAffineMap(map2); +// IMPL-NEXT: return {{.+}}.getAffineMapArrayAttr({ map0, map1, map2 }); // -// IMPL: void Test1Op::regionBuilder(Block &block) { +// IMPL: void Test1Op::regionBuilder(ImplicitLocOpBuilder &b, +// IMPL: Block &block, ValueRange captures) { // IMPL: Value [[a:.*]](args[0]), [[b:.*]](args[1]), [[c:.*]](args[2]); -// IMPL: Value [[d:.*]] = std_mulf([[a]], [[b]]); -// IMPL: Value [[e:.*]] = std_addf([[c]], [[d]]); -// IMPL: (linalg_yield(ValueRange{ [[e]] })); +// IMPL: Value [[d:.*]] = b.create<MulFOp>([[a]], [[b]]); +// IMPL: Value [[e:.*]] = b.create<AddFOp>([[c]], [[d]]); +// IMPL: b.create<linalg::YieldOp>(ValueRange{ [[e]] }); // ods_def<Test1Op> : def test1(A: f32(M, K), B: f32(K)) -> (C: f32(M)) { - C(m) = std_addf<k>(std_mulf(A(m, k), B(k))); + C(m) = AddFOp<k>(C(m), MulFOp(A(m, k), B(k))); } -// ODS-LABEL: def Test2Op : LinalgNamedStructured_Op<"test2", [ -// ODS-NEXT: NInputs<2> -// ODS-NEXT: NOutputs<1> -// ODS-NEXT: NamedStructuredOpTraits +// ODS-LABEL: def Test2Op : LinalgStructuredBase_Op<"test2", [ +// ODS-NEXT: AttrSizedOperandSegments +// ODS-NEXT: DeclareOpInterfaceMethods<MemoryEffectsOpInterface>, // ODS-NEXT: SingleBlockImplicitTerminator<"YieldOp"> // -// IMPL-LABEL: SmallVector<StringRef, 8> Test2Op::referenceIterators +// IMPL-LABEL: ArrayAttr Test2Op::iterator_types() { // IMPL: { {{.*}}Parallel{{.*}}, {{.*}}Parallel{{.*}}, {{.*}}Reduction{{.*}} } // -// IMPL: SmallVector<AffineMap, 8> Test2Op::referenceIndexingMaps -// IMPL: AffineMap::get(3, 0, {d0, d2}, context), -// IMPL-NEXT: AffineMap::get(3, 0, {d2, d1}, context), -// IMPL-NEXT: AffineMap::get(3, 0, {d0, d1}, context) }; +// IMPL: ArrayAttr Test2Op::indexing_maps() { +// IMPL: AffineMap::get(3, 3, {d0, d2}, context) +// IMPL: AffineMap::get(3, 3, {d2, d1}, context) +// IMPL: AffineMap::get(3, 3, {d0, d1}, context) // -// IMPL: Test2Op::regionBuilder(Block &block) { +// IMPL: Test2Op::regionBuilder(ImplicitLocOpBuilder &b, +// IMPL: Block &block, ValueRange captures) { // IMPL: Value [[a:.*]](args[0]), [[b:.*]](args[1]), [[c:.*]](args[2]); -// IMPL: Value [[d:.*]] = std_mulf([[a]], [[b]]); -// IMPL: Value [[e:.*]] = std_addf([[c]], [[d]]); -// IMPL: (linalg_yield(ValueRange{ [[e]] })); +// IMPL: Value [[d:.*]] = b.create<MulFOp>([[a]], [[b]]); +// IMPL: Value [[e:.*]] = b.create<AddFOp>([[c]], [[d]]); +// IMPL: b.create<linalg::YieldOp>(ValueRange{ [[e]] }); // ods_def<Test2Op> : def test2(A: f32(M, K), B: f32(K, N)) -> (C: f32(M, N)) { - C(m, n) = std_addf<k>(std_mulf(A(m, k), B(k, n))); + C(m, n) = AddFOp<k>(C(m, n), MulFOp(A(m, k), B(k, n))); } -// ODS-LABEL: def Test3Op : LinalgNamedStructured_Op<"test3", [ -// ODS-NEXT: NInputs<2> -// ODS-NEXT: NOutputs<1> -// ODS-NEXT: NamedStructuredOpTraits +// ODS-LABEL: def Test3Op : LinalgStructuredBase_Op<"test3", [ +// ODS-NEXT: AttrSizedOperandSegments +// ODS-NEXT: DeclareOpInterfaceMethods<MemoryEffectsOpInterface>, // ODS-NEXT: SingleBlockImplicitTerminator<"YieldOp"> // -// IMPL-LABEL: SmallVector<StringRef, 8> Test3Op::referenceIterators +// IMPL-LABEL: ArrayAttr Test3Op::iterator_types() { // IMPL: { {{.*}}Parallel{{.*}}, {{.*}}Parallel{{.*}}, {{.*}}Reduction{{.*}} } // -// IMPL: SmallVector<AffineMap, 8> Test3Op::referenceIndexingMaps -// IMPL: AffineMap::get(4, 0, {d0, d1, d3}, context), -// IMPL-NEXT: AffineMap::get(4, 0, {d3, d2}, context), -// IMPL-NEXT: AffineMap::get(4, 0, {d0, d1, d2}, context) }; +// IMPL: ArrayAttr Test3Op::indexing_maps() { +// IMPL: AffineMap::get(4, 4, {d0, d1, d3}, context) +// IMPL: AffineMap::get(4, 4, {d3, d2}, context) +// IMPL: AffineMap::get(4, 4, {d0, d1, d2}, context) // -// IMPL: Test3Op::regionBuilder(Block &block) { +// IMPL: Test3Op::regionBuilder(ImplicitLocOpBuilder &b, +// IMPL: Block &block, ValueRange captures) { // IMPL: Value [[a:.*]](args[0]), [[b:.*]](args[1]), [[c:.*]](args[2]); -// IMPL: Value [[d:.*]] = std_mulf([[a]], [[b]]); -// IMPL: Value [[e:.*]] = std_addf([[c]], [[d]]); -// IMPL: (linalg_yield(ValueRange{ [[e]] })); +// IMPL: Value [[d:.*]] = b.create<MulFOp>([[a]], [[b]]); +// IMPL: Value [[e:.*]] = b.create<AddFOp>([[c]], [[d]]); +// IMPL: b.create<linalg::YieldOp>(ValueRange{ [[e]] }); // ods_def<Test3Op> : def test3(A: f32(Batch, M, K), B: f32(K, N)) -> (C: f32(Batch, M, N)) { - C(b, m, n) = std_addf<k>(std_mulf(A(b, m, k), B(k, n))); + C(b, m, n) = AddFOp<k>(C(b, m, n), MulFOp(A(b, m, k), B(k, n))); +} + +// Test attribute definitions +// ODS-LABEL: def Test4Op +// ODS: F32ArrayAttr:$array_attr, +// ODS: F32Attr:$f32_attr, +// ODS: RankedF32ElementsAttr<[4]>:$fvec_attr, +// ODS: I32Attr:$i32_attr, +// ODS: I64Attr:$i64_attr, +// ODS: RankedI32ElementsAttr<[5, 6]>:$ivec_attr, +// ODS: OptionalAttr<F32Attr>:$optional_attr +// +// ODS: bool hasDynamicIndexingMaps(); +// ODS: LogicalResult verifyIndexingMapRequiredAttributes(); +// +// IMPL: bool Test4Op::hasDynamicIndexingMaps() { return true; } +// IMPL: LogicalResult Test4Op::verifyIndexingMapRequiredAttributes() +// IMPL: op->getAttrOfType<ArrayAttr>("array_attr") +// IMPL: op->getAttr("f32_attr") +// IMPL: op->getAttrOfType<DenseElementsAttr>("fvec_attr") +// IMPL: op->getAttr("i32_attr") +// IMPL: op->getAttr("i64_attr") +// IMPL: op->getAttrOfType<DenseElementsAttr>("ivec_attr") +// +ods_def<Test4Op> : +def test4(A: f32(Batch, M, K), B: f32(K, N)) -> (C: f32(Batch, M, N)) +attr( + f32_attr: f32, + i32_attr: i32, + i64_attr: i64, + fvec_attr: 4xf32, + ivec_attr: 5x6xi32, + array_attr : f32[], + optional_attr? : f32 +) { + C(b, m, n) = AddFOp<k>(C(b, m, n), MulFOp(A(b, m, k), B(k, n))); +} + +// Test attribute usage in affine expressions +// IMPL-LABEL: ArrayAttr Test5Op::indexing_maps() { +// IMPL: auto cst0 = getAffineConstantExpr(strides().getValue<int>({ 0 }), context); +// IMPL: auto cst1 = getAffineConstantExpr(strides().getValue<int>({ 1 }), context); +// IMPL: auto map0 = AffineMap::get(7, 9, {d0, d1 * s7 + d4, d2 * s8 + d5, d6}, context); +// IMPL: map0 = map0.replaceDimsAndSymbols({}, { s0, s1, s2, s3, s4, s5, s6, cst0, cst1 }, 7, 0); +// IMPL: map0 = simplifyAffineMap(map0); +// IMPL: auto map1 = AffineMap::get(7, 9, {d3, d4, d5, d6}, context); +// IMPL: map1 = map1.replaceDimsAndSymbols({}, { s0, s1, s2, s3, s4, s5, s6, cst0, cst1 }, 7, 0); +// IMPL: map1 = simplifyAffineMap(map1); +// IMPL: auto map2 = AffineMap::get(7, 7, {d0, d1, d2, d3}, context); +// IMPL: map2 = map2.replaceDimsAndSymbols({}, { s0, s1, s2, s3, s4, s5, s6, cst0, cst1 }, 7, 0); +// IMPL: map2 = simplifyAffineMap(map2); +// IMPL: return {{.+}}.getAffineMapArrayAttr({ map0, map1, map2 }); +// +ods_def<Test5Op>: +def test5(I: f32(N, H, W, C), K: f32(F, KH, KW, C)) -> (O: f32(N, H, W, F)) + attr(strides: 2xi32) { + O(n, h, w, f) = AddFOp<kh, kw>( + MulFOp(AddFOp(I(n, h * strides[0] + kh, w * strides[1] + kw, c), + I(n, h * strides[0] + kh, w * strides[1] + kw, c)), + K(f, kh, kw, c))); } + +// Test documentation +// ODS-LABEL: def Test6Op +// ODS: let summary = [{ My magic op. }]; +// ODS-NEXT: let description = [{ +// ODS-NEXT: It has two inputs. +// ODS-NEXT: It has one output. +// ODS-NEXT: }]; +// +ods_def<Test6Op>: +def test6(A: f32(M, K), B: f32(K)) -> (C: f32(M)) +""" +My magic op. + +It has two inputs. +It has one output. +""" +{ + C(m) = AddFOp<k>(C(m), MulFOp(A(m, k), B(k))); +} + +// Test attribute builder +// ODS-LABEL: def Test7Op +// ODS: OpBuilder< +// ODS: (ins "TypeRange":$resultTensorTypes, "ValueRange":$inputs, +// ODS: "ValueRange":$outputs, "Attribute":$attr_a, "Attribute":$attr_b) +// ODS: $_state.addAttribute("attr_a", attr_a); +// ODS: $_state.addAttribute("attr_b", attr_b); +// +ods_def<Test7Op>: +def test7(A: f32(M, K), B: f32(K)) -> (C: f32(M)) + attr(attr_a: f32, attr_b: 4xi32) +{ + C(m) = AddFOp<k>(C(m), MulFOp(A(m, k), B(k))); +} + +// Test output arg order. +// IMPL-LABEL: void Test8Op::regionBuilder(ImplicitLocOpBuilder &b, +// IMPL: Block &block, ValueRange captures) { +// IMPL: Value [[a:.*]](args[0]), [[b:.*]](args[1]), [[c:.*]](args[2]); +// IMPL: Value [[d:.*]] = b.create<MulFOp>([[a]], [[b]]); +// IMPL: Value [[e:.*]] = b.create<SubFOp>([[d]], [[c]]); +// IMPL: b.create<linalg::YieldOp>(ValueRange{ [[e]] }); +ods_def<Test8Op>: +def test8(A: f32(M, K), B: f32(K)) -> (C: f32(M)) +{ + C(m) = SubFOp<k>(MulFOp(A(m, k), B(k)), C(m)); +} + +// Test shape-only operand. +// IMPL-LABEL: ArrayAttr Test9Op::indexing_maps() { +// IMPL: auto map0 = AffineMap::get(2, 2, {d0, d1}, context); +// IMPL: auto map1 = AffineMap::get(2, 2, {d1}, context); +// IMPL: auto map2 = AffineMap::get(2, 2, {d0}, context); +// IMPL-LABEL: void Test9Op::regionBuilder(ImplicitLocOpBuilder &b, +// IMPL: Block &block, ValueRange captures) { +// IMPL: Value [[a:.*]](args[0]), [[c:.*]](args[2]); +ods_def<Test9Op>: +def test9(A: f32(M, K), B: f32(K)) -> (C: f32(M)) +{ + C(m) = AddFOp<k>(C(m), A(m, k)); +}