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

Merged
mbaret merged 5 commits into
apache:mainfrom
ekalda:depthwise_upstream2
Oct 11, 2021
Merged

Arm(R) Ethos(TM)-U NPU Depthwise2d operator support#9209
mbaret merged 5 commits into
apache:mainfrom
ekalda:depthwise_upstream2

Conversation

@ekalda

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

@manupa-arm@mbaret

@manupak

Copy link
Copy Markdown
Contributor

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

Comment threadtests/python/contrib/test_ethosu/test_legalize.py Outdated

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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.



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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

QnnDepthwiseConv2DParams

Copy link
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

Comment threadtests/python/contrib/test_ethosu/test_legalize.py
@manupak

Copy link
Copy Markdown
Contributor

also cc : @dchauhan-arm

@lhutton1lhutton1 left a comment

Copy link
Copy Markdown
Contributor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

self.strides = qnn_conv2d.attrs.strides
self.dilation = qnn_conv2d.attrs.dilation
self.activation = activation
self.channels = qnn_conv2d.attrs.channels

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

@ekalda
ekaldaforce-pushed the depthwise_upstream2 branch from 0812f86 to 1e7e9caCompareOctober 8, 2021 08:57

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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.

if re.match(r"\./codegen/host/src/\D+\d+\.c", name)
]
assert len(c_source_files) == 17
assert len(c_source_files) == 4

@manupakmanupakOct 8, 2021

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

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?

@lhutton1lhutton1 left a comment

Copy link
Copy Markdown
Contributor

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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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

@manupakmanupak 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
ekaldaforce-pushed the depthwise_upstream2 branch from 76ceb71 to f43e088CompareOctober 11, 2021 09:08

@mbaretmbaret left a comment

Copy link
Copy Markdown
Contributor

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:mainOct 11, 2021
@mbaret

Copy link
Copy Markdown
Contributor

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 freeto 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

@ekalda@manupak@mbaret@NicolaLancellotti@lhutton1@dchauhan-arm
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

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

Merged
mbaret merged 5 commits into
apache:mainfrom
ekalda:depthwise_upstream2
Oct 11, 2021
Merged

Arm(R) Ethos(TM)-U NPU Depthwise2d operator support#9209
mbaret merged 5 commits into
apache:mainfrom
ekalda:depthwise_upstream2

Conversation

@ekalda

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

@manupa-arm@mbaret

@manupak

Copy link
Copy Markdown
Contributor

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

Comment threadtests/python/contrib/test_ethosu/test_legalize.py Outdated

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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.



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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

QnnDepthwiseConv2DParams

Copy link
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

Comment threadtests/python/contrib/test_ethosu/test_legalize.py
@manupak

Copy link
Copy Markdown
Contributor

also cc : @dchauhan-arm

@lhutton1lhutton1 left a comment

Copy link
Copy Markdown
Contributor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

self.strides = qnn_conv2d.attrs.strides
self.dilation = qnn_conv2d.attrs.dilation
self.activation = activation
self.channels = qnn_conv2d.attrs.channels

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

@ekalda
ekaldaforce-pushed the depthwise_upstream2 branch from 0812f86 to 1e7e9caCompareOctober 8, 2021 08:57

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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.

if re.match(r"\./codegen/host/src/\D+\d+\.c", name)
]
assert len(c_source_files) == 17
assert len(c_source_files) == 4

@manupakmanupakOct 8, 2021

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

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?

@lhutton1lhutton1 left a comment

Copy link
Copy Markdown
Contributor

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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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

@manupakmanupak 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
ekaldaforce-pushed the depthwise_upstream2 branch from 76ceb71 to f43e088CompareOctober 11, 2021 09:08

@mbaretmbaret left a comment

Copy link
Copy Markdown
Contributor

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:mainOct 11, 2021
@mbaret

Copy link
Copy Markdown
Contributor

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 freeto 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

@ekalda@manupak@mbaret@NicolaLancellotti@lhutton1@dchauhan-arm
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

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

Merged
mbaret merged 5 commits into
apache:mainfrom
ekalda:depthwise_upstream2
Oct 11, 2021
Merged

