def test_lrn(): n, c , h, w = tvm.var("n"), tvm.var("c"), tvm.var("h"), tvm.var("w") x = relay.var("x", shape=(n, c , h, w)) y = relay.nn.lrn(x, size=10, axis=2, bias=0.5, alpha=.00001, beta=0.75) "alpha=" in y.astext() yy = relay.ir_pass.infer_type(y) assert yy.checked_type == relay.TensorType((n, c , h, w)) shape = (1, 5, 10, 10) dtype = "float32" x = relay.var("x", relay.TensorType(shape, dtype)) size=5 axis=1 bias=0.5 alpha=.00001 beta=0.75 z = relay.nn.lrn(x, size=size, axis=axis, bias=bias, alpha=alpha, beta=beta) yy = relay.ir_pass.infer_type(z) assert yy.checked_type == relay.TensorType(shape, dtype) func = relay.Function([x], z) x_data = np.random.uniform(low=-1, high=1, size=shape).astype(dtype) ref_res = topi.testing.lrn_python(x_data, size, axis, bias, alpha, beta) for target, ctx in ctx_list(): intrp1 = relay.create_executor("graph", ctx=ctx, target=target) intrp2 = relay.create_executor("debug", ctx=ctx, target=target) op_res1 = intrp1.evaluate(func)(x_data) tvm.testing.assert_allclose(op_res1.asnumpy(), ref_res, rtol=1e-5) op_res2 = intrp2.evaluate(func)(x_data) tvm.testing.assert_allclose(op_res2.asnumpy(), ref_res, rtol=1e-5)
def test_flatten_infer_type(): d1, d2, d3, d4 = tvm.var("d1"), tvm.var("d2"), tvm.var("d3"), tvm.var("d4") x = relay.var("x", relay.TensorType((d1, d2, d3, d4), "float32")) y = relay.nn.batch_flatten(x) yy = relay.ir_pass.infer_type(y) assert yy.checked_type == relay.TensorType((d1, ((d2*d3)*d4)), "float32") x = relay.var("x", relay.TensorType((3, 2, 4, 3), "float32")) y = relay.nn.batch_flatten(x) yy = relay.ir_pass.infer_type(y) assert yy.checked_type == relay.TensorType((3, 24), "float32") x = relay.var("x", relay.TensorType((d1, 2, d3, 3), "float32")) y = relay.nn.batch_flatten(x) yy = relay.ir_pass.infer_type(y) assert yy.checked_type == relay.TensorType((d1, ((2*d3)*3)), "float32") shape = (1, 5, 10, 10) o_shape = (1, 500) dtype = "float32" x = relay.var("x", relay.TensorType(shape, dtype)) z = relay.nn.batch_flatten(x) yy = relay.ir_pass.infer_type(z) assert yy.checked_type == relay.TensorType(o_shape, dtype) func = relay.Function([x], z) x_data = np.random.uniform(low=-1, high=1, size=shape).astype(dtype) ref_res = x_data.flatten().reshape(o_shape) for target, ctx in ctx_list(): intrp1 = relay.create_executor("graph", ctx=ctx, target=target) intrp2 = relay.create_executor("debug", ctx=ctx, target=target) op_res1 = intrp1.evaluate(func)(x_data) tvm.testing.assert_allclose(op_res1.asnumpy(), ref_res, rtol=1e-5) op_res2 = intrp2.evaluate(func)(x_data) tvm.testing.assert_allclose(op_res2.asnumpy(), ref_res, rtol=1e-5)
def verify_multibox_prior(x, dshape, ref_res, sizes=(1.0,), ratios=(1.0,), steps=(-1.0, -1.0), offsets=(0.5, 0.5), clip=True, check_size=False, check_type_only=False): z = relay.vision.multibox_prior(x, sizes, ratios, steps, offsets, clip) zz = relay.ir_pass.infer_type(z) if check_size: assert "sizes=" in z.astext() assert zz.checked_type == relay.TensorType( (1, dshape[2] * dshape[3] * (len(sizes) + len(ratios) - 1), 4), "float32") if check_type_only: return data = np.random.uniform(low=-1, high=1, size=dshape).astype("float32") func = relay.Function([x], z) func = relay.ir_pass.infer_type(func) for target, ctx in ctx_list(): intrp1 = relay.create_executor("graph", ctx=ctx, target=target) op_res1 = intrp1.evaluate(func)(data) tvm.testing.assert_allclose(op_res1.asnumpy(), ref_res, rtol=1e-5) intrp2 = relay.create_executor("debug", ctx=ctx, target=target) op_res2 = intrp2.evaluate(func)(data) tvm.testing.assert_allclose(op_res2.asnumpy(), ref_res, rtol=1e-5)
def test_l2_normalize(): n, c , h, w = tvm.var("n"), tvm.var("c"), tvm.var("h"), tvm.var("w") x = relay.var("x", shape=(n, c , h, w)) y = relay.nn.l2_normalize(x, eps=0.001, axis=[1]) "axis=" in y.astext() yy = relay.ir_pass.infer_type(y) assert yy.checked_type == relay.TensorType((n, c , h, w)) shape = (1, 5, 10, 10) dtype = "float32" x = relay.var("x", relay.TensorType(shape, dtype)) eps=0.001 axis=1 z = relay.nn.l2_normalize(x, eps=0.001, axis=[axis]) yy = relay.ir_pass.infer_type(z) assert yy.checked_type == relay.TensorType(shape, dtype) func = relay.Function([x], z) x_data = np.random.uniform(low=-1, high=1, size=shape).astype(dtype) ref_res = topi.testing.l2_normalize_python(x_data, eps, axis) for target, ctx in ctx_list(): intrp1 = relay.create_executor("graph", ctx=ctx, target=target) intrp2 = relay.create_executor("debug", ctx=ctx, target=target) op_res1 = intrp1.evaluate(func)(x_data) tvm.testing.assert_allclose(op_res1.asnumpy(), ref_res, rtol=1e-5) op_res2 = intrp2.evaluate(func)(x_data) tvm.testing.assert_allclose(op_res2.asnumpy(), ref_res, rtol=1e-5)
def verify_roi_pool(data_shape, rois_shape, pooled_size, spatial_scale): data = relay.var("data", relay.ty.TensorType(data_shape, "float32")) rois = relay.var("rois", relay.ty.TensorType(rois_shape, "float32")) z = relay.vision.roi_pool(data, rois, pooled_size=(pooled_size, pooled_size), spatial_scale=spatial_scale, layout="NCHW") zz = relay.ir_pass.infer_type(z) batch, channel, in_size, _ = data_shape num_roi = rois_shape[0] assert zz.checked_type == relay.ty.TensorType( (num_roi, channel, pooled_size, pooled_size), "float32") func = relay.Function([data, rois], z) func = relay.ir_pass.infer_type(func) np_data = np.random.uniform(size=data_shape).astype("float32") np_rois = np.random.uniform(size=rois_shape).astype('float32') * in_size np_rois[:, 0] = np.random.randint(low = 0, high = batch, size = num_roi).astype('float32') ref_res = topi.testing.roi_pool_nchw_python(np_data, np_rois, pooled_size=pooled_size, spatial_scale=spatial_scale) for target, ctx in ctx_list(): intrp1 = relay.create_executor("graph", ctx=ctx, target=target) op_res1 = intrp1.evaluate(func)(np_data, np_rois) tvm.testing.assert_allclose(op_res1.asnumpy(), ref_res, rtol=1e-4) intrp2 = relay.create_executor("debug", ctx=ctx, target=target) op_res2 = intrp2.evaluate(func)(np_data, np_rois) tvm.testing.assert_allclose(op_res2.asnumpy(), ref_res, rtol=1e-4)
def test_pass_run(): function_pass = transform assert pass_name in function_pass.astext() updated_mod = function_pass(mod) assert isinstance(updated_mod, relay.Module) # Check the log function in the updated module. new_v_log = updated_mod.get_global_var(v_log.name_hint) new_log = updated_mod[new_v_log] check_func(new_log, get_ref_log()) # Check the log function in the python transformed function. ret = opt_tester.transform(log, pass_ctx) check_func(new_log, ret) # Execute the add function. x_nd = get_rand(shape, dtype) ref_res = np.log(x_nd.asnumpy() * 2) for target, ctx in ctx_list(): exe1 = relay.create_executor("graph", ctx=ctx, target=target) exe2 = relay.create_executor("debug", ctx=ctx, target=target) res1 = exe1.evaluate(new_log)(x_nd) tvm.testing.assert_allclose(res1.asnumpy(), ref_res, rtol=1e-5) res2 = exe2.evaluate(new_log)(x_nd) tvm.testing.assert_allclose(res2.asnumpy(), ref_res, rtol=1e-5)
def test_infer_type_leaky_relu(): n, c , h, w = tvm.var("n"), tvm.var("c"), tvm.var("h"), tvm.var("w") x = relay.var("x", relay.TensorType((n, c, h, w), "float32")) y = relay.nn.leaky_relu(x, alpha=0.1) "alpha=0.1" in y.astext() yy = relay.ir_pass.infer_type(y) assert yy.checked_type == relay.TensorType((n, c, h, w), "float32") shape = (1, 5, 10, 10) dtype = "float32" x = relay.var("x", relay.TensorType(shape, dtype)) z = relay.nn.leaky_relu(x, alpha=0.1) assert "alpha=0.1" in z.astext() yy = relay.ir_pass.infer_type(z) assert yy.checked_type == relay.TensorType(shape, dtype) func = relay.Function([x], z) x_data = np.random.uniform(low=-1, high=1, size=shape).astype(dtype) ref_res = np.where(x_data > 0, x_data, x_data * 0.1) for target, ctx in ctx_list(): intrp1 = relay.create_executor("graph", ctx=ctx, target=target) intrp2 = relay.create_executor("debug", ctx=ctx, target=target) op_res1 = intrp1.evaluate(func)(x_data) tvm.testing.assert_allclose(op_res1.asnumpy(), ref_res, rtol=1e-5) op_res2 = intrp2.evaluate(func)(x_data) tvm.testing.assert_allclose(op_res2.asnumpy(), ref_res, rtol=1e-5)
def verify_infer_type_prelu(data, alpha, axis, output, dtype="float32"): x = relay.var("data", relay.TensorType(data, dtype)) if alpha: y = relay.var("alpha", relay.TensorType(alpha, dtype)) else: y = relay.var("alpha", relay.IncompleteType()) z = relay.nn.prelu(x, y, axis=axis) zz = relay.ir_pass.infer_type(z) if axis != 1: assert "axis" in z.astext() assert zz.checked_type == relay.ty.TensorType(output, dtype) if not alpha: axis = axis if axis else 1 alpha_shape = (data[axis],) assert zz.args[1].checked_type == relay.TensorType(alpha_shape, "float32") if all(isinstance(v, tvm.expr.Var) == 1 for v in data) or not alpha: return func = relay.Function([x, y], z) x_data = np.random.uniform(low=-1, high=1, size=data).astype(dtype) a_data = np.random.uniform(low=-1, high=1, size=alpha).astype(dtype) if axis == 1: ref_res = (x_data < 0) * (x_data * a_data.reshape(3, 1, 1)) + (x_data>=0) * x_data else: ref_res = (x_data < 0) * (x_data * a_data.reshape(1, 1, 3)) + (x_data>=0) * x_data for target, ctx in ctx_list(): intrp1 = relay.create_executor("graph", ctx=ctx, target=target) intrp2 = relay.create_executor("debug", ctx=ctx, target=target) op_res1 = intrp1.evaluate(func)(x_data, a_data) tvm.testing.assert_allclose(op_res1.asnumpy(), ref_res, rtol=1e-5) op_res2 = intrp2.evaluate(func)(x_data, a_data) tvm.testing.assert_allclose(op_res2.asnumpy(), ref_res, rtol=1e-5)
def test_forward_scalar_ops(): for op in [operator.add, operator.sub, operator.mul, operator.truediv, operator.pow, operator.lt, operator.le, operator.eq, operator.ne, operator.gt, operator.ge]: dtype='float32' a_shape = (3, 4, 5) a_np = np.random.uniform(size=a_shape).astype(dtype) b_scalar = 2.3 mx_sym = op(mx.sym.var('a'), b_scalar) ref_res = op(mx.nd.array(a_np), b_scalar) shapes = {'a': a_shape} new_sym, _ = relay.frontend.from_mxnet(mx_sym, shapes, dtype) for target, ctx in ctx_list(): for kind in ["graph", "debug"]: intrp = relay.create_executor(kind, ctx=ctx, target=target) op_res = intrp.evaluate(new_sym)(a_np) tvm.testing.assert_allclose(op_res.asnumpy(), ref_res.asnumpy()) for op in ["maximum", "minimum"]: dtype='float32' a_shape = (3, 4, 5) a_np = np.random.uniform(size=a_shape).astype(dtype) b_scalar = 2.3 mx_sym = _mx_symbol(mx.sym, op, [mx.sym.var('a'), b_scalar]) ref_res = _mx_symbol(mx.nd, op, [mx.nd.array(a_np), b_scalar]) shapes = {'a': a_shape} new_sym, _ = relay.frontend.from_mxnet(mx_sym, shapes, dtype) for target, ctx in ctx_list(): for kind in ["graph", "debug"]: intrp = relay.create_executor(kind, ctx=ctx, target=target) op_res = intrp.evaluate(new_sym)(a_np) tvm.testing.assert_allclose(op_res.asnumpy(), ref_res.asnumpy())
def test_default_value(): num_anchors = 3 num_classes = 3 np_cls_prob = np.array( [[[0.2, 0.5, 0.3], [0.25, 0.3, 0.45], [0.7, 0.1, 0.2]]]).astype("float32") np_loc_preds = np.array( [[0.1, -0.2, 0.3, 0.2, 0.2, 0.4, 0.5, -0.3, 0.7, -0.2, -0.4, -0.8]]).astype("float32") np_anchors = np.array( [[[-0.1, -0.1, 0.1, 0.1], [-0.2, -0.2, 0.2, 0.2], [1.2, 1.2, 1.5, 1.5]]]).astype("float32") expected_np_out = np.array([[[1, 0.69999999, 0, 0, 0.10818365, 0.10008108], [0, 0.44999999, 1, 1, 1, 1], [0, 0.30000001, 0, 0, 0.22903419, 0.20435292]]]) cls_prob = relay.var( "cls_prob", relay.ty.TensorType((1, num_anchors, num_classes), "float32")) loc_pred = relay.var( "loc_pred", relay.ty.TensorType((1, num_anchors * 4), "float32")) anchors = relay.var( "anchors", relay.ty.TensorType((1, num_anchors, 4), "float32")) mtl = relay.vision.multibox_transform_loc( cls_prob=cls_prob, loc_pred=loc_pred, anchor=anchors) ret = relay.ir_pass.infer_type(mtl.astuple()) ref_type = relay.ty.TupleType( tvm.convert([ relay.ty.TensorType((1, num_anchors, 6), "float32"), relay.ty.TensorType((1, ), "int") ])) assert ret.checked_type == ref_type nms = relay.vision.non_max_suppression(mtl[0], mtl[1], return_indices=False) func = relay.Function([cls_prob, loc_pred, anchors], nms) func = relay.ir_pass.infer_type(func) for target, ctx in ctx_list(): intrp1 = relay.create_executor("graph", ctx=ctx, target=target) op_res1 = intrp1.evaluate(func)(np_cls_prob, np_loc_preds, np_anchors) tvm.testing.assert_allclose(op_res1.asnumpy(), expected_np_out, rtol=1e-5) intrp2 = relay.create_executor("debug", ctx=ctx, target=target) op_res2 = intrp2.evaluate(func)(np_cls_prob, np_loc_preds, np_anchors) tvm.testing.assert_allclose(op_res2.asnumpy(), expected_np_out, rtol=1e-5)
def veval(f, *args, ctx=tvm.cpu()): if isinstance(f, relay.Expr): ex = relay.create_executor('vm', mod=relay.Module(), ctx=ctx) if len(args) == 0: return ex.evaluate(f) else: return ex.evaluate(f)(*args) else: assert isinstance(f, relay.Module), "expected expression or module" mod = f ex = relay.create_executor('vm', mod=mod, ctx=ctx) if len(args) == 0: return ex.evaluate(mod[mod.entry_func]) else: return ex.evaluate(mod[mod.entry_func])(*args)
def test_forward_broadcast_ops(): for op in ["broadcast_add", "broadcast_sub", "broadcast_mul", "broadcast_div", "broadcast_mod", "broadcast_maximum", "broadcast_minimum", "broadcast_equal", "broadcast_not_equal", "broadcast_greater", "broadcast_greater_equal", "broadcast_lesser", "broadcast_lesser_equal"]: a_shape = (3, 4, 5) b_shape = (4, 5) if op == "broadcast_mod": dtype = 'int32' a_np = np.random.randint(1, 100, size=a_shape).astype(dtype) b_np = np.random.randint(1, 100, size=b_shape).astype(dtype) else: dtype = 'float32' a_np = np.random.uniform(size=a_shape).astype(dtype) b_np = np.random.uniform(size=b_shape).astype(dtype) mx_sym = _mx_symbol(mx.sym, op, [mx.sym.var('a'), mx.sym.var('b')]) ref_res = _mx_symbol(mx.nd, op, [mx.nd.array(a_np), mx.nd.array(b_np)]) shapes = {'a': a_shape, 'b': b_shape} new_sym, _ = relay.frontend.from_mxnet(mx_sym, shapes, dtype) for target, ctx in ctx_list(): for kind in ["graph", "debug"]: intrp = relay.create_executor(kind, ctx=ctx, target=target) op_res = intrp.evaluate(new_sym)(a_np, b_np) tvm.testing.assert_allclose(op_res.asnumpy(), ref_res.asnumpy())
def test_broadcast_add(): shape1 = (3, 4, 1) shape2 = (1, 5) dtype = 'float32' x_nd = rand(dtype, *shape1) y_nd = rand(dtype, *shape2) x_np = x_nd.asnumpy() y_np = y_nd.asnumpy() expected_forward = x_np + y_np t1 = relay.TensorType(shape1, dtype) t2 = relay.TensorType(shape2, dtype) x = relay.var("x", t1) y = relay.var("y", t2) func = relay.Function([x, y], x + y) full_func = relay.ir_pass.infer_type(gradient(func)) assert full_func.checked_type == relay.FuncType([t1, t2], relay.TupleType([relay.TensorType(expected_forward.shape, dtype), relay.TupleType([t1, t2])])) ex = create_executor() forward, (grad_x, grad_y) = ex.evaluate(full_func)(x_nd, y_nd) tvm.testing.assert_allclose(forward.asnumpy(), expected_forward) tvm.testing.assert_allclose(grad_x.asnumpy(), np.ones_like(expected_forward).sum(axis=2, keepdims=True)) tvm.testing.assert_allclose(grad_y.asnumpy(), np.ones_like(expected_forward).sum(axis=(0, 1), keepdims=True).squeeze(axis=0))
def test_binary_int_broadcast(): for op, ref in [(relay.right_shift, np.right_shift), (relay.left_shift, np.left_shift), (relay.mod, np.mod), (relay.maximum, np.maximum), (relay.minimum, np.minimum)]: x = relay.var("x", relay.TensorType((10, 4), "int32")) y = relay.var("y", relay.TensorType((5, 10, 1), "int32")) z = op(x, y) zz = relay.ir_pass.infer_type(z) assert zz.checked_type == relay.TensorType((5, 10, 4), "int32") if ref is not None: x_shape = (10, 4) y_shape = (5, 10, 1) t1 = relay.TensorType(x_shape, 'int32') t2 = relay.TensorType(y_shape, 'int32') x_data = np.random.rand(*x_shape).astype(t1.dtype) y_data = np.random.rand(*y_shape).astype(t2.dtype) func = relay.Function([x, y], z) ref_res = ref(x_data, y_data) for target, ctx in ctx_list(): intrp = relay.create_executor("graph", ctx=ctx, target=target) op_res = intrp.evaluate(func)(x_data, y_data) tvm.testing.assert_allclose(op_res.asnumpy(), ref_res)
def check_binary_op(opfunc, ref): n = tvm.var("n") t1 = relay.TensorType((5, n, 5)) t2 = relay.TensorType((n, 1)) x = relay.var("x", t1) y = relay.var("y", t2) z = opfunc(x, y) # test printer assert ("{}(%x, %y)".format(z.op.name)) in z.astext() assert relay.ir_pass.infer_type(z).checked_type == t1 if ref is not None: t1 = relay.TensorType((5, 10, 5)) t2 = relay.TensorType((5, 10, 5)) x = relay.var("x", t1) y = relay.var("y", t2) z = opfunc(x, y) x_data = np.random.rand(5, 10, 5).astype(t1.dtype) y_data = np.random.rand(5, 10, 5).astype(t2.dtype) ref_res = ref(x_data, y_data) func = relay.Function([x, y], z) for target, ctx in ctx_list(): intrp = relay.create_executor("graph", ctx=ctx, target=target) op_res = intrp.evaluate(func)(x_data, y_data) tvm.testing.assert_allclose(op_res.asnumpy(), ref_res)
def test_forward_where(): cond = mx.sym.var('cond') x = mx.sym.var('x') y = mx.sym.var('y') dshape = (2, 2) dtype = 'float32' mx_sym = mx.sym.where(cond, x, y) np_cond = np.array([[0, 1], [-1, 0]]).astype(dtype) np_x = np.random.uniform(size=dshape).astype(dtype) np_y = np.random.uniform(size=dshape).astype(dtype) mx_cond = mx.nd.array(np_cond) mx_x = mx.nd.array(np_x) mx_y = mx.nd.array(np_y) shapes = {'cond': dshape, 'x': dshape, 'y': dshape} mod = mx.mod.Module(mx_sym, label_names=None, data_names=['cond', 'x', 'y']) mod.bind(data_shapes=shapes.items(), for_training=False) mod.init_params() args, auxs = mod.get_params() mx_out = mx.nd.where(mx_cond, mx_x, mx_y).asnumpy() new_sym, _ = relay.frontend.from_mxnet(mx_sym, shapes, args, auxs) for target, ctx in ctx_list(): for kind in ["graph", "debug"]: intrp = relay.create_executor(kind, ctx=ctx, target=target) op_res = intrp.evaluate(new_sym)(np_cond, np_x, np_y) tvm.testing.assert_allclose(op_res.asnumpy(), mx_out)
def test_cmp_type(): for op, ref in ((relay.greater, np.greater), (relay.greater_equal, np.greater_equal), (relay.less, np.less), (relay.less_equal, np.less_equal), (relay.equal, np.equal), (relay.not_equal, np.not_equal)): x = relay.var("x", relay.TensorType((10, 4), "float32")) y = relay.var("y", relay.TensorType((5, 10, 1), "float32")) z = op(x, y) z.astext() zz = relay.ir_pass.infer_type(z) assert zz.checked_type == relay.TensorType((5, 10, 4), "bool") if ref is not None: x_shape = (10, 4) y_shape = (5, 10, 1) t1 = relay.TensorType(x_shape) t2 = relay.TensorType(y_shape) x = relay.var("x", t1) y = relay.var("y", t2) z = op(x, y) x_data = np.random.rand(*x_shape).astype(t1.dtype) y_data = np.random.rand(*y_shape).astype(t2.dtype) ref_res = ref(x_data, y_data) func = relay.Function([x, y], z) for target, ctx in ctx_list(): intrp = relay.create_executor("graph", ctx=ctx, target=target) op_res = intrp.evaluate(func)(x_data, y_data) tvm.testing.assert_allclose(op_res.asnumpy(), ref_res)
def test_tuple(): shape = (10, 10) dtype = 'float32' t = relay.TensorType(shape, dtype) x = relay.var("x", t) y = relay.var("y", t) z = relay.var("z", t) tup = relay.Var("tup") func = relay.Function([x, y, z], relay.Let(tup, relay.Tuple([x, y, z]), relay.TupleGetItem(tup, 0) + relay.TupleGetItem(tup, 1) - relay.TupleGetItem(tup, 2))) back_func = relay.ir_pass.infer_type(gradient(func)) assert back_func.checked_type == relay.FuncType([t, t, t], relay.TupleType([t, relay.TupleType([t, t, t])])) x_nd = rand(dtype, *shape) y_nd = rand(dtype, *shape) z_nd = rand(dtype, *shape) x_np = x_nd.asnumpy() y_np = y_nd.asnumpy() z_np = z_nd.asnumpy() expected_forward = x_np + y_np - z_np ex = create_executor() forward, (grad_x, grad_y, grad_z) = ex.evaluate(back_func)(x_nd, y_nd, z_nd) tvm.testing.assert_allclose(forward.asnumpy(), expected_forward) tvm.testing.assert_allclose(grad_x.asnumpy(), np.ones_like(grad_x.asnumpy())) tvm.testing.assert_allclose(grad_y.asnumpy(), np.ones_like(grad_y.asnumpy())) tvm.testing.assert_allclose(grad_z.asnumpy(), -1 * np.ones_like(grad_z.asnumpy()))
def verify_adaptive_pool2d(dshape, out_size, pool_type, layout="NCHW", dtype="float32"): def start_index(index, odim, idim): return int(np.floor(index * idim / odim)) def end_index(index, odim, idim): return int(np.ceil((index + 1) * idim / odim)) np_data = np.random.uniform(low=0, high=255, size=dshape).astype(dtype) n, c, h, w = dshape oh, ow = out_size oshape = (n, c) + out_size np_out = np.zeros(oshape).astype(dtype) np_op = np.mean if pool_type == "avg" else np.max for i in range(n): for j in range(c): for k in range(oh): k_start = start_index(k, oh, h) k_end = end_index(k, oh, h) k_sl = slice(k_start, k_end) for l in range(ow): l_start = start_index(l, ow, w) l_end = end_index(l, ow, w) l_sl = slice(l_start, l_end) np_out[i, j, k, l] = np_op(np_data[i, j, k_sl, l_sl]) opfunc = relay.contrib.adaptive_avg_pool2d if pool_type == "avg" else relay.contrib.adaptive_max_pool2d x = relay.var("x", relay.TensorType((n, c, h, w), "float32")) y = opfunc(x, out_size, layout) func = relay.Function([x], y) for target, ctx in ctx_list(): intrp1 = relay.create_executor("graph", ctx=ctx, target=target) relay_out = intrp1.evaluate(func)(np_data) tvm.testing.assert_allclose(relay_out.asnumpy(), np_out, rtol=1e-5, atol=1e-5)
def run_test_conv2d(dtype, out_dtype, scale, dshape, kshape, padding=(1, 1), fref=None, groups=1, dilation=(1, 1), except_targets=None, **attrs): if except_targets is None: except_targets = [] x = relay.var("x", shape=dshape, dtype=dtype) w = relay.var("w", dtype=dtype) y = relay.nn.conv2d(x, w, padding=padding, dilation=dilation, groups=groups, **attrs) func = relay.Function([x, w], y) data = np.random.uniform(-scale, scale, size=dshape).astype(dtype) kernel = np.random.uniform(-scale, scale, size=kshape).astype(dtype) dkernel = topi.testing.dilate_python(kernel, (1, 1) + dilation) if fref is None: ref_res = topi.testing.conv2d_nchw_python( data.astype(out_dtype), dkernel.astype(out_dtype), 1, padding, groups=groups) else: ref_res = fref(data.astype(out_dtype), dkernel.astype(out_dtype)) for target, ctx in ctx_list(): if target in except_targets: continue intrp1 = relay.create_executor("graph", ctx=ctx, target=target) op_res1 = intrp1.evaluate(func)(data, kernel) tvm.testing.assert_allclose(op_res1.asnumpy(), ref_res, rtol=1e-5, atol=1e-5)
def _test_upsampling(layout, method): n, c, h, w = tvm.var("n"), 16, 32, 32 scale = 2 dtype = "float32" def get_shape(): if layout == "NCHW": return (c, h, w), (c, h*scale, w*scale) else: return (h, w, c), (h*scale, w*scale, c) ishape, oshape = get_shape() x = relay.var("x", relay.TensorType((n,) + ishape, dtype)) y = relay.nn.upsampling(x, scale=scale, layout=layout, method=method) yy = relay.ir_pass.infer_type(y) assert yy.checked_type == relay.TensorType((n,) + oshape, dtype) dshape = (1,) + ishape x = relay.var("x", shape=dshape) y = relay.nn.upsampling(x, scale=scale, layout=layout, method=method) func = relay.Function([x], y) data = np.random.uniform(size=dshape).astype(dtype) if method == "NEAREST_NEIGHBOR": ref = topi.testing.upsampling_python(data, scale, layout) else: ref = topi.testing.bilinear_resize_python(data, (h*scale, w*scale), layout) for target, ctx in ctx_list(): executor = relay.create_executor("graph", ctx=ctx, target=target) out = executor.evaluate(func)(data) tvm.testing.assert_allclose(out.asnumpy(), ref, rtol=1e-5, atol=1e-5)
def verify_get_valid_counts(dshape, score_threshold): dtype = "float32" batch_size, num_anchor, elem_length = dshape np_data = np.random.uniform(size=dshape).astype(dtype) np_out1 = np.zeros(shape=(batch_size,)) np_out2 = np.zeros(shape=dshape).astype(dtype) for i in range(batch_size): np_out1[i] = 0 inter_idx = 0 for j in range(num_anchor): score = np_data[i, j, 1] if score >= score_threshold: for k in range(elem_length): np_out2[i, inter_idx, k] = np_data[i, j, k] np_out1[i] += 1 inter_idx += 1 if j >= np_out1[i]: for k in range(elem_length): np_out2[i, j, k] = -1 x = relay.var("x", relay.ty.TensorType(dshape, dtype)) z = relay.vision.get_valid_counts(x, score_threshold) assert "score_threshold" in z.astext() func = relay.Function([x], z.astuple()) func = relay.ir_pass.infer_type(func) for target, ctx in ctx_list(): if target == 'cuda': return intrp = relay.create_executor("debug", ctx=ctx, target=target) out = intrp.evaluate(func)(np_data) tvm.testing.assert_allclose(out[0].asnumpy(), np_out1, rtol=1e-3, atol=1e-04) tvm.testing.assert_allclose(out[1].asnumpy(), np_out2, rtol=1e-3, atol=1e-04)
def test_run(batch, in_channel, size, out_channel, deformable_groups, groups): kernel_size = (3, 3) data_shape = (batch, in_channel, size, size) offset_shape = (batch, 2 * kernel_size[0] * kernel_size[1] * deformable_groups, size, size) kernel_shape = (out_channel, in_channel // groups, kernel_size[0], kernel_size[1]) dtype = 'float32' data = relay.var("data", shape=data_shape, dtype=dtype) offset = relay.var("offset") kernel = relay.var("kernel") y = relay.nn.deformable_conv2d(data, offset, kernel, strides=(1, 1), padding=(1, 1), dilation=(1, 1), kernel_size=kernel_size, deformable_groups=deformable_groups, groups=groups, channels=out_channel) func = relay.Function([data, offset, kernel], y) data = np.random.uniform(size=data_shape).astype(dtype) offset = np.random.uniform(size=offset_shape).astype(dtype) kernel = np.random.uniform(size=kernel_shape).astype(dtype) ref_res = topi.testing.deformable_conv2d_nchw_python(data, offset, kernel, stride=(1, 1), padding=(1, 1), dilation=(1, 1), deformable_groups=deformable_groups, groups=groups) for target, ctx in ctx_list(): for kind in ["graph", "debug"]: intrp1 = relay.create_executor(kind, ctx=ctx, target=target) op_res1 = intrp1.evaluate(func)(data, offset, kernel) tvm.testing.assert_allclose(op_res1.asnumpy(), ref_res, rtol=1e-5, atol=1e-5)
def check_binary_op(opfunc, ref): # TODO(@jroesch): this piece of code improperly uses type variables. n = tvm.var("n") s1 = (5, n, 5) s2 = (n, 1) t1 = relay.TensorType(s1) t2 = relay.TensorType(s2) x = relay.var("x", t1) y = relay.var("y", t2) z = opfunc(x, y) # test printer assert ("{}(%x, %y)".format(z.op.name)) in z.astext() assert relay.ir_pass.infer_type(z).checked_type == t1 if ref is not None: t1 = relay.TensorType((5, 10, 5)) t2 = relay.TensorType((5, 10, 5)) x = relay.var("x", t1) y = relay.var("y", t2) z = opfunc(x, y) x_data = np.random.rand(5, 10, 5).astype(t1.dtype) y_data = np.random.rand(5, 10, 5).astype(t2.dtype) ref_res = ref(x_data, y_data) func = relay.Function([x, y], z) for target, ctx in ctx_list(): # use graph by execuor default for testing, as we need # create function explicitly to avoid constant-folding. intrp = relay.create_executor("graph", ctx=ctx, target=target) op_res = intrp.evaluate(func)(x_data, y_data) np.testing.assert_allclose(op_res.asnumpy(), ref_res, rtol=0.01)
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)
def test_avg_pool2d_no_count_pad(): kh, kw = (4, 4) sh, sw = (2, 2) ph, pw = (2, 2) n = 1 (ic, ih, iw) = (3, 28, 28) (oc, oh, ow) = (3, 15, 15) dshape = (n, ic, ih, iw) x = relay.var("x", shape=dshape) y = relay.nn.avg_pool2d(x, pool_size=(kh, kw), strides=(sw, sw), padding=(ph, pw), count_include_pad=False) func = relay.Function([x], y) dtype = "float32" a_np = np.random.uniform(low=0.001, size=(n, ic, ih, iw)).astype(dtype) pad_np = np.zeros(shape=(n, ic, ih+2*ph, iw+2*pw)).astype(dtype) no_zero = (range(n), range(ic), (range(ph, ih+ph)), (range(pw, iw+pw))) pad_np[np.ix_(*no_zero)] = a_np b_np = np.zeros(shape=(n, oc, oh, ow)).astype(dtype) for i in range(oh): for j in range(ow): pad_count = np.sum(pad_np[:, :, i*sh:i*sh+kh, j*sw:j*sw+kw] > 0, axis=(2,3)) b_np[:,:,i,j] = np.sum(pad_np[:, :, i*sh:i*sh+kh, j*sw:j*sw+kw], axis=(2,3)) / np.maximum(pad_count, 1) ref_res = np.maximum(b_np, 0.0) data = a_np for target, ctx in ctx_list(): intrp1 = relay.create_executor("graph", ctx=ctx, target=target) op_res1 = intrp1.evaluate(func)(data) tvm.testing.assert_allclose(op_res1.asnumpy(), ref_res, rtol=1e-5, atol=1e-5)
def test_zeros_ones(): for op, ref in [(relay.zeros, np.zeros), (relay.ones, np.ones)]: y = op(shape=(124, 50), dtype="float64") yy = relay.ir_pass.infer_type(y) assert yy.checked_type == relay.TensorType((124, 50), "float64") intrp = create_executor() intrp_res = intrp.evaluate(y).asnumpy() np.testing.assert_allclose(intrp_res, ref((124, 50), 'float64'))
def check_eval(expr, args, expected_result, mod=None, rtol=1e-07): if mod is None: mod = relay.Module() ctx = tvm.context("llvm", 0) intrp = create_executor(mod=mod, ctx=ctx, target="llvm") result = intrp.evaluate(expr)(*args) np.testing.assert_allclose(result.asnumpy(), expected_result, rtol=rtol)
def verify(start, stop, step): ref_res = _mx_symbol(mx.nd, start, stop, step).asnumpy() mx_sym = _mx_symbol(mx.sym, start, stop, step) new_sym, _ = relay.frontend.from_mxnet(mx_sym, {}) for target, ctx in ctx_list(): for kind in ["graph", "debug"]: intrp = relay.create_executor(kind, ctx=ctx, target=target) op_res = intrp.evaluate(new_sym)() tvm.testing.assert_allclose(op_res.asnumpy(), ref_res)
def verify_expand_dims(dshape, dtype, oshape, axis, num_newaxis): x = relay.Var("x", relay.TensorType(dshape, dtype)) func = relay.Function([x], relay.expand_dims(x, axis, num_newaxis)) for target, ctx in ctx_list(): data = np.random.uniform(size=dshape).astype(dtype) ref_res = data.reshape(oshape) intrp = relay.create_executor("graph", ctx=ctx, target=target) op_res = intrp.evaluate(func)(data) np.testing.assert_allclose(op_res.asnumpy(), ref_res, rtol=0.01)
def test_extern_vitis_ai_resnet18(): """Test first part of Vitis-AI on-the-fly quantization runtime with ResNet 18 model""" if skip_test(): return dtype = "float32" ishape = (1, 3, 224, 224) mod, params = relay.testing.resnet.get_workload(num_layers=18, batch_size=1) ref_mod, params = relay.testing.resnet.get_workload(num_layers=18, batch_size=1) ref_ex = relay.create_executor("graph", mod=ref_mod, device=tvm.cpu(0)) i_data = np.random.uniform(0, 1, ishape).astype(dtype) ref_res = ref_ex.evaluate()(i_data, **params) verify_result( mod, {"data": i_data}, (1, 1000), ref_res.numpy(), tol=1e-5, params=params, dpu_target="DPUCADX8G", tvm_ops=4, )
def check_single_op(opfunc, ref): shape = (10, 4) dtype = 'float32' tp = relay.TensorType(shape, dtype) x = relay.var("x", tp) y = opfunc(x) # test printer assert ("{}(%x)".format(y.op.name)) in y.astext() # test type inference yy = run_infer_type(y) assert yy.checked_type == tp if ref is not None: data = np.random.rand(*shape).astype(dtype) ref_res = ref(data) func = relay.Function([x], y) for target, ctx in ctx_list(): # use graph by execuor default for testing, as we need # create function explicitly to avoid constant-folding. intrp = relay.create_executor("graph", ctx=ctx, target=target) op_res = intrp.evaluate(func)(data) np.testing.assert_allclose(op_res.asnumpy(), ref_res, rtol=0.01)
def __init__(self, do_aot, use_gpu, *args): assert isinstance(do_aot, bool) assert isinstance(use_gpu, bool) self.mod = Module() self.prelude = Prelude(self.mod) self.use_gpu = use_gpu self.context = tvm.gpu(0) if use_gpu else tvm.cpu(0) self.target = tvm.target.cuda() if use_gpu else tvm.target.create('llvm') self.executor = create_executor(mod=self.mod, ctx=self.context, target=self.target) self.parameters = [] self.forward_var = relay.GlobalVar('forward_var') # Set up forward pass. inputs, body, ret_type = self.compute(*args) self.inputs = inputs forward_compute = relay.Function(inputs + list([p[0] for p in self.parameters]), body, ret_type) self.mod[self.forward_var] = forward_compute self.mod['main'] = self.mod[self.forward_var] if do_aot: self.forward = aot.compile(self.forward_var, self.mod, ctx=self.context, tgt=self.target) else: self.forward = self.executor.evaluate(self.forward_var) self.args = [None] * len(inputs) + list([p[1] for p in self.parameters])
def test_tensorrt_not_compatible(): if skip_codegen_test(): return dtype = "float32" xshape = (1, 32, 14, 14) x_data = np.random.uniform(-1, 1, xshape).astype(dtype) x = relay.var("x", shape=(xshape), dtype=dtype) y = relay.add(x, x) z = relay.erf(y) out = relay.nn.relu(z) f = relay.Function([x], out) mod = tvm.IRModule() mod["main"] = f mod, config = tensorrt.partition_for_tensorrt(mod) for mode in ["graph", "vm"]: with tvm.transform.PassContext( opt_level=3, config={"relay.ext.tensorrt.options": config}): exec = relay.create_executor(mode, mod=mod, ctx=tvm.gpu(0), target="cuda") if not skip_runtime_test(): results = exec.evaluate()(x_data)
def verify_arange(start, stop, step): dtype = "float32" if start is None and step is None: x = relay.arange(relay.const(stop, dtype=dtype)) ref_res = np.arange(stop).astype(dtype) elif start is None: x = relay.arange(relay.const(stop, dtype=dtype), step=relay.const(step, dtype=dtype)) ref_res = np.arange(stop, step=step).astype(dtype) elif step is None: x = relay.arange(relay.const(start, dtype=dtype), relay.const(stop, dtype=dtype)) ref_res = np.arange(start, stop).astype(dtype) else: x = relay.arange( relay.const(start, dtype=dtype), relay.const(stop, dtype=dtype), relay.const(step, dtype=dtype)) ref_res = np.arange(start, stop, step).astype(dtype) func = relay.Function([], x) for target, ctx in ctx_list(): for kind in ["graph", "debug"]: intrp = relay.create_executor(kind, ctx=ctx, target=target) op_res = intrp.evaluate(func)() tvm.testing.assert_allclose(op_res.asnumpy(), ref_res, rtol=1e-5)
def test_extern_dnnl_mobilenet(): if not tvm.get_global_func("relay.ext.dnnl", True): print("skip because DNNL codegen is not available") return dtype = "float32" ishape = (1, 3, 224, 224) mod, params = relay.testing.mobilenet.get_workload(batch_size=1, dtype="float32") mod["main"] = relay.build_module.bind_params_by_name(mod["main"], params) mod = transform.AnnotateTarget("dnnl")(mod) mod = transform.PartitionGraph()(mod) i_data = np.random.uniform(0, 1, ishape).astype(dtype) ref_mod, params = relay.testing.mobilenet.get_workload(batch_size=1, dtype="float32") ref_ex = relay.create_executor("graph", mod=ref_mod, ctx=tvm.cpu(0)) ref_res = ref_ex.evaluate()(i_data, **params) check_result(mod, {"data": i_data}, (1, 1000), ref_res.asnumpy(), tol=1e-5, params=params)
def test_unary_identity(): for op, ref in [ (relay.zeros_like, np.zeros_like), (relay.ones_like, np.ones_like), (relay.ceil, np.ceil), (relay.floor, np.floor), (relay.trunc, np.trunc), (relay.round, np.round), (relay.abs, np.abs), (relay.copy, None), # np.copy (relay.negative, np.negative) ]: shape = (8, 9, 4) x = relay.var("x", relay.TensorType(shape, "float32")) y = op(x) yy = relay.ir_pass.infer_type(y) assert yy.checked_type == relay.TensorType(shape, "float32") if ref is not None: data = np.random.rand(*shape).astype('float32') intrp = create_executor() op_res = intrp.evaluate(y, {x: relay.const(data)}) ref_res = ref(data) np.testing.assert_allclose(op_res.asnumpy(), ref_res, rtol=0.01)
def test_add_tuple(): """Add elements of tuple. Check types and semantic equivalence.""" mod = tvm.IRModule() shape = (10, 10) dtype = 'float32' tensor_type = relay.TensorType(shape, dtype) t = relay.TupleType([tensor_type, tensor_type]) x = relay.var("x", t) # f((x1,x2)) = x1 + x2 y = relay.Function([x], relay.TupleGetItem(x, 0) + relay.TupleGetItem(x, 1)) mod["main"] = y mod = transform.LazyGradientInit()(mod) mod = tvm.transform.PrintIR(show_meta_data=True)(mod) y = mod["main"] assert mod["main"].checked_type == relay.FuncType([t], tensor_type) ex = create_executor(mod=mod) x = (rand(dtype, *shape), rand(dtype, *shape)) y = ex.evaluate(y)(x) assert_allclose(y.asnumpy(), x[0].asnumpy() + x[1].asnumpy())
def test_function_invalidate(): shape = () dtype = "bool" t = TensorType(shape, dtype) d = Var("d", t) r = Var("r") fetch = Function([], RefRead(r)) fet = Var("fetch") fet_obscured = Var("fetch_obscured") u = Var("u") body = If(d, fet_obscured(), fet_obscured()) body = Let(u, RefWrite(r, const(1)), body) body = Let(fet_obscured, If(d, fet, fet), body) body = Let(fet, fetch, body) body = Let(r, RefCreate(const(0)), body) f = Function([d], body) f = infer_type(f) pe_f = infer_type(partial_evaluate(f)) ex = create_executor() f_res = ex.evaluate(f)(const(True)) pe_f_res = ex.evaluate(pe_f)(const(True)) np.testing.assert_allclose(f_res.asnumpy(), np.ones_like(f_res.asnumpy())) np.testing.assert_allclose(pe_f_res.asnumpy(), np.ones_like(pe_f_res.asnumpy()))
def verify_dynamic_batch_matmul(x_shape, y_shape, out_shape, x_var_shape, y_var_shape, dtype="float32"): x = relay.var("x", relay.TensorType(x_var_shape, dtype)) y = relay.var("y", relay.TensorType(y_var_shape, dtype)) z = relay.nn.batch_matmul(x, y) func = relay.Function([x, y], z) x_np = np.random.uniform(size=x_shape).astype(dtype) y_np = np.random.uniform(size=y_shape).astype(dtype) z_np = tvm.topi.testing.batch_matmul(x_np, y_np) for target, dev in tvm.testing.enabled_targets(): for kind in ["vm", "debug"]: mod = tvm.ir.IRModule.from_expr(func) intrp = relay.create_executor(kind, mod=mod, device=dev, target=target) z = intrp.evaluate()(x_np, y_np) tvm.testing.assert_allclose(z.numpy(), z_np, rtol=1e-5)
def test_binary_int_broadcast(): for op, ref in [(relay.right_shift, np.right_shift), (relay.left_shift, np.left_shift), (relay.mod, np.mod), (relay.maximum, np.maximum), (relay.minimum, np.minimum)]: x = relay.var("x", relay.TensorType((10, 4), "int32")) y = relay.var("y", relay.TensorType((5, 10, 1), "int32")) z = op(x, y) zz = relay.ir_pass.infer_type(z) assert zz.checked_type == relay.TensorType((5, 10, 4), "int32") if ref is not None: x_shape = (10, 4) y_shape = (5, 10, 1) t1 = relay.TensorType(x_shape, 'int32') t2 = relay.TensorType(y_shape, 'int32') x_data = np.random.rand(*x_shape).astype(t1.dtype) y_data = np.random.rand(*y_shape).astype(t2.dtype) func = relay.Function([x, y], z) ref_res = ref(x_data, y_data) for target, ctx in ctx_list(): intrp = relay.create_executor("graph", ctx=ctx, target=target) op_res = intrp.evaluate(func)(x_data, y_data) tvm.testing.assert_allclose(op_res.asnumpy(), ref_res)
def verify_depth_to_space(dshape, block_size, layout, mode): if layout == "NHWC": out_shape = [ dshape[0], dshape[1] * block_size, dshape[2] * block_size, dshape[3] / (block_size * block_size) ] else: out_shape = [ dshape[0], dshape[1] / (block_size * block_size), dshape[2] * block_size, dshape[3] * block_size ] x_data = np.random.uniform(size=dshape).astype("float32") if layout == "NHWC": x_data = np.transpose(x_data, axes=[0, 3, 1, 2]) ref_res = topi.testing.depth_to_space_python(x_data, block_size, mode=mode) if layout == "NHWC": x_data = np.transpose(x_data, axes=[0, 2, 3, 1]) ref_res = np.transpose(ref_res, axes=[0, 2, 3, 1]) x = relay.var("x", relay.TensorType(dshape, "float32")) z = relay.nn.depth_to_space(x, block_size, layout, mode) assert "block_size=" in z.astext() zz = run_infer_type(z) assert zz.checked_type == relay.TensorType(ref_res.shape, "float32") func = relay.Function([x], z) for target, ctx in ctx_list(): for kind in ["graph", "debug"]: intrp = relay.create_executor(kind, ctx=ctx, target=target) op_res = intrp.evaluate(func)(x_data) tvm.testing.assert_allclose(op_res.asnumpy(), ref_res, rtol=1e-4)
def _test_global_pool2d(opfunc, reffunc): n, c, h, w = tvm.var("n"), tvm.var("c"), 224, 224 x = relay.var("x", relay.TensorType((n, h, w, c), "float32")) y = opfunc(x, layout="NHWC") yy = run_infer_type(y) assert yy.checked_type == relay.TensorType((n, 1, 1, c), "float32") n, c, h, w = tvm.var("n"), tvm.var("c"), tvm.var("h"), tvm.var("w") x = relay.var("x", relay.TensorType((n, c, h, w), "float32")) y = opfunc(x) yy = run_infer_type(y) assert yy.checked_type == relay.TensorType((n, c, 1, 1), "float32") # test execution dtype = "float32" dshape = (1, 1024, 7, 7) x = relay.var("x", shape=dshape) y = opfunc(x) func = relay.Function([x], y) data = np.random.uniform(size=dshape).astype(dtype) ref_res = reffunc(data, axis=(2,3), keepdims=True) for target, ctx in ctx_list(): intrp1 = relay.create_executor("graph", ctx=ctx, target=target) op_res1 = intrp1.evaluate(func)(data) tvm.testing.assert_allclose(op_res1.asnumpy(), ref_res, rtol=1e-5, atol=1e-5)
def verify_unravel_index(indices, shape, dtype): x_data = np.array(indices).astype(dtype) y_data = np.array(shape).astype(dtype) x = relay.var("x", relay.TensorType(x_data.shape, dtype)) y = relay.var("y", relay.TensorType(y_data.shape, dtype)) z = relay.unravel_index(x, y) zz = run_infer_type(z) if len(x_data.shape) == 1: out_shape = [y_data.shape[0], x_data.shape[0]] else: out_shape = [y_data.shape[0]] assert zz.checked_type == relay.ty.TensorType(out_shape, dtype) func = relay.Function([x, y], z) ref_res = np.unravel_index(x_data, y_data) for target, ctx in tvm.testing.enabled_targets(): for kind in ["graph", "debug"]: intrp = relay.create_executor(kind, ctx=ctx, target=target) op_res = intrp.evaluate(func)(x_data, y_data) tvm.testing.assert_allclose(op_res.asnumpy(), ref_res, rtol=1e-5)
def run_and_compare(mod, params, pt_result, target, device): exec_res = relay.create_executor("vm", mod=mod, device=device, target=target).evaluate()(**params) def flatten(nested): res = [] for r in nested: if isinstance(r, torch.Tensor): res.append(r) else: res.extend(flatten(r)) return res if isinstance(exec_res, tvm.runtime.container.ADT): assert not isinstance(pt_result, torch.Tensor) tvm_res = vmobj_to_list(exec_res) torch_res = flatten(pt_result) else: tvm_res = exec_res torch_res = pt_result assert_equal(tvm_res, torch_res)
def test_ret_tuple(): """Test tuple return type. Check types and semantic equivalence.""" mod = tvm.IRModule() shape = (10, 10) dtype = 'float32' t = relay.TensorType(shape, dtype) x = relay.var("x", t) # f(x) = (x,x) func = relay.Function([x], relay.Tuple([x,x * relay.const(2.0)])) func = run_infer_type(func) mod["main"] = func mod = transform.LazyGradientInit()(mod) func = mod["main"] assert mod["main"].checked_type == relay.FuncType([t], relay.TupleType([t, t])) ex = create_executor(mod=mod) x = rand(dtype, *shape) y = ex.evaluate(func)(x) assert_allclose(y[0].asnumpy(), x.asnumpy()) assert_allclose(y[1].asnumpy(), x.asnumpy() * 2.0)
def test_extern_dnnl_mobilenet(): if not tvm.get_global_func("relay.ext.dnnl", True): print("skip because DNNL codegen is not available") return dtype = 'float32' ishape = (1, 3, 224, 224) mod, params = relay.testing.mobilenet.get_workload(batch_size=1, dtype='float32') op_list = ["nn.conv2d", "nn.dense", "nn.relu", "add"] mod = WhiteListAnnotator(op_list, "dnnl")(mod) mod = transform.PartitionGraph()(mod) i_data = np.random.uniform(0, 1, ishape).astype(dtype) ref_mod, params = relay.testing.mobilenet.get_workload(batch_size=1, dtype='float32') ref_ex = relay.create_executor("graph", mod=ref_mod, ctx=tvm.cpu(0)) ref_res = ref_ex.evaluate()(i_data, **params) check_result(mod, {"data": i_data}, (1, 1000), ref_res.asnumpy(), tol=1e-5, params=params)
def test_recursive_concat(): """ fn @concat_loop(%i: int32, %st: (any, 1)) -> (any, 1) { if (%i < 10) { let %i = reshape(cast(i, "float32"), newshape=(1, )) let %new_st = concatenate((st, i), axis=0) concat_loop(%i + 1, ) } else { st } } """ # Initial Values. i = relay.var('i', shape=(), dtype='int32') st = relay.var('st', shape=(relay.Any(), 1), dtype='int32') def _cond(i, st): return relay.op.min(relay.op.less(i, int32(10))) def _body(i, st): i_vec = relay.op.reshape(i, (1, 1)) ret = relay.op.concatenate([st, i_vec], axis=0) return i + int32(1), ret loop = while_loop(_cond, [i, st], _body) start = relay.var('start', shape=(), dtype='int32') body = loop(start, relay.op.reshape(relay.const(0), newshape=(1, 1))) func = relay.Function([start], relay.TupleGetItem(body, 1)) mod = tvm.IRModule() mod["main"] = func data = np.array(0.0, dtype='int32') ref = np.array([0] + list(range(10))).reshape((11, 1)).astype("int32") for kind in ["debug", "vm"]: ex = relay.create_executor(kind, mod=mod, ctx=tvm.cpu(), target="llvm") result = ex.evaluate()(data) np.testing.assert_allclose(result.asnumpy(), ref)
def test_binary_int_broadcast_1(): for op, ref in [(relay.right_shift, np.right_shift), (relay.left_shift, np.left_shift)]: x = relay.var("x", relay.TensorType((10, 4), "int32")) y = relay.var("y", relay.TensorType((5, 10, 1), "int32")) z = op(x, y) zz = run_infer_type(z) assert zz.checked_type == relay.TensorType((5, 10, 4), "int32") if ref is not None: x_shape = (10, 4) y_shape = (5, 10, 1) t1 = relay.TensorType(x_shape, "int32") t2 = relay.TensorType(y_shape, "int32") x_data = np.random.randint(1, 10000, size=(x_shape)).astype(t1.dtype) y_data = np.random.randint(1, 31, size=(y_shape)).astype(t2.dtype) func = relay.Function([x, y], z) ref_res = ref(x_data, y_data) for target, ctx in tvm.testing.enabled_targets(): intrp = relay.create_executor("graph", ctx=ctx, target=target) op_res = intrp.evaluate(func)(x_data, y_data) tvm.testing.assert_allclose(op_res.asnumpy(), ref_res)
def check_binary_op(opfunc, ref): s = (5, 10, 5) t = relay.TensorType((5, 10, 5)) x = relay.var("x", t) y = relay.var("y", t) z = opfunc(x, y) x_data = np.random.rand(*s).astype(t.dtype) y_data = np.random.rand(*s).astype(t.dtype) ref_grad0, ref_grad1 = ref(x_data, y_data) fwd_func = relay.Function([x, y], z) fwd_func = run_infer_type(fwd_func) bwd_func = run_infer_type(gradient(fwd_func)) for target, ctx in ctx_list(): intrp = relay.create_executor(ctx=ctx, target=target) op_res, (op_grad0, op_grad1) = intrp.evaluate(bwd_func)(x_data, y_data) np.testing.assert_allclose(op_grad0.asnumpy(), ref_grad0, rtol=0.01) np.testing.assert_allclose(op_grad1.asnumpy(), ref_grad1, rtol=0.01)
def verify_topk(k, axis, ret_type, is_ascend, dtype): shape = (20, 100) x = relay.var("x", relay.TensorType(shape, "float32")) out = relay.topk(x, k, axis, ret_type, is_ascend, dtype) if isinstance(out, relay.expr.TupleWrapper): out = out.astuple() func = relay.Function([x], out) np_data = np.random.uniform(size=shape).astype("float32") if is_ascend: np_indices = np.argsort(np_data, axis=axis) else: np_indices = np.argsort(-np_data, axis=axis) kk = k if k >= 1 else shape[axis] if axis == 0: np_indices = np_indices[:kk, :] np_values = np.zeros(np_indices.shape).astype("float32") for i in range(shape[1]): np_values[:, i] = np_data[np_indices[:, i], i] else: np_indices = np_indices[:, :kk] np_values = np.zeros(np_indices.shape).astype("float32") for i in range(shape[0]): np_values[i, :] = np_data[i, np_indices[i, :]] np_indices = np_indices.astype(dtype) for target, dev in tvm.testing.enabled_targets(): for kind in ["graph", "debug"]: intrp = relay.create_executor(kind, device=dev, target=target) op_res = intrp.evaluate(func)(np_data) if ret_type == "both": tvm.testing.assert_allclose(op_res[0].numpy(), np_values) tvm.testing.assert_allclose(op_res[1].numpy(), np_indices) elif ret_type == "values": tvm.testing.assert_allclose(op_res.numpy(), np_values) else: tvm.testing.assert_allclose(op_res.numpy(), np_indices)
def check_result(args, mod, expected, flatten=False, assert_shape=False, only_vm=False): for kind in ["debug", "vm"]: for tgt, ctx in tvm.testing.enabled_targets(): if kind == "debug" and (only_vm or ctx.device_type != tvm.cpu().device_type): continue ex = relay.create_executor(kind, mod=mod, ctx=ctx, target=tgt) result = ex.evaluate()(*args) result = result.asnumpy() if assert_shape: assert result.shape == expected, \ "Shape mismatch: expect %s but got %s." \ % (str(expected), str(result.shape)) return if flatten: result = result.flatten() expected = expected.flatten() tvm.testing.assert_allclose(result, expected)
def verify_global_avg_pool2d_grad(x_shape): x = relay.var("x", relay.TensorType(x_shape, "float32")) y = tvm.relay.nn.global_avg_pool2d(x) fwd_func = relay.Function([x], y) fwd_func = run_infer_type(fwd_func) bwd_func = run_infer_type(gradient(fwd_func)) data = np.random.rand(*x_shape).astype("float32") y_shape = topi.util.get_const_tuple(fwd_func.ret_type.shape) out_grad = np.ones(shape=y_shape) ref_grad = tvm.topi.testing.pool_grad_nchw(data, out_grad, pool_size=(x_shape[2], x_shape[3]), strides=(1, 1), padding=[0, 0, 0, 0], pool_type='avg', ceil_mode=False) for target, ctx in ctx_list(): intrp = relay.create_executor(ctx=ctx, target=target) op_res, (op_grad, ) = intrp.evaluate(bwd_func)(data) np.testing.assert_allclose(op_grad.asnumpy(), ref_grad, rtol=0.01)
def _eval_mod(mod): vm = relay.create_executor('vm', ctx=tvm.cpu(0), target='llvm', mod=mod) return vm.evaluate()(*params)
def manual_tir_common(do_tune=False): M, N, K = 1024, 1024, 1024 # pylint: disable=invalid-name data_shape = (M, K) weight_shape = (N, K) data_dtype = "uint8" data = relay.var("data", shape=data_shape, dtype=data_dtype) weight = relay.var("weight", shape=weight_shape, dtype="int8") bias = relay.var("bias", shape=(weight_shape[0], ), dtype="int32") # dense is tuned by the TIR schedule above, bmm is scheduled by TE (topi/x86/batch_matmul.py) dense = relay.nn.dense(data, weight, out_dtype="int32") bias_add = relay.nn.bias_add(dense, bias) + relay.const(1, dtype="int32") out = relay.nn.batch_matmul( relay.cast(relay.expand_dims(bias_add, 0), "uint8"), relay.cast(relay.expand_dims(bias_add, 0), "int8"), out_dtype="int32", ) relay_mod = tvm.IRModule.from_expr(out) target = "llvm -mcpu=cascadelake -num-cores 4" dev = tvm.device(target, 0) data = np.random.uniform(1, 10, size=(M, K)).astype("uint8") weight_np = np.random.uniform(1, 10, size=weight_shape).astype("int8") bias_np = np.random.uniform(1, 10, size=(weight_shape[0], )).astype("int32") ref = (relay.create_executor( "vm", mod=relay_mod, device=dev, target=target).evaluate()(*[data, weight_np, bias_np]).numpy()) params = {"weight": weight_np, "bias": bias_np} if do_tune: extracted_tasks = extract_task_from_relay(relay_mod, target, params) # Filter out tasks that we don't intend to schedule / tune with TIR. tune_tasks = list( filter( lambda task: "dense" in task.task_name, extracted_tasks, )) config = TuneConfig( strategy="replay_trace", num_trials_per_iter=64, max_trials_per_task=20000, max_trials_global=20000, ) with tempfile.TemporaryDirectory() as work_dir: # postprocs=lambda: [] is important to prevent default post processors from # tampering with the manual schedule. database = tune_extracted_tasks( tune_tasks, config, work_dir=work_dir, postprocs=lambda: [], ) else: def schedule_fn(task, sch): if "dense" not in task.task_name: return False block = sch.get_block("compute") # Looks up schedule_rule annotation. # See the comment in test_tune_relay_manual_tir_vnni(). schedule_rule = sch.get(block).annotations["schedule_rule"] assert "dense_vnni" in schedule_rule schedule_dense(block, M, False, sch) return True database = apply_fixed_schedules(relay_mod, target, params, schedule_fn) with ApplyHistoryBest(database): with tvm.transform.PassContext( opt_level=3, config={"relay.backend.use_meta_schedule": True}, ): # pylint: disable=W0105 """ The log should say Warning: Cannot find workload: tvmgen_default_fused_expand_dims Warning: Cannot find workload: tvmgen_default_fused_cast Warning: Cannot find workload: tvmgen_default_fused_cast_1 Warning: Cannot find workload: tvmgen_default_fused_nn_batch_matmul This means batch matmul and others are scheduled by TE, and dense (the one not warned) is found in the meta schedule tuning database during ApplyHistoryBest """ # pylint: enable=W0105 lib = relay.build(relay_mod, target=target, params=params) runtime = tvm.contrib.graph_executor.GraphModule(lib["default"](dev)) runtime.set_input("data", data) runtime.run() out = runtime.get_output(0).numpy() np.testing.assert_equal(out, ref)
def convert_ndarray(dst_dtype, array): """Converts an NDArray into the specified datatype""" x = relay.var("x", shape=array.shape, dtype=str(array.dtype)) cast = relay.Function([x], x.astype(dst_dtype)) with tvm.transform.PassContext(config={"tir.disable_vectorize": True}): return relay.create_executor("graph").evaluate(cast)(array)
###################################################################### # Now, we create random inputs to feed into this program using numpy: import numpy as np np.random.seed(23) # for reproducibility x_input = np.random.rand(3).astype("float32") y_input = np.random.rand(3).astype("float32") print("x: {}".format(x_input)) print("y: {}".format(y_input)) ###################################################################### # Finally, we're ready to run the program: ex = relay.create_executor(mod=module) z_output = ex.evaluate()(x_input, y_input) print("z: {}".format(z_output)) ###################################################################### # Adding Custom Datatypes # ----------------------- # Now, we will do the same, but we will use a custom datatype for our intermediate computation. # # We use the same input variables ``x`` and ``y`` as above, but before adding ``x + y``, we first cast both ``x`` and ``y`` to a custom datatype via the ``relay.cast(...)`` call. # # Note how we specify the custom datatype: we indicate it using the special ``custom[...]`` syntax. # Additionally, note the "32" after the datatype: this is the bitwidth of the custom datatype. This tells TVM that each instance of ``myfloat`` is 32 bits wide. try:
def check_grad(func, inputs=None, eps=1e-6, atol=1e-5, rtol=1e-3, scale=None, mean=0): """Perform numerical gradient checking given a relay function. Compare analytical gradients to numerical gradients derived from two-sided approximation. Note that this test may fail if your function input types are not of high enough precision. Parameters ---------- func : tvm.relay.Function The relay function to test. inputs: List[np.array] Optional user-provided input parameters to use. If not given, will generate random normal inputs scaled to be close to the chosen epsilon value to avoid numerical precision loss. eps: float The epsilon value to use for computing numerical gradient approximation. atol: float The absolute tolerance on difference between numerical and analytical gradients. Note that this needs to be scaled appropriately relative to the chosen eps and inputs. rtol: float The relative tolerance on difference between numerical and analytical gradients. Note that this needs to be scaled appropriately relative to the chosen eps. scale: float The standard deviation of the inputs. mean: float The mean of the inputs. """ fwd_func = run_infer_type(func) bwd_func = run_infer_type(gradient(fwd_func)) if scale is None: scale = 10 * eps if inputs is None: params = fwd_func.params # Generate random inputs on the same scale as epsilon to avoid numerical precision loss. inputs = [ _np_randn_from_type(x.checked_type, scale=scale, mean=mean) for x in params ] for target, ctx in ctx_list(): intrp = relay.create_executor(ctx=ctx, target=target) # Get analytic gradients. _, grads = intrp.evaluate(bwd_func)(*inputs) grads = [grad.asnumpy().astype("float64") for grad in grads] # Get numeric gradients for each dimension of each param, using two-sided approximation. approx_grads = [] for x in inputs: approx_grad = np.zeros(x.shape) for i in np.ndindex(*x.shape): x_i = x[i] x[i] = x_i + eps fwd_plus = intrp.evaluate(fwd_func)( *inputs).asnumpy().astype("float64") x[i] = x_i - eps fwd_minus = intrp.evaluate(fwd_func)( *inputs).asnumpy().astype("float64") x[i] = x_i approx_grad[i] = np.sum((fwd_plus - fwd_minus) / (2 * eps)) approx_grads.append(approx_grad) # Compare gradients by checking that relative difference is below tolerance. for grad, approx_grad in zip(grads, approx_grads): np.testing.assert_allclose(grad, approx_grad, atol=atol, rtol=rtol)
def test_alter_layout_strided_slice(): """Test rewriting strided_slice during alter_iop_layout""" def before(): x = relay.var("x", shape=(1, 32, 28, 28)) weight = relay.var('weight', shape=(32, 32, 3, 3)) y = relay.nn.conv2d(x, weight, channels=32, kernel_size=(3, 3), padding=(1, 1)) y = relay.strided_slice(y, begin=relay.const([0, 16], "int32"), end=relay.const([1, 33], "int32"), strides=relay.const([1, 1], "int32")) y = relay.Function(analysis.free_vars(y), y) return y def alter_conv2d(attrs, inputs, tinfos, out_type): data, weight = inputs new_attrs = dict(attrs) new_attrs['data_layout'] = 'NCHW4c' return relay.nn.conv2d(data, weight, **new_attrs) def expected(): x = relay.var("x", shape=(1, 32, 28, 28)) weight = relay.var("weight", shape=(32, 32, 3, 3)) weight = relay.layout_transform(weight, "OIHW", "OIHW4i4o") x = relay.layout_transform(x, "NCHW", "NCHW4c") y = relay.op.nn.contrib_conv2d_nchwc(x, weight, channels=32, kernel_size=(3, 3), padding=(1, 1), data_layout="NCHW4c") y = relay.strided_slice(y, begin=relay.const([0, 4], "int32"), end=relay.const([1, 21], "int32"), strides=relay.const([1, 1], "int32")) y = relay.layout_transform(y, "NCHW4c", "NCHW") y = relay.Function(analysis.free_vars(y), y) return y with TempOpAttr("nn.conv2d", "FTVMAlterOpLayout", alter_conv2d): a = before() b = run_opt_pass(expected(), transform.InferType()) # Verify inference result mod_before = tvm.IRModule() mod_new = tvm.IRModule() mod_before['main'] = a mod_new['main'] = b with relay.build_config(opt_level=3): for target, ctx in ctx_list(): for kind in ["graph", "debug", "vm"]: ex_before = relay.create_executor(kind, mod=mod_before, ctx=ctx, target=target) ex_new = relay.create_executor(kind, mod=mod_new, ctx=ctx, target=target) np_data = np.random.uniform(size=(1, 32, 28, 28)).astype("float32") np_weight = np.random.uniform(size=(32, 32, 3, 3)).astype("float32") result_before = ex_before.evaluate()(np_data, np_weight) result_new = ex_new.evaluate()(np_data, np_weight) tvm.testing.assert_allclose(result_before.asnumpy(), result_new.asnumpy(), rtol=1e-5, atol=1e-5)
def check_eval(expr, expected_result, mod=None, rtol=1e-07): ctx = tvm.context("llvm", 0) intrp = create_executor(mod=mod, ctx=ctx, target="llvm") result = intrp.evaluate(expr) np.testing.assert_allclose(result.asnumpy(), expected_result, rtol=rtol)