From 98477c327cdcdfe6a9ce82a63a1f6fad364019bf Mon Sep 17 00:00:00 2001 From: Andrew Luo Date: Wed, 8 Dec 2021 14:18:08 -0800 Subject: [PATCH 1/3] enable grouped conv --- python/tvm/relay/frontend/onnx.py | 45 ++++--------------------------- src/relay/op/nn/convolution.h | 3 +-- 2 files changed, 6 insertions(+), 42 deletions(-) diff --git a/python/tvm/relay/frontend/onnx.py b/python/tvm/relay/frontend/onnx.py index 189c7f054664..d2d5b4df6389 100644 --- a/python/tvm/relay/frontend/onnx.py +++ b/python/tvm/relay/frontend/onnx.py @@ -37,25 +37,11 @@ from .. import random as _random from .. import ty as _ty from .. import vision as _vision -from .common import ( - autopad, - AttrCvt, - Renamer, - ensure_scalar_shape, - fold_constant, - get_name, - get_relay_op, - gru_cell, - infer_channels, - infer_shape, - infer_type, - infer_value, - lstm_cell, - new_var, - shape_of, - try_resolve_var_to_const, - unbind, -) +from .common import (AttrCvt, Renamer, autopad, ensure_scalar_shape, + fold_constant, get_name, get_relay_op, gru_cell, + infer_channels, infer_shape, infer_type, infer_value, + lstm_cell, new_var, shape_of, try_resolve_var_to_const, + unbind) __all__ = ["from_onnx"] @@ -523,23 +509,6 @@ def _impl_v1(cls, inputs, attr, params): raise tvm.error.OpAttributeInvalid(msg.format(attr["auto_pad"])) attr.pop("auto_pad") - # Check if the requested convolution is a group conv1d, if so convert it to conv2d. - # TODO(jwfromm) Remove once proper group_conv1d is supported. - group_conv1d = False - if dimension_picker("conv")(attr) == "conv1d" and attr.get("group") != 1: - group_conv1d = True - # Expand input from NCW to NCHW - data = _op.expand_dims(data, axis=2) - # Expand kernel from OIW to OIHW - kernel = _op.expand_dims(kernel, axis=2) - # Add new value to kernel_shape, strices, dilation, pads, if needed - attr["kernel_shape"] = [1] + list(attr["kernel_shape"]) - if "strides" in attr: - attr["strides"] = [1] + list(attr["strides"]) - if "dilations" in attr: - attr["dilations"] = [1] + list(attr["dilations"]) - if "pads" in attr: - attr["pads"] = [0, attr["pads"][0], 0, attr["pads"][1]] attr["channels"] = kernel_shapes[0][0] out = AttrCvt( op_name=dimension_picker("conv"), @@ -552,10 +521,6 @@ def _impl_v1(cls, inputs, attr, params): custom_check=dimension_constraint(), )([data, kernel], attr, params) - # If this was a group_conv1d, squish output back to NCW. - if group_conv1d: - out = _op.squeeze(out, axis=[2]) - use_bias = len(inputs) == 3 if use_bias: out = _op.nn.bias_add(out, inputs[2]) diff --git a/src/relay/op/nn/convolution.h b/src/relay/op/nn/convolution.h index e5e64fa5be65..06b54be5c5b2 100644 --- a/src/relay/op/nn/convolution.h +++ b/src/relay/op/nn/convolution.h @@ -76,8 +76,7 @@ bool Conv1DRel(const Array& types, int num_inputs, const Attrs& attrs, if (param->kernel_size.defined() && param->channels.defined()) { Array wshape; - wshape = {{param->channels, dshape_ncw[1], param->kernel_size[0]}}; - + wshape = {{param->channels, indexdiv(dshape_ncw[1], param->groups), param->kernel_size[0]}}; wshape = trans_kernel_layout.BackwardShape(wshape); channels = param->channels; dilated_ksize = 1 + (param->kernel_size[0] - 1) * param->dilation[0]; From 84d771bc191802fd8016cc7c829a933fb53af3c2 Mon Sep 17 00:00:00 2001 From: Andrew Luo Date: Wed, 8 Dec 2021 14:19:29 -0800 Subject: [PATCH 2/3] undo extra formatting --- python/tvm/relay/frontend/onnx.py | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/python/tvm/relay/frontend/onnx.py b/python/tvm/relay/frontend/onnx.py index d2d5b4df6389..e0c7e171cf5a 100644 --- a/python/tvm/relay/frontend/onnx.py +++ b/python/tvm/relay/frontend/onnx.py @@ -37,11 +37,25 @@ from .. import random as _random from .. import ty as _ty from .. import vision as _vision -from .common import (AttrCvt, Renamer, autopad, ensure_scalar_shape, - fold_constant, get_name, get_relay_op, gru_cell, - infer_channels, infer_shape, infer_type, infer_value, - lstm_cell, new_var, shape_of, try_resolve_var_to_const, - unbind) +from .common import ( + AttrCvt, + Renamer, + autopad, + ensure_scalar_shape, + fold_constant, + get_name, + get_relay_op, + gru_cell, + infer_channels, + infer_shape, + infer_type, + infer_value, + lstm_cell, + new_var, + shape_of, + try_resolve_var_to_const, + unbind, +) __all__ = ["from_onnx"] From 1d668652fd551c64227392f7db0a9431f34d4cd6 Mon Sep 17 00:00:00 2001 From: Andrew Luo Date: Wed, 8 Dec 2021 14:28:36 -0800 Subject: [PATCH 3/3] add tests --- tests/python/relay/test_op_level2.py | 58 +++++++++++++++++++++++++++- 1 file changed, 57 insertions(+), 1 deletion(-) diff --git a/tests/python/relay/test_op_level2.py b/tests/python/relay/test_op_level2.py index db712be4262e..67f36b669e01 100644 --- a/tests/python/relay/test_op_level2.py +++ b/tests/python/relay/test_op_level2.py @@ -71,6 +71,61 @@ def test_conv1d_infer_type(): assert yy.checked_type == relay.TensorType((n, w, 16), "int32") +@tvm.testing.uses_gpu +def test_grouped_conv1d_run(): + # TODO(AndrewZhaoLuo): support ground truth function to have grouped support + # and then combine with test_conv1d_run + def run_test_conv1d( + dtype, + scale, + dshape, + kshape, + padding=(1, 1), + fref=None, + groups=1, + dilation=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.conv1d(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) + + for target, dev in tvm.testing.enabled_targets(): + if target in except_targets: + continue + dev = tvm.device(target, 0) + relay.create_executor("graph", device=dev, target=target).evaluate(func)(data, kernel) + + dshape = (1, 6, 224) + run_test_conv1d( + "float32", + 1, + dshape, + kshape=(10, 1, 3), + padding=(1, 1), + channels=10, + kernel_size=3, + groups=6, + ) + run_test_conv1d( + "float32", + 1, + dshape, + kshape=(10, 2, 3), + padding=(1, 1), + channels=10, + kernel_size=3, + groups=3, + ) + + @tvm.testing.uses_gpu def test_conv1d_run(): def run_test_conv1d( @@ -81,6 +136,7 @@ def run_test_conv1d( kshape, padding=(1, 1), fref=None, + groups=1, dilation=1, except_targets=None, **attrs, @@ -90,7 +146,7 @@ def run_test_conv1d( x = relay.var("x", shape=dshape, dtype=dtype) w = relay.var("w", dtype=dtype) - y = relay.nn.conv1d(x, w, padding=padding, dilation=dilation, **attrs) + y = relay.nn.conv1d(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)