Arm(R) Ethos(TM)-U NPU Depthwise2d operator support#9209
mbaret merged 5 commits into
apache:mainfrom
ekalda:depthwise_upstream2

Conversation

@ekalda

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

@manupa-arm@mbaret

@manupak

Copy link
Copy Markdown
Contributor

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

Comment threadtests/python/contrib/test_ethosu/test_legalize.py Outdated

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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.



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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

QnnDepthwiseConv2DParams

Copy link
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

Comment threadtests/python/contrib/test_ethosu/test_legalize.py
@manupak

Copy link
Copy Markdown
Contributor

also cc : @dchauhan-arm

@lhutton1lhutton1 left a comment

Copy link
Copy Markdown
Contributor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

self.strides = qnn_conv2d.attrs.strides
self.dilation = qnn_conv2d.attrs.dilation
self.activation = activation
self.channels = qnn_conv2d.attrs.channels

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

@ekalda
ekaldaforce-pushed the depthwise_upstream2 branch from 0812f86 to 1e7e9caCompareOctober 8, 2021 08:57

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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.

if re.match(r"\./codegen/host/src/\D+\d+\.c", name)
]
assert len(c_source_files) == 17
assert len(c_source_files) == 4

@manupakmanupakOct 8, 2021

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

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?

@lhutton1lhutton1 left a comment

Copy link
Copy Markdown
Contributor

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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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

@manupakmanupak 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
ekaldaforce-pushed the depthwise_upstream2 branch from 76ceb71 to f43e088CompareOctober 11, 2021 09:08

@mbaretmbaret left a comment

Copy link
Copy Markdown
Contributor

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:mainOct 11, 2021
@mbaret

Copy link
Copy Markdown
Contributor

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 freeto 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

@ekalda@manupak@mbaret@NicolaLancellotti@lhutton1@dchauhan-arm
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

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

Merged
mbaret merged 5 commits into
apache:mainfrom
ekalda:depthwise_upstream2
Oct 11, 2021
Merged

Arm(R) Ethos(TM)-U NPU Depthwise2d operator support#9209
mbaret merged 5 commits into
apache:mainfrom
ekalda:depthwise_upstream2

Conversation

@ekalda

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

@manupa-arm@mbaret

@manupak

Copy link
Copy Markdown
Contributor

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

Comment threadtests/python/contrib/test_ethosu/test_legalize.py Outdated

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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.



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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

QnnDepthwiseConv2DParams

Copy link
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

Comment threadtests/python/contrib/test_ethosu/test_legalize.py
@manupak

Copy link
Copy Markdown
Contributor

also cc : @dchauhan-arm

@lhutton1lhutton1 left a comment

Copy link
Copy Markdown
Contributor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

self.strides = qnn_conv2d.attrs.strides
self.dilation = qnn_conv2d.attrs.dilation
self.activation = activation
self.channels = qnn_conv2d.attrs.channels

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

@ekalda
ekaldaforce-pushed the depthwise_upstream2 branch from 0812f86 to 1e7e9caCompareOctober 8, 2021 08:57

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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.

if re.match(r"\./codegen/host/src/\D+\d+\.c", name)
]
assert len(c_source_files) == 17
assert len(c_source_files) == 4

@manupakmanupakOct 8, 2021

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

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?

@lhutton1lhutton1 left a comment

Copy link
Copy Markdown
Contributor

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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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

@manupakmanupak 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
ekaldaforce-pushed the depthwise_upstream2 branch from 76ceb71 to f43e088CompareOctober 11, 2021 09:08

@mbaretmbaret left a comment

Copy link
Copy Markdown
Contributor

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:mainOct 11, 2021
@mbaret

Copy link
Copy Markdown
Contributor

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 freeto 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

@ekalda@manupak@mbaret@NicolaLancellotti@lhutton1@dchauhan-arm
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

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

Merged
mbaret merged 5 commits into
apache:mainfrom
ekalda:depthwise_upstream2
Oct 11, 2021
Merged

