-
Notifications
You must be signed in to change notification settings - Fork 3.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[ETHOSU][MicroNPU][Pass] Add a pass to replicate pads #14909
[ETHOSU][MicroNPU][Pass] Add a pass to replicate pads #14909
Conversation
cc @neildhickey, @ekalda, @ilyag-grovety, @Aleksei-grovety @arina-grovety |
ff1fd37
to
7836a42
Compare
@tvm-bot rerun |
if op_pairs[0] == "depthwise": | ||
weight_shape = [kernel_shape[0], kernel_shape[1], ifm_shape[3], 1] | ||
weight = tf.constant(np.random.uniform(size=weight_shape), dtype=tf.float32) | ||
x1 = tf.nn.depthwise_conv2d( | ||
x, weight, strides=tf_strides, padding=op_padding, dilations=dilation | ||
) | ||
else: | ||
weight_shape = [kernel_shape[0], kernel_shape[1], ifm_shape[3], 3] | ||
weight = tf.constant(np.random.uniform(size=weight_shape), dtype=tf.float32) | ||
x1 = tf.nn.conv2d( | ||
x, | ||
weight, | ||
strides=tf_strides, | ||
padding=op_padding, | ||
dilations=dilation, | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here the same code as on lines 3706 - 3721, it can be put into a separate function.
# KIND, either express or implied. See the License for the | ||
# specific language governing permissions and limitations | ||
# under the License. | ||
"Adds pads so that each conv2d operator has only one consumer" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe "Adds pads to each conv2d operator so that each pad has only one consumer."?
new_conv2d_args = [] | ||
for i, arg in enumerate(call.args): | ||
if i == 0: | ||
new_conv2d_args.append(self.visit(new_pad)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new_pad is visited twice the first time on line 59.
@tvm-bot rerun |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks @sergio-grovety, great work! Bar @Aleksei-grovety suggestions, I only had one nit and two more general points:
- This pass is necessary due to how we do pattern matching for Ethos-U and is therefore coupled to Ethos-U integration, so I don't think it makes much sense to have it among generic Relay transformation passes. Maybe move it to somewhere into
ethosu
namespace, e.g. into codegen. - Testing - while legalization test is the most important test for this kind of change, I think it would also be good to have a simple lightweight codegen test for this kind of graph topology. Since the pass creates a new conv2d, there is some risk of constants getting messed up, but a simple codegen test should eliminate that risk.
|
||
def __init__(self): | ||
ExprMutator.__init__(self) | ||
self.hashes = set() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nit: Maybe add a comment what self.hashes
represents
bf520bd
to
4678cbf
Compare
@tvm-bot rerun |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Almost there, one suggestion regarding to testing!
@pytest.mark.parametrize("accel_type", ACCEL_TYPES) | ||
@pytest.mark.parametrize("ifm_shape", [(1, 55, 32, 3)]) | ||
@pytest.mark.parametrize( | ||
"kernel_shape, activation_function", | ||
[((3, 3), "RELU"), ((1, 2), "NONE")], | ||
) | ||
@pytest.mark.parametrize("strides, dilation", [((3, 2), (1, 1))]) | ||
@pytest.mark.parametrize("op_padding", ["SAME", "VALID"]) | ||
@pytest.mark.parametrize("sep_padding", [(0, 0, 1, 1), (7, 5, 4, 5)]) | ||
@pytest.mark.parametrize( | ||
"op_pairs", [("conv2d", "conv2d"), ("depthwise", "depthwise"), ("conv2d", "depthwise")] | ||
) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is 128 codegen tests, which would noticeably increase CI time. I think the variations on kernel_shape
, activation_function
, op_padding
and sep_padding
are exercised by other tests as well, so these values could be kept constant. Also, if we are parametrizing over one value, it doesn't need to be expressed with parametrize
and can be included into the test code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM! Thanks @sergio-grovety, @Aleksei-grovety and @arina-grovety!
Thanks all, this is merged now! |
Added a pass to to handle the situation when nn.pad operator has more than one qnn.conv2d consumer. pad / \ Conv2D Conv2D In this case, because of the peculiarities of pattern parsing, conv2d does not get into the composite for the NPU. Therefore, pads are added so that each has only one consumer. --------- Co-authored-by: Sergey Smirnov <89378719+sergey-grovety@users.noreply.github.com> Co-authored-by: Arina <117634809+arina-grovety@users.noreply.github.com> Co-authored-by: arina.naumova <naumova@grovety.com>
Added a pass to to handle the situation when nn.pad operator has more than one qnn.conv2d consumer. pad / \ Conv2D Conv2D In this case, because of the peculiarities of pattern parsing, conv2d does not get into the composite for the NPU. Therefore, pads are added so that each has only one consumer. --------- Co-authored-by: Sergey Smirnov <89378719+sergey-grovety@users.noreply.github.com> Co-authored-by: Arina <117634809+arina-grovety@users.noreply.github.com> Co-authored-by: arina.naumova <naumova@grovety.com>
Added a pass to to handle the situation when nn.pad operator has more than one qnn.conv2d consumer. pad / \ Conv2D Conv2D In this case, because of the peculiarities of pattern parsing, conv2d does not get into the composite for the NPU. Therefore, pads are added so that each has only one consumer. --------- Co-authored-by: Sergey Smirnov <89378719+sergey-grovety@users.noreply.github.com> Co-authored-by: Arina <117634809+arina-grovety@users.noreply.github.com> Co-authored-by: arina.naumova <naumova@grovety.com>
Added a pass to to handle the situation when nn.pad operator has more than one qnn.conv2d consumer.
In this case, because of the peculiarities of pattern parsing, conv2d does not get into the composite for the NPU. Therefore, pads are added so that each has only one consumer.