tensorflow / mlir

"Multi-Level Intermediate Representation" Compiler Infrastructure
1.74k stars 259 forks source link

Results of Tutorial Toy Chapter 1 looks different from the description #158

Open kiszk opened 5 years ago

kiszk commented 5 years ago

When I run Tutorial Toy Chapter 1, I realized there are two differences from the description.
Should we address these differences? Or, is MLIR specification changed?

  1. Loc of BinOp is different: Should BinOp: * @ast.toy:6:14 be BinOp: * @ast.toy:6:12?
  2. VarDecl a<> @ast.toy:12:3 has no shape while the example has a shape like VarDecl a<2, 3> @test/ast.toy:11:3

Environment: Ubuntu 16.04.6 LTS on x86_64 g++ 7.4.0

$ git log | head -1
commit 17a31464cafceb74d06a907c6cc789567539e7be
$ pwd
/home/foo/llvm-project/build
$ cd ../llvm/projects/mlir/test/Examples/Toy/Ch1
$ ../../../../../../../build/bin/toyc-ch1 ast.toy -emit=ast
  Module:
    Function 
      Proto 'multiply_transpose' @ast.toy:5:1'
      Params: [a, b]
      Block {
        Return
          BinOp: * @ast.toy:6:14
            var: a @ast.toy:6:10
            Call 'transpose' [ @ast.toy:6:14
              var: b @ast.toy:6:24
            ]
      } // Block
    Function 
      Proto 'main' @ast.toy:9:1'
      Params: []
      Block {
        VarDecl a<> @ast.toy:12:3
          Literal: <2, 3>[ <3>[ 1.000000e+00, 2.000000e+00, 3.000000e+00], <3>[ 4.000000e+00, 5.000000e+00, 6.000000e+00]] @ast.toy:12:11
        VarDecl b<2, 3> @ast.toy:15:3
          Literal: <6>[ 1.000000e+00, 2.000000e+00, 3.000000e+00, 4.000000e+00, 5.000000e+00, 6.000000e+00] @ast.toy:15:17
        VarDecl c<> @ast.toy:18:3
          Call 'multiply_transpose' [ @ast.toy:18:11
            var: a @ast.toy:18:30
            var: b @ast.toy:18:33
          ]
        VarDecl d<> @ast.toy:21:3
          Call 'multiply_transpose' [ @ast.toy:21:11
            var: b @ast.toy:21:30
            var: a @ast.toy:21:33
          ]
        VarDecl e<> @ast.toy:24:3
          Call 'multiply_transpose' [ @ast.toy:24:11
            var: b @ast.toy:24:30
            var: c @ast.toy:24:33
          ]
        VarDecl e<> @ast.toy:27:3
          Call 'multiply_transpose' [ @ast.toy:27:11
            Call 'transpose' [ @ast.toy:27:30
              var: a @ast.toy:27:40
            ]
            var: c @ast.toy:27:44
          ]
      } // Block
$  cat ast.toy 
# RUN: toyc-ch1 %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 implicitly 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' @{{.*}}ast.toy:5:1'
# CHECK-NEXT:       Params: [a, b]
# CHECK-NEXT:       Block {
# CHECK-NEXT:         Retur
# CHECK-NEXT:           BinOp: * @{{.*}}ast.toy:6:14
# CHECK-NEXT:             var: a @{{.*}}ast.toy:6:10
# CHECK-NEXT:             Call 'transpose' [ @{{.*}}ast.toy:6:14
# CHECK-NEXT:               var: b @{{.*}}ast.toy:6:24
# CHECK-NEXT:             ]
# CHECK-NEXT:       } // Block
# CHECK-NEXT:     Function
# CHECK-NEXT:       Proto 'main' @{{.*}}ast.toy:9:1'
# CHECK-NEXT:       Params: []
# CHECK-NEXT:       Block {
# CHECK-NEXT:         VarDecl a<> @{{.*}}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]] @{{.*}}ast.toy:12:11
# CHECK-NEXT:         VarDecl b<2, 3> @{{.*}}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] @{{.*}}ast.toy:15:17
# CHECK-NEXT:         VarDecl c<> @{{.*}}ast.toy:18:3
# CHECK-NEXT:           Call 'multiply_transpose' [ @{{.*}}ast.toy:18:11
# CHECK-NEXT:             var: a @{{.*}}ast.toy:18:30
# CHECK-NEXT:             var: b @{{.*}}ast.toy:18:33
# CHECK-NEXT:           ]
# CHECK-NEXT:         VarDecl d<> @{{.*}}ast.toy:21:3
# CHECK-NEXT:           Call 'multiply_transpose' [ @{{.*}}ast.toy:21:11
# CHECK-NEXT:             var: b @{{.*}}ast.toy:21:30
# CHECK-NEXT:             var: a @{{.*}}ast.toy:21:33
# CHECK-NEXT:           ]
# CHECK-NEXT:         VarDecl e<> @{{.*}}ast.toy:24:3
# CHECK-NEXT:           Call 'multiply_transpose' [ @{{.*}}ast.toy:24:11
# CHECK-NEXT:             var: b @{{.*}}ast.toy:24:30
# CHECK-NEXT:             var: c @{{.*}}ast.toy:24:33
# CHECK-NEXT:           ]
# CHECK-NEXT:         VarDecl e<> @{{.*}}ast.toy:27:3
# CHECK-NEXT:           Call 'multiply_transpose' [ @{{.*}}ast.toy:27:11
# CHECK-NEXT:             Call 'transpose' [ @{{.*}}ast.toy:27:30
# CHECK-NEXT:               var: a @{{.*}}ast.toy:27:40
# CHECK-NEXT:             ]
# CHECK-NEXT:             var: c @{{.*}}ast.toy:27:44
# CHECK-NEXT:           ]
joker-eph commented 5 years ago

Thanks for the report! I would delay acting on this at the moment as in the next two weeks we are landing a major update to the whole tutorial.

kiszk commented 5 years ago

@joker-eph I see. Item 2 may come from the specification update of MLIR. On the other hand, item 1 looks obviously incorrect in the output. Should we find and solve the root cause in mlir module?

River707 commented 5 years ago

The location difference is to be expected because the ast.toy in the test directory has two additional lines to account for the lit test RUN line. The example in Ch-1.md just needs to be updated to have the explicit shape removed, i.e. it should match whatever ast.toy generates.