Arm(R) Ethos(TM)-U NPU Depthwise2d operator support#9209
mbaret merged 5 commits into
apache:mainfrom
ekalda:depthwise_upstream2

Conversation

@ekalda

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

@manupa-arm@mbaret

@manupak

Copy link
Copy Markdown
Contributor

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

Comment threadtests/python/contrib/test_ethosu/test_legalize.py Outdated

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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.



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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

QnnDepthwiseConv2DParams

Copy link
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

Comment threadtests/python/contrib/test_ethosu/test_legalize.py
@manupak

Copy link
Copy Markdown
Contributor

also cc : @dchauhan-arm

@lhutton1lhutton1 left a comment

Copy link
Copy Markdown
Contributor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

self.strides = qnn_conv2d.attrs.strides
self.dilation = qnn_conv2d.attrs.dilation
self.activation = activation
self.channels = qnn_conv2d.attrs.channels

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

@ekalda
ekaldaforce-pushed the depthwise_upstream2 branch from 0812f86 to 1e7e9caCompareOctober 8, 2021 08:57

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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.

if re.match(r"\./codegen/host/src/\D+\d+\.c", name)
]
assert len(c_source_files) == 17
assert len(c_source_files) == 4

@manupakmanupakOct 8, 2021

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

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?

@lhutton1lhutton1 left a comment

Copy link
Copy Markdown
Contributor

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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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

@manupakmanupak 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
ekaldaforce-pushed the depthwise_upstream2 branch from 76ceb71 to f43e088CompareOctober 11, 2021 09:08

@mbaretmbaret left a comment

Copy link
Copy Markdown
Contributor

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:mainOct 11, 2021
@mbaret

Copy link
Copy Markdown
Contributor

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 freeto 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

@ekalda@manupak@mbaret@NicolaLancellotti@lhutton1@dchauhan-arm
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

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

Merged
mbaret merged 5 commits into
apache:mainfrom
ekalda:depthwise_upstream2
Oct 11, 2021
Merged

Arm(R) Ethos(TM)-U NPU Depthwise2d operator support#9209
mbaret merged 5 commits into
apache:mainfrom
ekalda:depthwise_upstream2

Conversation

@ekalda

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

@manupa-arm@mbaret

@manupak

Copy link
Copy Markdown
Contributor

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

Comment threadtests/python/contrib/test_ethosu/test_legalize.py Outdated

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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.



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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

QnnDepthwiseConv2DParams

Copy link
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

Comment threadtests/python/contrib/test_ethosu/test_legalize.py
@manupak

Copy link
Copy Markdown
Contributor

also cc : @dchauhan-arm

@lhutton1lhutton1 left a comment

Copy link
Copy Markdown
Contributor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

self.strides = qnn_conv2d.attrs.strides
self.dilation = qnn_conv2d.attrs.dilation
self.activation = activation
self.channels = qnn_conv2d.attrs.channels

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

@ekalda
ekaldaforce-pushed the depthwise_upstream2 branch from 0812f86 to 1e7e9caCompareOctober 8, 2021 08:57

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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.

if re.match(r"\./codegen/host/src/\D+\d+\.c", name)
]
assert len(c_source_files) == 17
assert len(c_source_files) == 4

@manupakmanupakOct 8, 2021

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

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?

@lhutton1lhutton1 left a comment

Copy link
Copy Markdown
Contributor

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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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

@manupakmanupak 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
ekaldaforce-pushed the depthwise_upstream2 branch from 76ceb71 to f43e088CompareOctober 11, 2021 09:08

@mbaretmbaret left a comment

Copy link
Copy Markdown
Contributor

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:mainOct 11, 2021
@mbaret

Copy link
Copy Markdown
Contributor

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 freeto 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

@ekalda@manupak@mbaret@NicolaLancellotti@lhutton1@dchauhan-arm
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

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

Merged
mbaret merged 5 commits into
apache:mainfrom
ekalda:depthwise_upstream2
Oct 11, 2021
Merged

Arm(R) Ethos(TM)-U NPU Depthwise2d operator support#9209
mbaret merged 5 commits into
apache:mainfrom
ekalda:depthwise_upstream2

