From 9371a8685f2a32c906ed492b0694044695c4a890 Mon Sep 17 00:00:00 2001 From: Luke Hutton Date: Tue, 28 Mar 2023 16:47:05 +0000 Subject: [PATCH] [ETHOSN] Remove requantize dependency on resize A following requantize operation can instead be offloaded as a standalone operation, leaving to the support library to optimize. Change-Id: I573d8d67bcdf54f23d4c73ea70dbbe3f0c9be9cb --- python/tvm/relay/op/contrib/ethosn.py | 6 +-- .../backend/contrib/ethosn/ethosn_api.cc | 45 +++++++------------ .../python/contrib/test_ethosn/test_resize.py | 24 +--------- 3 files changed, 18 insertions(+), 57 deletions(-) diff --git a/python/tvm/relay/op/contrib/ethosn.py b/python/tvm/relay/op/contrib/ethosn.py index 7acaee9706c2..81534d48a216 100644 --- a/python/tvm/relay/op/contrib/ethosn.py +++ b/python/tvm/relay/op/contrib/ethosn.py @@ -206,11 +206,7 @@ def qnn_requantize_pattern(): return pattern def qnn_resize_pattern(): - pattern = is_op("image.resize2d")(wildcard()).has_attr({"method": "nearest_neighbor"}) - pattern = is_op("qnn.requantize")( - pattern, is_constant(), is_constant(), is_constant(), is_constant() - ) - return pattern + return is_op("image.resize2d")(wildcard()).has_attr({"method": "nearest_neighbor"}) def qnn_mul_pattern(): """ diff --git a/src/relay/backend/contrib/ethosn/ethosn_api.cc b/src/relay/backend/contrib/ethosn/ethosn_api.cc index c0f8767a8c65..a3f3e6e1eb6e 100644 --- a/src/relay/backend/contrib/ethosn/ethosn_api.cc +++ b/src/relay/backend/contrib/ethosn/ethosn_api.cc @@ -838,40 +838,27 @@ EthosnError EthosnAPI::ReinterpretQuantize(const Expr& expr, } EthosnError EthosnAPI::Resize(const Expr& expr, ResizeParams* params) { - Call requantize = Downcast(expr); - Call resize = Downcast(requantize->args[0]); + Call resize = Downcast(expr); + const auto* input_ttype = resize->args[0]->checked_type().as(); + + const auto* attrs = resize->attrs.as(); + uint32_t height, width; + EthosnError err = Tvm2Npu(attrs->size, &height, &width); + params->resize_info = sl::ResizeInfo{sl::ResizeAlgorithm::NEAREST_NEIGHBOUR, height, width, + params->input_info.m_QuantizationInfo}; - const auto* input_dtype = resize->args[0]->checked_type().as(); sl::TensorShape input_tensor_shape = {1, 1, 1, 1}; - EthosnError err = Tvm2Npu(input_dtype->shape, &input_tensor_shape); sl::DataType input_tensor_dtype; - err += Tvm2Npu(input_dtype->dtype, &input_tensor_dtype); - float input_sc; - int input_zp; - err += AsConstant(requantize->args[2], &input_zp); - err += AsConstant(requantize->args[1], &input_sc); - sl::QuantizationInfo input_q_info; - err += Tvm2Npu(input_zp, input_sc, &input_q_info); + err = Tvm2Npu(input_ttype->shape, &input_tensor_shape); + err += Tvm2Npu(input_ttype->dtype, &input_tensor_dtype); params->input_info = - sl::TensorInfo(input_tensor_shape, input_tensor_dtype, sl::DataFormat::NHWC, input_q_info); + sl::TensorInfo(input_tensor_shape, input_tensor_dtype, params->input_info.m_DataFormat, + params->input_info.m_QuantizationInfo); - float output_sc; - int output_zp; - err += AsConstant(requantize->args[3], &output_sc); - err += AsConstant(requantize->args[4], &output_zp); - sl::QuantizationInfo resize_q_info; - err += Tvm2Npu(output_zp, output_sc, &resize_q_info); - const auto* attrs = resize->attrs.as(); - uint32_t height, width; - err += Tvm2Npu(attrs->size, &height, &width); - params->resize_info = - sl::ResizeInfo{sl::ResizeAlgorithm::NEAREST_NEIGHBOUR, height, width, resize_q_info}; - - sl::TensorInfo output_info = params->input_info; - output_info.m_Dimensions[1] = params->resize_info.m_NewHeight; - output_info.m_Dimensions[2] = params->resize_info.m_NewWidth; - output_info.m_QuantizationInfo = params->resize_info.m_OutputQuantizationInfo; - params->output_info = output_info; + sl::TensorInfo output_tensor_info; + err += Tvm2Npu(resize->checked_type(), &output_tensor_info); + output_tensor_info.m_QuantizationInfo = params->input_info.m_QuantizationInfo; + params->output_info = output_tensor_info; return err; } diff --git a/tests/python/contrib/test_ethosn/test_resize.py b/tests/python/contrib/test_ethosn/test_resize.py index 30b29fb1612e..88880d7d4a99 100644 --- a/tests/python/contrib/test_ethosn/test_resize.py +++ b/tests/python/contrib/test_ethosn/test_resize.py @@ -29,15 +29,11 @@ def _get_model( shape, dtype, size, - input_zp, - input_sc, - output_zp, - output_sc, coordinate_transformation_mode, rounding_method, ): x = relay.var("x", shape=shape, dtype=dtype) - resize = relay.image.resize2d( + return relay.image.resize2d( data=x, size=size, layout="NHWC", @@ -45,15 +41,6 @@ def _get_model( coordinate_transformation_mode=coordinate_transformation_mode, rounding_method=rounding_method, ) - model = relay.qnn.op.requantize( - resize, - input_scale=relay.const(input_sc, "float32"), - input_zero_point=relay.const(input_zp, "int32"), - output_scale=relay.const(output_sc, "float32"), - output_zero_point=relay.const(output_zp, "int32"), - out_dtype=dtype, - ) - return model @requires_ethosn @@ -82,10 +69,6 @@ def test_resize(dtype, shape, size, coordinate_transformation_mode, rounding_met shape=shape, dtype=dtype, size=size, - input_zp=zp_min + 128, - input_sc=0.0784314, - output_zp=zp_min + 128, - output_sc=0.0784314, coordinate_transformation_mode=coordinate_transformation_mode, rounding_method=rounding_method, ) @@ -113,16 +96,11 @@ def test_resize(dtype, shape, size, coordinate_transformation_mode, rounding_met def test_resize_failure(size, err_msg): """Check Resize error messages.""" dtype = "int8" - zp_min = np.iinfo(dtype).min model = _get_model( shape=(1, 10, 10, 1), dtype=dtype, size=size, - input_zp=zp_min + 128, - input_sc=0.0784314, - output_zp=zp_min + 128, - output_sc=0.0784314, coordinate_transformation_mode="half_pixel", rounding_method="round_prefer_ceil", )