-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
Conversation
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 |
There was a problem hiding this 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""" |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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}) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
QnnDepthwiseConv2DParams
There was a problem hiding this comment.
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), |
There was a problem hiding this comment.
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]]
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit : type annotations
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
also cc : @dchauhan-arm |
There was a problem hiding this 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], |
There was a problem hiding this comment.
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?
There was a problem hiding this comment.
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 |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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() |
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"ethosu.depthwise2d", | |
"ethosu.QnnDepthwise2DParams.composite_name", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
0812f86
to
1e7e9ca
Compare
There was a problem hiding this 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 |
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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?
There was a problem hiding this 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 | ||
|
There was a problem hiding this comment.
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], | ||
): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
): | |
) -> Tuple[SerialPooling, tvm.tir.Var, tvm.tir.Var]: |
There was a problem hiding this comment.
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): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
def __init__(self, func_body): | |
def __init__(self, func_body: tvm.relay.expr.Call): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
There was a problem hiding this 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
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
76ceb71
to
f43e088
Compare
There was a problem hiding this 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.
This is now merged, thanks everyone! |
* 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
* 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
* 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
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.