Conversation

@ekalda

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

@manupa-arm@mbaret

@manupak

Copy link
Copy Markdown
Contributor

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

Comment threadtests/python/contrib/test_ethosu/test_legalize.py Outdated

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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.



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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

QnnDepthwiseConv2DParams

Copy link
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

Comment threadtests/python/contrib/test_ethosu/test_legalize.py
@manupak

Copy link
Copy Markdown
Contributor

also cc : @dchauhan-arm

@lhutton1lhutton1 left a comment

Copy link
Copy Markdown
Contributor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

self.strides = qnn_conv2d.attrs.strides
self.dilation = qnn_conv2d.attrs.dilation
self.activation = activation
self.channels = qnn_conv2d.attrs.channels

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

@ekalda
ekaldaforce-pushed the depthwise_upstream2 branch from 0812f86 to 1e7e9caCompareOctober 8, 2021 08:57

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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.

if re.match(r"\./codegen/host/src/\D+\d+\.c", name)
]
assert len(c_source_files) == 17
assert len(c_source_files) == 4

@manupakmanupakOct 8, 2021

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

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?

@lhutton1lhutton1 left a comment

Copy link
Copy Markdown
Contributor

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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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

@manupakmanupak 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
ekaldaforce-pushed the depthwise_upstream2 branch from 76ceb71 to f43e088CompareOctober 11, 2021 09:08

@mbaretmbaret left a comment

Copy link
Copy Markdown
Contributor

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:mainOct 11, 2021
@mbaret

Copy link
Copy Markdown
Contributor

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 freeto 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

@ekalda@manupak@mbaret@NicolaLancellotti@lhutton1@dchauhan-arm
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

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

Merged
mbaret merged 5 commits into
apache:mainfrom
ekalda:depthwise_upstream2
Oct 11, 2021
Merged

Arm(R) Ethos(TM)-U NPU Depthwise2d operator support#9209
mbaret merged 5 commits into
apache:mainfrom
ekalda:depthwise_upstream2

Conversation

@ekalda

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

@manupa-arm@mbaret

@manupak

Copy link
Copy Markdown
Contributor

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

Comment threadtests/python/contrib/test_ethosu/test_legalize.py Outdated

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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.



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

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

QnnDepthwiseConv2DParams

Copy link
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

Comment threadtests/python/contrib/test_ethosu/test_legalize.py
@manupak

Copy link
Copy Markdown
Contributor

also cc : @dchauhan-arm

@lhutton1lhutton1 left a comment

Copy link
Copy Markdown
Contributor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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.

self.strides = qnn_conv2d.attrs.strides
self.dilation = qnn_conv2d.attrs.dilation
self.activation = activation
self.channels = qnn_conv2d.attrs.channels

Copy link
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

@ekalda
ekaldaforce-pushed the depthwise_upstream2 branch from 0812f86 to 1e7e9caCompareOctober 8, 2021 08:57

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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.

if re.match(r"\./codegen/host/src/\D+\d+\.c", name)
]
assert len(c_source_files) == 17
assert len(c_source_files) == 4

@manupakmanupakOct 8, 2021

Copy link
Copy Markdown
Contributor

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
Copy Markdown
ContributorAuthor

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?

@lhutton1lhutton1 left a comment

Copy link
Copy Markdown
Contributor

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
Copy Markdown
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
Copy Markdown
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
Copy Markdown
ContributorAuthor

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
Copy Markdown
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
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

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

Done

@manupakmanupak left a comment

Copy link
Copy Markdown
Contributor

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

@manupakmanupak 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
ekaldaforce-pushed the depthwise_upstream2 branch from 76ceb71 to f43e088CompareOctober 11, 2021 09:08

@mbaretmbaret left a comment

Copy link
Copy Markdown
Contributor

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:mainOct 11, 2021
@mbaret

Copy link
Copy Markdown
Contributor

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 freeto 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

@ekalda@manupak@mbaret@NicolaLancellotti@lhutton1@dchauhan-arm