From 469ae670861e073f69ed9a64cafa7eeedf425d90 Mon Sep 17 00:00:00 2001 From: Lily Orth-Smith Date: Fri, 21 Aug 2020 18:03:43 -0700 Subject: [PATCH] [BUG_FIX] Fix resize test (#6298) * fix resize tests * add different scale to resize tests * fix dynamic to static resize test * fix error throwing in topi resize * fix topi and importer tests * fix lint * flakey test failed * make resize test less sensitive; had floating point rounding err on gpu * remove nearest_neighbor + half_pixel option from pytorch importer * remove nearest_neighbor + half_pixel in upsample3d --- python/tvm/relay/frontend/onnx.py | 5 ++++- python/tvm/relay/frontend/pytorch.py | 8 ++++++-- python/tvm/topi/image/resize.py | 5 ++++- .../relay/dyn/test_dynamic_op_level5.py | 8 +++++++- tests/python/relay/test_op_level5.py | 19 ++++++++++++------- .../relay/test_pass_dynamic_to_static.py | 4 +++- tests/python/topi/python/test_topi_image.py | 3 +++ 7 files changed, 39 insertions(+), 13 deletions(-) diff --git a/python/tvm/relay/frontend/onnx.py b/python/tvm/relay/frontend/onnx.py index bc44431df3eba..952f6675c8742 100644 --- a/python/tvm/relay/frontend/onnx.py +++ b/python/tvm/relay/frontend/onnx.py @@ -937,7 +937,10 @@ def _impl_v9(cls, inputs, attr, params): else: assert len(scales) == 4 attr['layout'] = 'NCHW' - attr['align_corners'] = True + if method == 'nearest_neighbor': + attr['align_corners'] = False + else: + attr['align_corners'] = True op_name = 'upsampling' return AttrCvt(op_name)(inputs, attr) diff --git a/python/tvm/relay/frontend/pytorch.py b/python/tvm/relay/frontend/pytorch.py index 8725a64a689c3..b75f3f909b937 100644 --- a/python/tvm/relay/frontend/pytorch.py +++ b/python/tvm/relay/frontend/pytorch.py @@ -1539,7 +1539,9 @@ def _impl(inputs, input_types): else: align_corners = False - if align_corners: + if method == "nearest_neighbor": + coord_trans = "asymmetric" + elif align_corners: coord_trans = "align_corners" else: coord_trans = "half_pixel" @@ -1584,7 +1586,9 @@ def _impl(inputs, input_types): else: align_corners = False - if align_corners: + if method == "nearest_neighbor": + coord_trans = "asymmetric" + elif align_corners: coord_trans = "align_corners" else: coord_trans = "half_pixel" diff --git a/python/tvm/topi/image/resize.py b/python/tvm/topi/image/resize.py index aab3009bd922c..25258925aa373 100644 --- a/python/tvm/topi/image/resize.py +++ b/python/tvm/topi/image/resize.py @@ -529,8 +529,11 @@ def resize(data, size, layout="NCHW", method="bilinear", or [batch, in_height*scale, in_width*scale, channel] or 5-D with shape [batch, channel-major, in_height*scale, in_width*scale, channel-minor] """ - method = method.lower() + if method == "nearest_neighbor" and coordinate_transformation_mode != "asymmetric": + raise ValueError('Topi Resize does not support the combination of method %s ' \ + 'and coordinate_transformation_mode %s' % + (method, coordinate_transformation_mode)) if layout == 'NHWC': in_n, in_h, in_w, in_c = data.shape if output_shape is None: diff --git a/tests/python/relay/dyn/test_dynamic_op_level5.py b/tests/python/relay/dyn/test_dynamic_op_level5.py index f0095a1f03c91..8dcfd1fd5778a 100644 --- a/tests/python/relay/dyn/test_dynamic_op_level5.py +++ b/tests/python/relay/dyn/test_dynamic_op_level5.py @@ -49,7 +49,11 @@ def verify_resize(dshape, scale, method, layout): ref_res = tvm.topi.testing.upsampling_python(x_data, (scale, scale), layout) x = relay.var("x", relay.TensorType(dshape, "float32")) size_var = relay.var("size", relay.TensorType((2,), "int64")) - z = relay.image.resize(x, size_var, layout, method, "align_corners") + + coord_trans = "asymmetric" if method == "nearest_neighbor" else "align_corners" + z = relay.image.resize(x, size_var, layout, method, + coordinate_transformation_mode=coord_trans) + zz = run_infer_type(z) func = relay.Function([x, size_var], z) @@ -60,9 +64,11 @@ def verify_resize(dshape, scale, method, layout): intrp = relay.create_executor(kind, mod=mod, ctx=ctx, target=target) op_res = intrp.evaluate()(x_data, size) tvm.testing.assert_allclose(op_res.asnumpy(), ref_res, rtol=1e-4, atol=1e-6) + for method in ["bilinear", "nearest_neighbor"]: for layout in ["NCHW", "NHWC"]: verify_resize((1, 4, 4, 4), 2, method, layout) + verify_resize((2, 8, 17, 20), 7, method, layout) if __name__ == "__main__": test_resize_infer_type() diff --git a/tests/python/relay/test_op_level5.py b/tests/python/relay/test_op_level5.py index 70678031156db..254bab5e1692e 100644 --- a/tests/python/relay/test_op_level5.py +++ b/tests/python/relay/test_op_level5.py @@ -41,19 +41,21 @@ def test_resize_infer_type(): assert zz.checked_type == relay.TensorType((n, c, 100, 200), "int8") def test_resize(): - def verify_resize(dshape, scale, method, layout): + def verify_resize(dshape, scale, method, layout, coord_trans): if layout == "NHWC": size = (dshape[1] * scale, dshape[2] * scale) else: size = (dshape[2] * scale, dshape[3] * scale) x_data = np.random.uniform(size=dshape).astype("float32") + if method == "bilinear": - ref_res = tvm.topi.testing.bilinear_resize_python(x_data, size, layout) + ref_res = tvm.topi.testing.bilinear_resize_python(x_data, size, layout, coord_trans) else: ref_res = tvm.topi.testing.upsampling_python(x_data, (scale, scale), layout) x = relay.var("x", relay.TensorType(dshape, "float32")) - z = relay.image.resize(x, size, layout, method, "align_corners") + z = relay.image.resize(x, size, layout, method, + coordinate_transformation_mode=coord_trans) assert "size=" in z.astext() zz = run_infer_type(z) assert zz.checked_type == relay.TensorType(ref_res.shape, "float32") @@ -63,10 +65,13 @@ def verify_resize(dshape, scale, method, layout): 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, atol=1e-6) - for method in ["bilinear", "nearest_neighbor"]: - for layout in ["NHWC", "NCHW"]: - verify_resize((1, 4, 4, 4), 2, method, layout) + tvm.testing.assert_allclose(op_res.asnumpy(), ref_res, rtol=1e-4, atol=1e-5) + + for layout in ["NHWC", "NCHW"]: + verify_resize((1, 4, 4, 4), 2, "bilinear", layout, "align_corners") + verify_resize((2, 8, 17, 20), 3, "bilinear", layout, "half_pixel") + verify_resize((2, 8, 17, 20), 3, "bilinear", layout, "asymmetric") + verify_resize((3, 4, 5, 6), 5, "nearest_neighbor", layout, "asymmetric") def test_resize3d_infer_type(): n, c, d, h, w = te.size_var("n"), te.size_var("c"), te.size_var("d"), te.size_var("h"), te.size_var("w") diff --git a/tests/python/relay/test_pass_dynamic_to_static.py b/tests/python/relay/test_pass_dynamic_to_static.py index c47d9596c7868..6b422ca0d5947 100644 --- a/tests/python/relay/test_pass_dynamic_to_static.py +++ b/tests/python/relay/test_pass_dynamic_to_static.py @@ -250,7 +250,9 @@ def verify_resize(shape, scale, method, layout): x = relay.var("x", relay.TensorType(shape, "float32")) size_var = relay.const(np.array(size).astype("float32")) - z = relay.image.resize(x, size_var, layout, method, "align_corners") + coord_trans = "asymmetric" if method == "nearest_neighbor" else "align_corners" + z = relay.image.resize(x, size_var, layout, method, + coordinate_transformation_mode=coord_trans) func = run_infer_type(relay.Function([x], z)) func2 = run_opt_pass(run_opt_pass(func, transform.DynamicToStatic()), diff --git a/tests/python/topi/python/test_topi_image.py b/tests/python/topi/python/test_topi_image.py index 8d0092901c5c6..7fce69d2300c2 100644 --- a/tests/python/topi/python/test_topi_image.py +++ b/tests/python/topi/python/test_topi_image.py @@ -81,6 +81,9 @@ def test_resize(): # half_pixel verify_resize(4, 16, 16, 16, 32, 32, 'NCHW', "half_pixel", method="bilinear") verify_resize(4, 16, 16, 16, 32, 32, 'NHWC', "half_pixel", method="bilinear") + # Bilinear + Fractional + verify_resize(4, 16, 32, 32, 50, 50, 'NCHW', "asymmetric", method="bilinear") + verify_resize(4, 16, 32, 32, 50, 50, 'NHWC', "asymmetric", method="bilinear") def verify_resize3d(batch, in_channel, in_depth, in_height, in_width, out_depth, out_height, out_width,