Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arm(R) Ethos(TM)-U NPU Depthwise2d operator support #9209

Merged
merged 5 commits into from
Oct 11, 2021

Conversation

ekalda
Copy link
Contributor

@ekalda ekalda commented Oct 6, 2021

This commit adds support for Depthwise2d primitive operator throughout
the TVM stack including Relay legalization pass, operator definition,
TE, TIR passes and translation into the command stream.

@ekalda
Copy link
Contributor Author

ekalda commented Oct 6, 2021

@manupa-arm @mbaret

@manupak
Copy link
Contributor

manupak commented Oct 6, 2021

Thanks @ekalda!

Just a high-level comment, I think we should stick to DepthwiseConv2D (as opposed to Depthwise2D). I ll have a look,

Also cc : @NicolaLancellotti @lhutton1

Copy link
Contributor

@manupak manupak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@ekalda I have left some minor comments, otherwise the implementation generally looks good.

@@ -208,6 +208,96 @@ def __call__(self, *args, **kwargs):
pass


class EthosuDepthwise2DRewriter(DFPatternCallback):
"""Convert ethosu.qnn_depthwise2d composite functions to ethosu_depthwise2d operators"""
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let us stick to depthwiseconv2d/DepthwiseConv2D and also in the following mentions to it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done (I used depthwise_conv2d since it is more readable, but I can change it to depthwiseconv2d if you'd prefer that)

def __init__(self):
super().__init__(require_type=True)
self.pattern = (
wildcard().has_attr({"Composite": ethosu_patterns.QnnDepthwise2DParams.composite_name})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

QnnDepthwiseConv2DParams

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

ofm_zero_point: int,
kernel_shape: Tuple[int, int],
ofm_channels: int,
strides: Tuple[int, int] = (1, 1),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit : We can use Optional[Tuple[int, int]]

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I left it as is since Optional is used when the variable can take a value None

The OFM tensor.

"""
assert ifm.shape[0] == 1
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is better to give a message when this fails as to why it was assumed to be 1.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

)


def get_depthwise2d_params(stmt, producers, consumers):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit : type annotations

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@manupak
Copy link
Contributor

manupak commented Oct 7, 2021

also cc : @dchauhan-arm

Copy link
Contributor

@lhutton1 lhutton1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, just a couple of questions/minor things

if str(params.ofm.layout) not in channels_map.keys():
raise UnsupportedLayout(str(params.ofm.layout))
kernel_shape_map = {
"HWOI": params.weights.shape[0:2],
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it worth supporting OHWI weights here?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

IIRC, in the Relay that corresponds to depthwise conv2d operator from TFLite, the weights are always in HWOI, that's why other formats are not handled here.

@@ -223,12 +223,13 @@ def __init__(self, func_body: tvm.relay.Function):
self.strides = qnn_conv2d.attrs.strides
self.dilation = qnn_conv2d.attrs.dilation
self.activation = activation
self.channels = qnn_conv2d.attrs.channels
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to access attrs once here i.e,

attrs = qnn_conv2d.attrs
self.padding = attrs.padding
...
self.channels = attrs.channels

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

).has_attr({"kernel_layout": "HWOI"})
bias_add = is_op("nn.bias_add")(qnn_conv2d, is_constant())
req = is_op("qnn.requantize")(
qnn_conv2d | bias_add, is_constant(), is_constant(), is_constant(), is_constant()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove optional bias here? Then we can follow up with separate PR for conv2d

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good point, done


depthwise_pattern_table = [
(
"ethosu.depthwise2d",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
"ethosu.depthwise2d",
"ethosu.QnnDepthwise2DParams.composite_name",

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

@ekalda ekalda force-pushed the depthwise_upstream2 branch from 0812f86 to 1e7e9ca Compare October 8, 2021 08:57
Copy link
Contributor

@manupak manupak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just one comment otherwise LGTM modulo others' comments.

@@ -471,7 +471,7 @@ def test_compile_tflite_module_with_external_codegen_ethosu(
for name in mlf_package.getnames()
if re.match(r"\./codegen/host/src/\D+\d+\.c", name)
]
assert len(c_source_files) == 17
assert len(c_source_files) == 4
Copy link
Contributor

@manupak manupak Oct 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should have put a comment saying why there was 17 here originally. Sorry about that.
Would you be able to put a comments explaining why it is 4 now ?

It should along the lines of that we expect lesser subgraphs where it was just conv2D being offloaded and now we have depthwise_conv2d being offloaded as well from mobilenet. Therefore [conv2d-->dethpwise_conv2d-->conv2d-> ... ] get fused to a single primitive external function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a comment, does it make sense?

Copy link
Contributor

@lhutton1 lhutton1 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

if activation:
op = tf.nn.relu(op)
return op

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM regarding tf.nn.depthwise_conv2d usage. Others' comments cover everything else.

stmt: tvm.tir.AttrStmt,
producers: Dict[tvm.tir.Var, tvm.tir.AttrStmt],
consumers: Dict[tvm.tir.Var, tvm.tir.AttrStmt],
):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
):
) -> Tuple[SerialPooling, tvm.tir.Var, tvm.tir.Var]:

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

# The hardware only supports padding upto the numbers as follows
padding_bounds = [31, 31, 32, 32]

def __init__(self, func_body):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
def __init__(self, func_body):
def __init__(self, func_body: tvm.relay.expr.Call):

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done

Copy link
Contributor

@manupak manupak left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

Other reviewers please approve explicitly if the discussions are resolved.
https://tvm.apache.org/docs/contribute/code_review.html#approve-and-request-changes-explicitly

@manupak manupak self-assigned this Oct 8, 2021
This commit adds support for Depthwise2d primitive operator throughout
the TVM stack including Relay legalization pass, operator definition,
TE, TIR passes and translation into the command stream.

Change-Id: If82b85f5d3b23cd214fe38babd724451bf95ef5b
And respond to other review comments.

Change-Id: I58a9f28723750970d386b4d0ba62fa399c5c6181
Change-Id: Idf4c078bf65e7ed31fe82a92bf334295a82b6ead
Change-Id: Ic6c77af30a5b9cb68dcc0c173b95490965359481
Change-Id: I7318bd8cfa5985b33fc7d020cc19057cc9498197
@ekalda ekalda force-pushed the depthwise_upstream2 branch from 76ceb71 to f43e088 Compare October 11, 2021 09:08
Copy link
Contributor

@mbaret mbaret left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, let's get this in.

@mbaret mbaret merged commit 8ba0451 into apache:main Oct 11, 2021
@mbaret
Copy link
Contributor

mbaret commented Oct 11, 2021

This is now merged, thanks everyone!

@ekalda ekalda deleted the depthwise_upstream2 branch October 11, 2021 15:51
masahi pushed a commit to Laurawly/tvm-1 that referenced this pull request Oct 14, 2021
* Arm(R) Ethos(TM)-U NPU Depthwise2d operator support

This commit adds support for Depthwise2d primitive operator throughout
the TVM stack including Relay legalization pass, operator definition,
TE, TIR passes and translation into the command stream.

Change-Id: If82b85f5d3b23cd214fe38babd724451bf95ef5b

* Change depthwise2d to depthwise_conv2d

And respond to other review comments.

Change-Id: I58a9f28723750970d386b4d0ba62fa399c5c6181

* Make a line shorter and add a comment

Change-Id: Idf4c078bf65e7ed31fe82a92bf334295a82b6ead

* Change the order of imports

Change-Id: Ic6c77af30a5b9cb68dcc0c173b95490965359481

* Whitespace change

Change-Id: I7318bd8cfa5985b33fc7d020cc19057cc9498197
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 7, 2022
* Arm(R) Ethos(TM)-U NPU Depthwise2d operator support

This commit adds support for Depthwise2d primitive operator throughout
the TVM stack including Relay legalization pass, operator definition,
TE, TIR passes and translation into the command stream.

Change-Id: If82b85f5d3b23cd214fe38babd724451bf95ef5b

* Change depthwise2d to depthwise_conv2d

And respond to other review comments.

Change-Id: I58a9f28723750970d386b4d0ba62fa399c5c6181

* Make a line shorter and add a comment

Change-Id: Idf4c078bf65e7ed31fe82a92bf334295a82b6ead

* Change the order of imports

Change-Id: Ic6c77af30a5b9cb68dcc0c173b95490965359481

* Whitespace change

Change-Id: I7318bd8cfa5985b33fc7d020cc19057cc9498197
ylc pushed a commit to ylc/tvm that referenced this pull request Jan 13, 2022
* Arm(R) Ethos(TM)-U NPU Depthwise2d operator support

This commit adds support for Depthwise2d primitive operator throughout
the TVM stack including Relay legalization pass, operator definition,
TE, TIR passes and translation into the command stream.

Change-Id: If82b85f5d3b23cd214fe38babd724451bf95ef5b

* Change depthwise2d to depthwise_conv2d

And respond to other review comments.

Change-Id: I58a9f28723750970d386b4d0ba62fa399c5c6181

* Make a line shorter and add a comment

Change-Id: Idf4c078bf65e7ed31fe82a92bf334295a82b6ead

* Change the order of imports

Change-Id: Ic6c77af30a5b9cb68dcc0c173b95490965359481

* Whitespace change

Change-Id: I7318bd8cfa5985b33fc7d020cc19057cc9498197
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants