JiaruiWang-Jill opened a new issue #8087: URL: https://github.com/apache/tvm/issues/8087
@hzfan and I found `topi.nn.conv2d_transpose_nchw` and `te.gradient` behave strange when they are combined together and kernel's (height, width)=(1, 1). For instance, ``` X = te.placeholder((8, 3, 32, 32), name="X") W = te.placeholder((3, 16, 1, 1), name="W") R = topi.nn.conv2d_transpose_nchw(X, W, (2,2), (1,1), "float32", (1,1)) ``` Under our testing, test result shows ``` 38% of elements differ, first 10 of wrong positions: [(0, 1, 11, 30), (0, 1, 12, 4), (0, 1, 12, 8), (0, 1, 12, 12), (0, 1, 12, 16), (0, 1, 12, 20), (0, 1, 15, 2), (0, 1, 15, 3), (0, 1, 15, 6), (0, 1, 15, 7)] distance > atol*sqrt(n) + rtol*grad_norm distance 275.2369689941406 > 0.01*156.76734353812338 + 0.1*1753.1251220703125 ``` Please see the following lines for python test. ``` import numpy as np import random import tvm from tvm import topi from tvm import te from tvm.testing import assert_allclose from tvm.topi.utils import get_const_tuple random.seed(2) # check_grad function refers to https://github.com/apache/tvm/blob/main/tests/python/unittest/test_te_autodiff.py def check_grad( out, inputs, args=[], data_range=(-10, 10), desired_grads=None, assert_no_jacobian=True ): inputs = inputs if isinstance(inputs, list) else [inputs] def check_device(device, host="llvm"): dev = tvm.device(device, 0) if not tvm.testing.device_enabled(host): return sout = te.create_schedule(out.op) mout = tvm.build(sout, [out] + inputs + args) out_shape = get_const_tuple(out.shape) l, h = data_range input_data = [ tvm.nd.array( np.random.uniform(l, h, size=get_const_tuple(input.shape)).astype(input.dtype) ) for input in inputs ] arg_vals = [ tvm.nd.array(np.random.uniform(l, h, size=get_const_tuple(arg.shape)).astype(arg.dtype)) for arg in args ] ones = topi.full_like(out, 1.0) grads = te.gradient(out, inputs, head=ones) grad_sched = te.create_schedule([grad.op for grad in grads]) mgrad = tvm.build(grad_sched, list(grads) + inputs + args) if assert_no_jacobian: lowered_ir = str(tvm.lower(grad_sched, list(grads) + inputs + args, simple_mode=True)) assert "jacobian" not in lowered_ir, lowered_ir grad_data = [tvm.nd.empty(get_const_tuple(i.shape), g.dtype) for i, g in zip(inputs, grads)] mgrad(*grad_data, *input_data, *arg_vals) g_res = [g.asnumpy() for g in grad_data] if desired_grads: assert isinstance(desired_grads, list) for actual, desired in zip(g_res, desired_grads): assert_allclose(actual, desired, rtol=0.1, atol=1e-2) else: def forward(*in_data): out_data = tvm.nd.empty(out_shape, out.dtype) mout(out_data, *[tvm.nd.array(d) for d in list(in_data)]) return out_data.asnumpy().sum() tvm.testing.check_numerical_grads( forward, [d.asnumpy() for d in input_data + arg_vals], g_res ) check_device("cpu") X = te.placeholder((8, 3, 32, 32), name="X") W = te.placeholder((3, 16, 1, 1), name="W") R = topi.nn.conv2d_transpose_nchw(X, W, (2,2), (1,1), "float32", (1,1)) check_grad(R, [X, W]) ``` -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: [email protected]
