Exemplo n.º 1
0
    def testTwoOutputs(self):
        I = Tensor(LogicalShape(plaidml.DType.FLOAT32, [3]), name='I')
        program1 = Program('two_outputs', [I, I])
        self.assertMultiLineEqual(
            str(program1), '''function (
  I[I_0]
) -> (
  _X1,
  _X0
) {
  _X0 = ident(I);
  _X1 = ident(I);
}
''')
        outputs = plaidml_exec.run(program1, [(I, np.array([(1, 2, 3)]))])
        self.assertEqual(outputs[0].tolist(), [1, 2, 3])
        self.assertEqual(outputs[1].tolist(), [1, 2, 3])

        O1 = I
        O2 = I
        program2 = Program('two_outputs', [O1, O2])
        self.assertMultiLineEqual(str(program1), str(program2))

        outputs = plaidml_exec.run(program2, [(I, np.array([(1, 2, 3)]))])
        self.assertEqual(outputs[0].tolist(), [1, 2, 3])
        self.assertEqual(outputs[1].tolist(), [1, 2, 3])
Exemplo n.º 2
0
    def test_identity(self):
        I = Tensor(LogicalShape(plaidml.DType.FLOAT32, [3]), name='I')
        program = Program('identity', [I])
        if USE_MLIR():
            self.assertMultiLineEqual(
                str(program), '''

module {
  func @identity(%arg0: tensor<3x!eltwise.fp32> {tile.name = "I"}) -> tensor<3x!eltwise.fp32> {
    %0 = "eltwise.ident"(%arg0) {type = !eltwise.fp32} : (tensor<3x!eltwise.fp32>) -> tensor<3x!eltwise.fp32>
    return %0 : tensor<3x!eltwise.fp32>
  }
}
''')
        else:
            self.assertMultiLineEqual(
                str(program), '''function (
  I[I_0]
) -> (
  _X0
) {
  _X0 = ident(I);
}
''')
        outputs = plaidml_exec.run(program, [(I, np.array([(1, 2, 3)]))])
        self.assertEqual(outputs[0].tolist(), [1, 2, 3])
Exemplo n.º 3
0
    def testAssignmentExceptions(self):
        A = Tensor(LogicalShape(plaidml.DType.FLOAT32, [5, 1]), name='A')
        B = Tensor(LogicalShape(plaidml.DType.FLOAT32, [1, 5]), name='B')
        L, M, N = TensorDims(3)
        i, j, k = TensorIndexes(3)
        A.bind_dims(L, M)
        B.bind_dims(M, N)
        O = TensorOutput(L, N)
        O[i, j] = A[i, k] * B[k, j]
        program = Program('assignment_non_exception', [O])
        self.assertMultiLineEqual(
            str(program), '''function (
  A[A_0, A_1],
  B[B_0, B_1]
) -> (
  _X0
) {
  _X0[x0, x2 : 5, 5] = =(A[x0, x1] * B[x1, x2]);
}
''')
        outputs = plaidml_exec.run(program, [(A, np.array([[1], [2], [3], [4], [5]])),
                                             (B, np.array([1, 2, 3, 4, 5]))])
        self.assertEqual(outputs[0].tolist(),
                         [[1., 2., 3., 4., 5.], [2., 4., 6., 8., 10.], [3., 6., 9., 12., 15.],
                          [4., 8., 12., 16., 20.], [5., 10., 15., 20., 25.]])

        O = TensorOutput(L, N)
        O[i, j] = B[i, k] * A[k, j]
        with self.assertRaises(plaidml.Error) as cm:
            program = Program('assignment_exception', [O])
        self.assertTrue("illegal assignment aggregation" in str(cm.exception))
