test_backend_interpreter.py 4.7 KB
Newer Older
1 2
import numpy as np
import tvm
3
import tvm.testing
4
from tvm import relay
5
from tvm.relay.backend.interpreter import Value, TupleValue
6
from tvm.relay.scope_builder import ScopeBuilder
7
from tvm.relay import testing, create_executor
8 9


10
def check_eval(expr, args, expected_result, mod=None, rtol=1e-07):
11 12 13 14 15 16 17 18 19 20
    # TODO(tqchen) add more types once the schedule register is fixed.
    for target in ["llvm"]:
        ctx = tvm.context(target, 0)
        if not ctx.exist:
            return
        intrp = create_executor(mod=mod, ctx=ctx, target=target)
        result = intrp.evaluate(expr)(*args)
        # use tvm.testing which also set atol
        tvm.testing.assert_allclose(
            result.asnumpy(), expected_result, rtol=rtol)
21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39


def test_from_scalar():
    np.testing.assert_allclose(Value.from_scalar(1, 'int32').asnumpy(), 1)
    np.testing.assert_allclose(Value.from_scalar(10.0, 'float32').asnumpy(), 10.0)
    np.testing.assert_allclose(Value.from_scalar(True).asnumpy(), True)


def test_tuple_value():
    tv = TupleValue(Value.from_scalar(
        1), Value.from_scalar(2), Value.from_scalar(3))
    np.testing.assert_allclose(tv[0].asnumpy(), 1)
    np.testing.assert_allclose(tv[1].asnumpy(), 2)
    np.testing.assert_allclose(tv[2].asnumpy(), 3)


def test_id():
    x = relay.var('x', 'float32')
    ident = relay.Function([x], x)
40 41
    one = np.array(1.0, 'float32')
    check_eval(ident, [one], one)
42 43 44


def test_add_const():
45
    two = relay.add(relay.const(1), relay.const(1))
46 47 48 49 50 51 52
    func = relay.Function([], two)
    check_eval(func, [], 2)


def test_mul_param():
    x = relay.var('x', shape=(10, 10))
    y = relay.var('y', shape=(1, 10))
53
    func = relay.Function([x, y], relay.multiply(x, y))
54 55 56 57 58 59 60 61
    x_data = np.random.rand(10, 10).astype('float32')
    y_data = np.random.rand(1, 10).astype('float32')
    check_eval(func, [x_data, y_data], x_data * y_data)


def test_equal():
    i = relay.var('i', shape=[], dtype='int32')
    j = relay.var('i', shape=[], dtype='int32')
62
    z = relay.equal(i, j)
63
    func = relay.Function([i, j], z, ret_type=relay.TensorType([], 'bool'))
64 65
    i_data = relay.const(0, 'int32')
    j_data = relay.const(0, 'int32')
66 67
    check_eval(func, [i_data, j_data], True)

68

69 70
def test_subtract():
    i = relay.var('i', shape=[], dtype='int32')
71
    sub = relay.subtract(i, relay.const(1, dtype='int32'))
72 73 74 75
    func = relay.Function([i], sub, ret_type=relay.TensorType([], 'int32'))
    i_data = np.array(1, dtype='int32')
    check_eval(func, [i_data], 0)

76

77
def test_simple_loop():
78
    mod = relay.module.Module({})
79 80 81
    sum_up = relay.GlobalVar('sum_up')
    i = relay.var('i', shape=[], dtype='int32')
    sb = ScopeBuilder()
82
    with sb.if_scope(relay.equal(i, relay.const(0, dtype='int32'))):
83 84
        sb.ret(i)
    with sb.else_scope():
85
        one_less = relay.subtract(i, relay.const(1, dtype='int32'))
86
        rec_call = relay.Call(sum_up, [one_less])
87
        sb.ret(relay.add(rec_call, i))
88
    func = relay.Function([i], sb.get(), ret_type=relay.TensorType([], 'int32'))
89
    mod[sum_up] = func
90
    i_data = np.array(10, dtype='int32')
91
    check_eval(sum_up, [i_data], sum(range(1, 11)), mod=mod)
92

93

94
def test_loop():
95
    mod = relay.module.Module({})
96 97 98 99
    sum_up = relay.GlobalVar('sum_up')
    i = relay.var('i', shape=[], dtype='int32')
    accum = relay.var('accum', shape=[], dtype='int32')
    sb = ScopeBuilder()
100
    with sb.if_scope(relay.equal(i, relay.const(0, 'int32'))):
101 102
        sb.ret(accum)
    with sb.else_scope():
103
        one_less = relay.subtract(i, relay.const(1, 'int32'))
104
        new_accum = relay.add(accum, i)
105 106
        sb.ret(relay.Call(sum_up, [one_less, new_accum]))
    func = relay.Function([i, accum], sb.get())
107
    mod[sum_up] = func
108 109
    i_data = np.array(10, dtype='int32')
    accum_data = np.array(0, dtype='int32')
110
    check_eval(sum_up, [i_data, accum_data], sum(range(1, 11)), mod=mod)
111

112 113 114 115 116 117 118 119 120

def test_binds():
    x = relay.var("x")
    y = relay.add(x, x)
    intrp = create_executor("debug")
    xx = np.ones((10, 20))
    res = intrp.evaluate(y, binds={x: xx}).asnumpy()
    tvm.testing.assert_allclose(xx + xx, res)

121 122 123 124 125 126 127 128 129 130 131 132
def test_kwargs_params():
    x = relay.var("x", shape=(1, 10))
    y = relay.var("y", shape=(1, 10))
    z = relay.var("z", shape=(1, 10))
    f = relay.Function([x, y, z], x + y + z)
    x_data = np.random.rand(1, 10).astype('float32')
    y_data = np.random.rand(1, 10).astype('float32')
    z_data = np.random.rand(1, 10).astype('float32')
    params = { 'y': y_data, 'z': z_data }
    intrp = create_executor("debug")
    res = intrp.evaluate(f)(x_data, **params).data
    tvm.testing.assert_allclose(res.asnumpy(), x_data + y_data + z_data)
133 134 135 136 137 138 139 140

if __name__ == "__main__":
    test_id()
    test_add_const()
    test_equal()
    test_subtract()
    test_simple_loop()
    test_loop()
141
    test_binds()
142
    test_kwargs_params()