summaryrefslogtreecommitdiffstats
path: root/mlir/test/Examples
diff options
context:
space:
mode:
authorMehdi Amini <aminim@google.com>2019-04-04 18:31:31 -0700
committerMehdi Amini <joker.eph@gmail.com>2019-04-05 07:42:56 -0700
commitd33a9dcc73252ee129c58bd975f43e7e7b198050 (patch)
tree0766451ae51dcba6827c0f6e8b78714b28264145 /mlir/test/Examples
parent0a6cb916158c80762bf9fe497ed31cd983995bd3 (diff)
downloadbcm5719-llvm-d33a9dcc73252ee129c58bd975f43e7e7b198050.tar.gz
bcm5719-llvm-d33a9dcc73252ee129c58bd975f43e7e7b198050.zip
Add Chapter 4 for the Toy tutorial: shape inference, function specialization, and basic combines
-- PiperOrigin-RevId: 242050514
Diffstat (limited to 'mlir/test/Examples')
-rw-r--r--mlir/test/Examples/Toy/Ch4/ast.toy73
-rw-r--r--mlir/test/Examples/Toy/Ch4/codegen.toy32
-rw-r--r--mlir/test/Examples/Toy/Ch4/invalid.mlir11
-rw-r--r--mlir/test/Examples/Toy/Ch4/scalar.toy14
-rw-r--r--mlir/test/Examples/Toy/Ch4/transpose_transpose.toy19
-rw-r--r--mlir/test/Examples/Toy/Ch4/trivialReshape.toy24
6 files changed, 173 insertions, 0 deletions
diff --git a/mlir/test/Examples/Toy/Ch4/ast.toy b/mlir/test/Examples/Toy/Ch4/ast.toy
new file mode 100644
index 00000000000..dbc9d927abe
--- /dev/null
+++ b/mlir/test/Examples/Toy/Ch4/ast.toy
@@ -0,0 +1,73 @@
+# RUN: toyc-ch4 %s -emit=ast 2>&1 | FileCheck %s
+
+
+# User defined generic function that operates solely on
+def multiply_transpose(a, b) {
+ return a * transpose(b);
+}
+
+def main() {
+ # Define a variable `a` with shape <2, 3>, initialized with the literal value.
+ # The shape is inferred from the supplied literal.
+ var a = [[1, 2, 3], [4, 5, 6]];
+ # b is identical to a, the literal array is implicitely reshaped: defining new
+ # variables is the way to reshape arrays (element count must match).
+ var b<2, 3> = [1, 2, 3, 4, 5, 6];
+ # This call will specialize `multiply_transpose` with <2, 3> for both
+ # arguments and deduce a return type of <2, 2> in initialization of `c`.
+ var c = multiply_transpose(a, b);
+ # A second call to `multiply_transpose` with <2, 3> for both arguments will
+ # reuse the previously specialized and inferred version and return `<2, 2>`
+ var d = multiply_transpose(b, a);
+ # A new call with `<2, 2>` for both dimension will trigger another
+ # specialization of `multiply_transpose`.
+ var e = multiply_transpose(b, c);
+ # Finally, calling into `multiply_transpose` with incompatible shape will
+ # trigger a shape inference error.
+ var e = multiply_transpose(transpose(a), c);
+}
+
+
+# CHECK: Module:
+# CHECK-NEXT: Function
+# CHECK-NEXT: Proto 'multiply_transpose' @{{.*}}Toy/Ch4/ast.toy:5:1'
+# CHECK-NEXT: Params: [a, b]
+# CHECK-NEXT: Block {
+# CHECK-NEXT: Retur
+# CHECK-NEXT: BinOp: * @{{.*}}Toy/Ch4/ast.toy:6:14
+# CHECK-NEXT: var: a @{{.*}}Toy/Ch4/ast.toy:6:10
+# CHECK-NEXT: Call 'transpose' [ @{{.*}}Toy/Ch4/ast.toy:6:14
+# CHECK-NEXT: var: b @{{.*}}Toy/Ch4/ast.toy:6:24
+# CHECK-NEXT: ]
+# CHECK-NEXT: } // Block
+# CHECK-NEXT: Function
+# CHECK-NEXT: Proto 'main' @{{.*}}Toy/Ch4/ast.toy:9:1'
+# CHECK-NEXT: Params: []
+# CHECK-NEXT: Block {
+# CHECK-NEXT: VarDecl a<> @{{.*}}Toy/Ch4/ast.toy:12:3
+# CHECK-NEXT: Literal: <2, 3>[ <3>[ 1.000000e+00, 2.000000e+00, 3.000000e+00], <3>[ 4.000000e+00, 5.000000e+00, 6.000000e+00]] @{{.*}}Toy/Ch4/ast.toy:12:11
+# CHECK-NEXT: VarDecl b<2, 3> @{{.*}}Toy/Ch4/ast.toy:15:3
+# CHECK-NEXT: Literal: <6>[ 1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00] @{{.*}}Toy/Ch4/ast.toy:15:17
+# CHECK-NEXT: VarDecl c<> @{{.*}}Toy/Ch4/ast.toy:18:3
+# CHECK-NEXT: Call 'multiply_transpose' [ @{{.*}}Toy/Ch4/ast.toy:18:11
+# CHECK-NEXT: var: a @{{.*}}Toy/Ch4/ast.toy:18:30
+# CHECK-NEXT: var: b @{{.*}}Toy/Ch4/ast.toy:18:33
+# CHECK-NEXT: ]
+# CHECK-NEXT: VarDecl d<> @{{.*}}Toy/Ch4/ast.toy:21:3
+# CHECK-NEXT: Call 'multiply_transpose' [ @{{.*}}Toy/Ch4/ast.toy:21:11
+# CHECK-NEXT: var: b @{{.*}}Toy/Ch4/ast.toy:21:30
+# CHECK-NEXT: var: a @{{.*}}Toy/Ch4/ast.toy:21:33
+# CHECK-NEXT: ]
+# CHECK-NEXT: VarDecl e<> @{{.*}}Toy/Ch4/ast.toy:24:3
+# CHECK-NEXT: Call 'multiply_transpose' [ @{{.*}}Toy/Ch4/ast.toy:24:11
+# CHECK-NEXT: var: b @{{.*}}Toy/Ch4/ast.toy:24:30
+# CHECK-NEXT: var: c @{{.*}}Toy/Ch4/ast.toy:24:33
+# CHECK-NEXT: ]
+# CHECK-NEXT: VarDecl e<> @{{.*}}Toy/Ch4/ast.toy:27:3
+# CHECK-NEXT: Call 'multiply_transpose' [ @{{.*}}Toy/Ch4/ast.toy:27:11
+# CHECK-NEXT: Call 'transpose' [ @{{.*}}Toy/Ch4/ast.toy:27:30
+# CHECK-NEXT: var: a @{{.*}}Toy/Ch4/ast.toy:27:40
+# CHECK-NEXT: ]
+# CHECK-NEXT: var: c @{{.*}}Toy/Ch4/ast.toy:27:44
+# CHECK-NEXT: ]
+
diff --git a/mlir/test/Examples/Toy/Ch4/codegen.toy b/mlir/test/Examples/Toy/Ch4/codegen.toy
new file mode 100644
index 00000000000..c0497a1851a
--- /dev/null
+++ b/mlir/test/Examples/Toy/Ch4/codegen.toy
@@ -0,0 +1,32 @@
+# RUN: toyc-ch4 %s -emit=mlir 2>&1 | FileCheck %s
+
+# User defined generic function that operates on unknown shaped arguments
+def multiply_transpose(a, b) {
+ return a * transpose(b);
+}
+
+def main() {
+ var a<2, 3> = [[1, 2, 3], [4, 5, 6]];
+ var b<2, 3> = [1, 2, 3, 4, 5, 6];
+ var c = multiply_transpose(a, b);
+ var d = multiply_transpose(b, a);
+ print(d);
+}
+
+# CHECK-LABEL: func @multiply_transpose(%arg0: !toy<"array">, %arg1: !toy<"array">)
+# CHECK-NEXT: attributes {toy.generic: true} {
+# CHECK-NEXT: %0 = "toy.transpose"(%arg1) : (!toy<"array">) -> !toy<"array">
+# CHECK-NEXT: %1 = "toy.mul"(%arg0, %0) : (!toy<"array">, !toy<"array">) -> !toy<"array">
+# CHECK-NEXT: "toy.return"(%1) : (!toy<"array">) -> ()
+# CHECK-NEXT: }
+
+# CHECK-LABEL: func @main() {
+# CHECK-NEXT: %0 = "toy.constant"() {value: dense<tensor<2x3xf64>, {{\[\[}}1.000000e+00, 2.000000e+00, 3.000000e+00], [4.000000e+00, 5.000000e+00, 6.000000e+00]]>} : () -> !toy<"array<2, 3>">
+# CHECK-NEXT: %1 = "toy.reshape"(%0) : (!toy<"array<2, 3>">) -> !toy<"array<2, 3>">
+# CHECK-NEXT: %2 = "toy.constant"() {value: dense<tensor<6xf64>, [1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00]>} : () -> !toy<"array<6>">
+# CHECK-NEXT: %3 = "toy.reshape"(%2) : (!toy<"array<6>">) -> !toy<"array<2, 3>">
+# CHECK-NEXT: %4 = "toy.generic_call"(%1, %3) {callee: "multiply_transpose"} : (!toy<"array<2, 3>">, !toy<"array<2, 3>">) -> !toy<"array">
+# CHECK-NEXT: %5 = "toy.generic_call"(%3, %1) {callee: "multiply_transpose"} : (!toy<"array<2, 3>">, !toy<"array<2, 3>">) -> !toy<"array">
+# CHECK-NEXT: "toy.print"(%5) : (!toy<"array">) -> ()
+# CHECK-NEXT: "toy.return"() : () -> ()
+
diff --git a/mlir/test/Examples/Toy/Ch4/invalid.mlir b/mlir/test/Examples/Toy/Ch4/invalid.mlir
new file mode 100644
index 00000000000..0e33397730e
--- /dev/null
+++ b/mlir/test/Examples/Toy/Ch4/invalid.mlir
@@ -0,0 +1,11 @@
+// RUN: not toyc-ch4 %s -emit=mlir 2>&1
+
+
+// This IR is not "valid":
+// - toy.print should not return a value.
+// - toy.print should take an argument.
+// - There should be a block terminator.
+// This all round-trip since this is opaque for MLIR.
+func @main() {
+ %0 = "toy.print"() : () -> !toy<"array<2, 3>">
+}
diff --git a/mlir/test/Examples/Toy/Ch4/scalar.toy b/mlir/test/Examples/Toy/Ch4/scalar.toy
new file mode 100644
index 00000000000..51fbcaf8b7a
--- /dev/null
+++ b/mlir/test/Examples/Toy/Ch4/scalar.toy
@@ -0,0 +1,14 @@
+# RUN: toyc-ch4 %s -emit=mlir 2>&1 | FileCheck %s
+
+def main() {
+ var a<2, 2> = 5.5;
+ print(a);
+}
+
+# CHECK-LABEL: func @main() {
+# CHECK-NEXT: %0 = "toy.constant"() {value: dense<tensor<1xf64>, [5.500000e+00]>} : () -> !toy<"array<1>">
+# CHECK-NEXT: %1 = "toy.reshape"(%0) : (!toy<"array<1>">) -> !toy<"array<2, 2>">
+# CHECK-NEXT: "toy.print"(%1) : (!toy<"array<2, 2>">) -> ()
+# CHECK-NEXT: "toy.return"() : () -> ()
+# CHECK-NEXT: }
+
diff --git a/mlir/test/Examples/Toy/Ch4/transpose_transpose.toy b/mlir/test/Examples/Toy/Ch4/transpose_transpose.toy
new file mode 100644
index 00000000000..31399eee53f
--- /dev/null
+++ b/mlir/test/Examples/Toy/Ch4/transpose_transpose.toy
@@ -0,0 +1,19 @@
+# RUN: toyc-ch4 %s -emit=mlir 2>&1 | FileCheck %s
+# RUN: toyc-ch4 %s -emit=mlir -opt 2>&1 | FileCheck %s --check-prefix=OPT
+
+def transpose_transpose(x) {
+ return transpose(transpose(x));
+}
+
+def main() {
+ print(transpose_transpose([[1, 2], [3, 4]]));
+}
+
+#CHECK-LABEL: func @transpose_transpose
+#CHECK: transpose
+#CHECK-LABEL: main
+
+
+#OPT-LABEL: func @transpose_transpose
+#OPT-NOT: transpose
+
diff --git a/mlir/test/Examples/Toy/Ch4/trivialReshape.toy b/mlir/test/Examples/Toy/Ch4/trivialReshape.toy
new file mode 100644
index 00000000000..c7a805d89ef
--- /dev/null
+++ b/mlir/test/Examples/Toy/Ch4/trivialReshape.toy
@@ -0,0 +1,24 @@
+# RUN: toyc-ch4 %s -emit=mlir 2>&1 | FileCheck %s
+# RUN: toyc-ch4 %s -emit=mlir -opt 2>&1 | FileCheck %s --check-prefix=OPT
+
+# We expect no reshape in this function with optimizations enabled
+def foo(a) {
+ var b<2,1> = a;
+ var c<2,1> = b;
+ print(c);
+}
+
+def main() {
+ var a<2, 1> = [1, 2];
+ foo(a);
+}
+
+# without optimizations, match the reshape
+#CHECK-LABEL: func @foo
+#CHECK: reshape
+#CHECK-LABEL: main
+
+# with optimizations, ensure no reshape
+#OPT-LABEL: main
+#OPT-LABEL: func @foo_2x1
+#OPT-NOT: reshape
OpenPOWER on IntegriCloud