Exemplo n.º 4
0
    def testFunkyLayerNames(self):
        '''Exercises fix for plaidml bug #241

        Now that we emit keras layer names as 'pid' attribute values, in order
        to help link tile code back to its origin while debugging, we must
        reformat those names as valid tile identifiers. If we are doing that,
        this test will pass, otherwise we'll get a syntax error.'''

        I = Tensor(LogicalShape(plaidml.DType.FLOAT32, [3]), name='I')
        K = Tensor(LogicalShape(plaidml.DType.FLOAT32, [3]), name='K')
        i, j = TensorIndexes(2)
        O = TensorOutput(5)
        O[i] += (I[(i - j + 1) // 2] * K[j])
        program = Program('this-is-not an identifier', [O])
        self.assertMultiLineEqual(
            str(program), '''function (
  I[I_0],
  K[K_0]
) -> (
  _X0
) {
  _X0[x0 : 5] = +(I[1/2 + 1/2*x0 - 1/2*x1] * K[x1]);
}
''')
        outputs = plaidml_exec.run(program, [(I, np.array([1, 2, 3])), (K, np.array([1, 2, 3]))])
        self.assertEqual(outputs[0].tolist(), [2, 5, 4, 9, 6])
Exemplo n.º 5
0
    def test_funky_names(self):
        '''Exercises fix for plaidml bug #241

        Now that we emit keras layer names as 'pid' attribute values, in order
        to help link tile code back to its origin while debugging, we must
        reformat those names as valid tile identifiers. If we are doing that,
        this test will pass, otherwise we'll get a syntax error.'''

        I = Tensor(LogicalShape(plaidml.DType.FLOAT32, [3]), name='I')
        K = Tensor(LogicalShape(plaidml.DType.FLOAT32, [3]), name='K')
        i, j = TensorIndexes(2)
        O = TensorOutput(5)
        O[i] += (I[(i - j + 1) // 2] * K[j])
        program = Program('this-is-not an identifier', [O])
        if USE_MLIR():
            self.assertMultiLineEqual(
                str(program), '''

module {
  func @"this-is-not an identifier"(%arg0: tensor<3x!eltwise.fp32> {tile.name = "I"}, %arg1: tensor<3x!eltwise.fp32> {tile.name = "K"}) -> tensor<5x!eltwise.fp32> {
    %c1 = "tile.affine_const"() {value = 1 : i64} : () -> !eltwise.i32
    %c2 = "tile.affine_const"() {value = 2 : i64} : () -> !eltwise.i32
    %c5 = "tile.affine_const"() {value = 5 : i64} : () -> !eltwise.i32
    %0 = "tile.domain"() ( {
    ^bb0(%arg2: !eltwise.i32, %arg3: !eltwise.i32):	// no predecessors
      %1 = "tile.affine_sub"(%arg3, %arg2) : (!eltwise.i32, !eltwise.i32) -> !eltwise.i32
      %2 = "tile.affine_add"(%1, %c1) : (!eltwise.i32, !eltwise.i32) -> !eltwise.i32
      %3 = "tile.affine_div"(%2, %c2) : (!eltwise.i32, !eltwise.i32) -> !eltwise.i32
      %4 = "tile.src_idx_map"(%arg0, %3) : (tensor<3x!eltwise.fp32>, !eltwise.i32) -> !tile.imap
      %5 = "tile.src_idx_map"(%arg1, %arg2) : (tensor<3x!eltwise.fp32>, !eltwise.i32) -> !tile.imap
      %6 = "tile.sink_idx_map"(%arg3) : (!eltwise.i32) -> !tile.imap
      %7 = "tile.size_map"(%c5) : (!eltwise.i32) -> !tile.smap
      "tile.+(x*y)"(%7, %4, %5, %6) : (!tile.smap, !tile.imap, !tile.imap, !tile.imap) -> ()
    }) {idx_names = ["x0", "x1"]} : () -> tensor<5x!eltwise.fp32>
    return %0 : tensor<5x!eltwise.fp32>
  }
}
''')
        else:
            self.assertMultiLineEqual(
                str(program), '''function (
  I[I_0],
  K[K_0]
) -> (
  _X0
) {
  _X0[x0 : 5] = +(I[1/2 + 1/2*x0 - 1/2*x1] * K[x1]);
}
''')
        outputs = plaidml_exec.run(program, [(I, np.array([1, 2, 3])),
                                             (K, np.array([1, 2, 3]))])
        self.assertEqual(outputs[0].tolist(), [2, 5, 4, 9, 6])
Exemplo n.º 6
0
    def testTileIdentity(self):
        I = Tensor(LogicalShape(plaidml.DType.FLOAT32, [3]), name='I')
        program = Program('tile_identity', [I])
        self.assertMultiLineEqual(str(program), '''function (
  I[I_0]
) -> (
  _X0
) {
  _X0 = ident(I);
}
''')
        outputs = plaidml_exec.run(program, [(I, np.array([(1, 2, 3)]))])
        self.assertEqual(outputs[0].tolist(), [1, 2, 3])
Exemplo n.º 7
0
    def test_two_outputs(self):
        I = Tensor(LogicalShape(plaidml.DType.FLOAT32, [3]), name='I')
        program1 = Program('two_outputs', [I, I])
        if USE_MLIR():
            self.assertMultiLineEqual(
                str(program1), '''

module {
  func @two_outputs(%arg0: tensor<3x!eltwise.fp32> {tile.name = "I"}) -> (tensor<3x!eltwise.fp32>, tensor<3x!eltwise.fp32>) {
    %0 = "eltwise.ident"(%arg0) {type = !eltwise.fp32} : (tensor<3x!eltwise.fp32>) -> tensor<3x!eltwise.fp32>
    %1 = "eltwise.ident"(%arg0) {type = !eltwise.fp32} : (tensor<3x!eltwise.fp32>) -> tensor<3x!eltwise.fp32>
    return %0, %1 : tensor<3x!eltwise.fp32>, tensor<3x!eltwise.fp32>
  }
}
''')
        else:
            self.assertMultiLineEqual(
                str(program1), '''function (
  I[I_0]
) -> (
  _X1,
  _X0
) {
  _X0 = ident(I);
  _X1 = ident(I);
}
''')
        outputs = plaidml_exec.run(program1, [(I, np.array([(1, 2, 3)]))])
        self.assertEqual(outputs[0].tolist(), [1, 2, 3])
        self.assertEqual(outputs[1].tolist(), [1, 2, 3])

        O1 = I
        O2 = I
        program2 = Program('two_outputs', [O1, O2])
        self.assertMultiLineEqual(str(program1), str(program2))

        outputs = plaidml_exec.run(program2, [(I, np.array([(1, 2, 3)]))])
        self.assertEqual(outputs[0].tolist(), [1, 2, 3])
        self.assertEqual(outputs[1].tolist(), [1, 2, 3])
Exemplo n.º 8
0
    def testDefractShort(self):
        I = Tensor(LogicalShape(plaidml.DType.FLOAT32, [3]), name='I')
        i, j = TensorIndexes(2)
        O = TensorOutput(6)
        O[i] += (I[(i - 1) // 2])
        program = Program('defract_short_test', [O])
        self.assertMultiLineEqual(
            str(program), '''function (
  I[I_0]
) -> (
  _X0
) {
  _X0[x0 : 6] = +(I[-1/2 + 1/2*x0]);
}
''')
        outputs = plaidml_exec.run(program, [(I, np.array([1, 2, 3]))])
        self.assertEqual(outputs[0].tolist(), [0, 1, 0, 2, 0, 3])
Exemplo n.º 9
0
    def test_defract(self):
        I = Tensor(LogicalShape(plaidml.DType.FLOAT32, [3]), name='I')
        K = Tensor(LogicalShape(plaidml.DType.FLOAT32, [3]), name='K')
        i, j = TensorIndexes(2)
        O = TensorOutput(5)
        O[i] += (I[(i - j + 1) // 2] * K[j])
        program = Program('defract_test', [O])
        if USE_MLIR():
            self.assertMultiLineEqual(
                str(program), '''

module {
  func @defract_test(%arg0: tensor<3x!eltwise.fp32> {tile.name = "I"}, %arg1: tensor<3x!eltwise.fp32> {tile.name = "K"}) -> tensor<5x!eltwise.fp32> {
    %c1 = "tile.affine_const"() {value = 1 : i64} : () -> !eltwise.i32
    %c2 = "tile.affine_const"() {value = 2 : i64} : () -> !eltwise.i32
    %c5 = "tile.affine_const"() {value = 5 : i64} : () -> !eltwise.i32
    %0 = "tile.domain"() ( {
    ^bb0(%arg2: !eltwise.i32, %arg3: !eltwise.i32):	// no predecessors
      %1 = "tile.affine_sub"(%arg3, %arg2) : (!eltwise.i32, !eltwise.i32) -> !eltwise.i32
      %2 = "tile.affine_add"(%1, %c1) : (!eltwise.i32, !eltwise.i32) -> !eltwise.i32
      %3 = "tile.affine_div"(%2, %c2) : (!eltwise.i32, !eltwise.i32) -> !eltwise.i32
      %4 = "tile.src_idx_map"(%arg0, %3) : (tensor<3x!eltwise.fp32>, !eltwise.i32) -> !tile.imap
      %5 = "tile.src_idx_map"(%arg1, %arg2) : (tensor<3x!eltwise.fp32>, !eltwise.i32) -> !tile.imap
      %6 = "tile.sink_idx_map"(%arg3) : (!eltwise.i32) -> !tile.imap
      %7 = "tile.size_map"(%c5) : (!eltwise.i32) -> !tile.smap
      "tile.+(x*y)"(%7, %4, %5, %6) : (!tile.smap, !tile.imap, !tile.imap, !tile.imap) -> ()
    }) {idx_names = ["x0", "x1"]} : () -> tensor<5x!eltwise.fp32>
    return %0 : tensor<5x!eltwise.fp32>
  }
}
''')
        else:
            self.assertMultiLineEqual(
                str(program), '''function (
  I[I_0],
  K[K_0]
) -> (
  _X0
) {
  _X0[x0 : 5] = +(I[1/2 + 1/2*x0 - 1/2*x1] * K[x1]);
}
''')
        outputs = plaidml_exec.run(program, [(I, np.array([1, 2, 3])),
                                             (K, np.array([1, 2, 3]))])
        self.assertEqual(outputs[0].tolist(), [2, 5, 4, 9, 6])
Exemplo n.º 10
0
    def testDefract(self):
        I = Tensor(LogicalShape(plaidml.DType.FLOAT32, [3]), name='I')
        K = Tensor(LogicalShape(plaidml.DType.FLOAT32, [3]), name='K')
        i, j = TensorIndexes(2)
        O = TensorOutput(5)
        O[i] += (I[(i - j + 1) // 2] * K[j])
        program = Program('defract_test', [O])
        self.assertMultiLineEqual(
            str(program), '''function (
  I[I_0],
  K[K_0]
) -> (
  _X0
) {
  _X0[x0 : 5] = +(I[1/2 + 1/2*x0 - 1/2*x1] * K[x1]);
}
''')
        outputs = plaidml_exec.run(program, [(I, np.array([1, 2, 3])), (K, np.array([1, 2, 3]))])
        self.assertEqual(outputs[0].tolist(), [2, 5, 4, 9, 6])
Exemplo n.º 11
0
    def testDefractLong(self):
        shape = [1, 3, 3, 1]
        I = Tensor(LogicalShape(plaidml.DType.FLOAT32, shape), name='I')
        K = Tensor(LogicalShape(plaidml.DType.FLOAT32, shape), name='K')
        n, x0, x1, c0, c1, co, ci, k0, k1 = TensorIndexes(9)
        O = TensorOutput(1, 5, 5, 1)
        O[n, x0, x1, co] += (I[n, (x0 + k0 - 1) // 2,
                               (x1 + k1 - 1) // 2, ci] * K[2 - k0, 2 - k1, co, ci])
        program = Program('defract_long', [O])
        self.assertMultiLineEqual(
            str(program), '''function (
  I[I_0, I_1, I_2, I_3],
  K[K_0, K_1, K_2, K_3]
) -> (
  _X0
) {
  _X0[x0, x1, x3, x6 : 1, 5, 5, 1] = +(I[x0, -1/2 + 1/2*x1 + 1/2*x2, -1/2 + 1/2*x3 + 1/2*x4, x5] * K[2 - x2, 2 - x4, x6, x5]);
}
''')
        outputs = plaidml_exec.run(program, [
            (I, np.array([[
                [[1], [3], [-1]],
                [[0], [2], [4]],
                [[1], [-1], [-2]],
            ]])),
            (K, np.array([[
                [[2], [3], [4]],
                [[6], [-3], [-1]],
                [[-1], [-2], [1]],
            ]])),
        ])
        np.testing.assert_array_equal(
            outputs[0],
            np.array([[
                [[0], [0], [0], [0], [0]],
                [[0], [4], [12], [6], [24]],
                [[0], [0], [0], [0], [0]],
                [[6], [-3], [-6], [-3], [-12]],
                [[0], [0], [0], [0], [0]],
            ]]))
Exemplo n.º 12
0
    def test_defract_short(self):
        I = Tensor(LogicalShape(plaidml.DType.FLOAT32, [3]), name='I')
        i, j = TensorIndexes(2)
        O = TensorOutput(6)
        O[i] += (I[(i - 1) // 2])
        program = Program('defract_short_test', [O])
        if USE_MLIR():
            self.assertMultiLineEqual(
                str(program), '''

module {
  func @defract_short_test(%arg0: tensor<3x!eltwise.fp32> {tile.name = "I"}) -> tensor<6x!eltwise.fp32> {
    %c1 = "tile.affine_const"() {value = 1 : i64} : () -> !eltwise.i32
    %c2 = "tile.affine_const"() {value = 2 : i64} : () -> !eltwise.i32
    %c6 = "tile.affine_const"() {value = 6 : i64} : () -> !eltwise.i32
    %0 = "tile.domain"() ( {
    ^bb0(%arg1: !eltwise.i32):	// no predecessors
      %1 = "tile.affine_sub"(%arg1, %c1) : (!eltwise.i32, !eltwise.i32) -> !eltwise.i32
      %2 = "tile.affine_div"(%1, %c2) : (!eltwise.i32, !eltwise.i32) -> !eltwise.i32
      %3 = "tile.src_idx_map"(%arg0, %2) : (tensor<3x!eltwise.fp32>, !eltwise.i32) -> !tile.imap
      %4 = "tile.sink_idx_map"(%arg1) : (!eltwise.i32) -> !tile.imap
      %5 = "tile.size_map"(%c6) : (!eltwise.i32) -> !tile.smap
      "tile.+(x)"(%5, %3, %4) : (!tile.smap, !tile.imap, !tile.imap) -> ()
    }) {idx_names = ["x0"]} : () -> tensor<6x!eltwise.fp32>
    return %0 : tensor<6x!eltwise.fp32>
  }
}
''')
        else:
            self.assertMultiLineEqual(
                str(program), '''function (
  I[I_0]
) -> (
  _X0
) {
  _X0[x0 : 6] = +(I[-1/2 + 1/2*x0]);
}
''')
        outputs = plaidml_exec.run(program, [(I, np.array([1, 2, 3]))])
        self.assertEqual(outputs[0].tolist(), [0, 1, 0, 2, 0, 3])
Exemplo n.º 13
0
def main():
    print("""
PlaidML Setup ({0})

Thanks for using PlaidML!

Some Notes:
  * Bugs and other issues: https://github.com/plaidml/plaidml
  * Questions: https://stackoverflow.com/questions/tagged/plaidml
  * Say hello: https://groups.google.com/forum/#!forum/plaidml-dev
  * PlaidML is licensed under the Apache License 2.0
 """.format(plaidml.__version__))

    devices = sorted(plaidml_exec.list_devices())
    targets = sorted(plaidml_exec.list_targets())

    if not devices:
        print("""
No OpenCL devices found. Check driver installation.
Read the helpful, easy driver installation instructions from our README:
http://github.com/plaidml/plaidml
""")
        sys.exit(-1)

    dev_idx = 0
    if len(devices) > 1:
        print("""
Multiple devices detected (You can override by setting PLAIDML_DEVICE).
Please choose a default device:
""")
        for i, device in enumerate(devices):
            print("   {} : {}".format(i + 1, device))
        choices = [str(i + 1) for i in range(len(devices))]
        dev_idx = int(choice_prompt("\nDefault device", choices, "1"))
    plaidml_settings.set('PLAIDML_DEVICE', devices[dev_idx - 1])
    device = plaidml_settings.get('PLAIDML_DEVICE')

    print()
    print("Selected device:")
    print("    {}".format(device))

    print()
    print("A target determines the compiler configuration and should be matched with your device.")
    print("Please choose a default target:")
    for i, target in enumerate(targets):
        print("   {} : {}".format(i + 1, target))
    choices = [str(i + 1) for i in range(len(targets))]
    tgt_idx = int(choice_prompt("\nDefault target", choices, "1"))
    plaidml_settings.set('PLAIDML_TARGET', targets[tgt_idx - 1])
    target = plaidml_settings.get('PLAIDML_TARGET')

    print()
    print("Selected target:")
    print("    {}".format(target))

    print()
    print("Almost done. Multiplying some matrices...")
    print("Tile code:")
    print("  function (B[X, Z], C[Z, Y]) -> (A) { A[x, y : X, Y] = +(B[x, z] * C[z, y]); }")

    shape = edsl.LogicalShape(plaidml.DType.FLOAT32, [3, 3])
    B = edsl.Tensor(shape)
    C = edsl.Tensor(shape)

    X, Y, Z = edsl.TensorDims(3)
    x, y, z = edsl.TensorIndexes(3)
    B.bind_dims(X, Z)
    C.bind_dims(Z, Y)
    A = edsl.TensorOutput(X, Y)
    A[x, y] += B[x, z] * C[z, y]

    program = edsl.Program('plaidml_setup', [A])
    plaidml_exec.run(program, [(B, np.random.rand(3, 3)), (C, np.random.rand(3, 3))])
    print("Whew. That worked.")
    print()

    settings_path = plaidml_settings.get('PLAIDML_SETTINGS')
    save = choice_prompt("Save settings to {0}".format(settings_path), ["y", "n"], "y")
    if save == "y":
        plaidml_settings.save()
    print("Success!")
    print()
Exemplo n.º 14
0
    def test_defract_long(self):
        shape = [1, 3, 3, 1]
        I = Tensor(LogicalShape(plaidml.DType.FLOAT32, shape), name='I')
        K = Tensor(LogicalShape(plaidml.DType.FLOAT32, shape), name='K')
        n, x0, x1, c0, c1, co, ci, k0, k1 = TensorIndexes(9)
        O = TensorOutput(1, 5, 5, 1)
        O[n, x0, x1,
          co] += (I[n, (x0 + k0 - 1) // 2,
                    (x1 + k1 - 1) // 2, ci] * K[2 - k0, 2 - k1, co, ci])
        program = Program('defract_long', [O])
        if USE_MLIR():
            self.assertMultiLineEqual(
                str(program), '''

module {
  func @defract_long(%arg0: tensor<1x3x3x1x!eltwise.fp32> {tile.name = "I"}, %arg1: tensor<1x3x3x1x!eltwise.fp32> {tile.name = "K"}) -> tensor<1x5x5x1x!eltwise.fp32> {
    %c2 = "tile.affine_const"() {value = 2 : i64} : () -> !eltwise.i32
    %c5 = "tile.affine_const"() {value = 5 : i64} : () -> !eltwise.i32
    %c1 = "tile.affine_const"() {value = 1 : i64} : () -> !eltwise.i32
    %0 = "tile.domain"() ( {
    ^bb0(%arg2: !eltwise.i32, %arg3: !eltwise.i32, %arg4: !eltwise.i32, %arg5: !eltwise.i32, %arg6: !eltwise.i32, %arg7: !eltwise.i32, %arg8: !eltwise.i32):	// no predecessors
      %1 = "tile.affine_add"(%arg4, %arg3) : (!eltwise.i32, !eltwise.i32) -> !eltwise.i32
      %2 = "tile.affine_sub"(%1, %c1) : (!eltwise.i32, !eltwise.i32) -> !eltwise.i32
      %3 = "tile.affine_div"(%2, %c2) : (!eltwise.i32, !eltwise.i32) -> !eltwise.i32
      %4 = "tile.affine_add"(%arg6, %arg5) : (!eltwise.i32, !eltwise.i32) -> !eltwise.i32
      %5 = "tile.affine_sub"(%4, %c1) : (!eltwise.i32, !eltwise.i32) -> !eltwise.i32
      %6 = "tile.affine_div"(%5, %c2) : (!eltwise.i32, !eltwise.i32) -> !eltwise.i32
      %7 = "tile.src_idx_map"(%arg0, %arg7, %6, %3, %arg2) : (tensor<1x3x3x1x!eltwise.fp32>, !eltwise.i32, !eltwise.i32, !eltwise.i32, !eltwise.i32) -> !tile.imap
      %8 = "tile.affine_sub"(%c2, %arg3) : (!eltwise.i32, !eltwise.i32) -> !eltwise.i32
      %9 = "tile.affine_sub"(%c2, %arg5) : (!eltwise.i32, !eltwise.i32) -> !eltwise.i32
      %10 = "tile.src_idx_map"(%arg1, %9, %8, %arg8, %arg2) : (tensor<1x3x3x1x!eltwise.fp32>, !eltwise.i32, !eltwise.i32, !eltwise.i32, !eltwise.i32) -> !tile.imap
      %11 = "tile.sink_idx_map"(%arg7, %arg6, %arg4, %arg8) : (!eltwise.i32, !eltwise.i32, !eltwise.i32, !eltwise.i32) -> !tile.imap
      %12 = "tile.size_map"(%c1, %c5, %c5, %c1) : (!eltwise.i32, !eltwise.i32, !eltwise.i32, !eltwise.i32) -> !tile.smap
      "tile.+(x*y)"(%12, %7, %10, %11) : (!tile.smap, !tile.imap, !tile.imap, !tile.imap) -> ()
    }) {idx_names = ["x0", "x1", "x2", "x3", "x4", "x5", "x6"]} : () -> tensor<1x5x5x1x!eltwise.fp32>
    return %0 : tensor<1x5x5x1x!eltwise.fp32>
  }
}
''')
        else:
            self.assertMultiLineEqual(
                str(program), '''function (
  I[I_0, I_1, I_2, I_3],
  K[K_0, K_1, K_2, K_3]
) -> (
  _X0
) {
  _X0[x0, x1, x3, x6 : 1, 5, 5, 1] = +(I[x0, -1/2 + 1/2*x1 + 1/2*x2, -1/2 + 1/2*x3 + 1/2*x4, x5] * K[2 - x2, 2 - x4, x6, x5]);
}
''')
        outputs = plaidml_exec.run(program, [
            (I,
             np.array([[
                 [[1], [3], [-1]],
                 [[0], [2], [4]],
                 [[1], [-1], [-2]],
             ]])),
            (K,
             np.array([[
                 [[2], [3], [4]],
                 [[6], [-3], [-1]],
                 [[-1], [-2], [1]],
             ]])),
        ])
        np.testing.assert_array_equal(
            outputs[0],
            np.array([[
                [[0], [0], [0], [0], [0]],
                [[0], [4], [12], [6], [24]],
                [[0], [0], [0], [0], [0]],
                [[6], [-3], [-6], [-3], [-12]],
                [[0], [0], [0], [0], [0]],
            ]]))