Skip to content
New issue

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

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

Already on GitHub? Sign in to your account

Add missing validation steps for several ops #820

Merged
merged 2 commits into from
Feb 22, 2025

Conversation

inexorabletash
Copy link
Member

@inexorabletash inexorabletash commented Feb 19, 2025

A follow-on to #706 and the
audit by @huningxin that adds validation steps to several ops identified for edge cases in the Chromium prototype implementation.

This touches the following ops:

  • convTranspose2d - outputSizes items must be valid dimensions
  • lstm - steps must be greater than 0
  • pool2d - windowDimensions must be greater than 0
  • pool2d - outputSizes items must be valid dimensions
  • pool2d - specified output sizes must be floor() or ceil() of calculated output sizes
  • split - splits (if a number) must be greater than 0

Fixes #818 as well.


Preview | Diff

A follow-on to webmachinelearning#706 and the
[audit](https://docs.google.com/spreadsheets/d/1S5-bMWN1hDrkPGiHFCyX-OjcbEBj1a-aWNdtTQ2dcGg)
by @huningxin that adds validation steps to several ops identified for
edge cases in the Chromium prototype implementation.

This touches the following ops:

- convTranspose2d - outputSizes items must be valid dimensions
- lstm - steps must be greater than 0
- pool2d - windowDimensions must be greater than 0
- pool2d - outputSizes items must be valid dimensions
- pool2d - specified output sizes must be floor() or ceil() of calculated output sizes
- split - splits (if a number) must be greater than 0

Fixes webmachinelearning#818 as well.
@inexorabletash inexorabletash marked this pull request as draft February 19, 2025 00:29
@inexorabletash
Copy link
Member Author

@huningxin can you take an initial look? I went through the Chromium code and I believe this captures all of the validation missing from the spec for these ops, but I may have missed some.

I left "Issue" blocks in this PR for what I believe end up being redundant steps. In a few places we can validate e.g. outputHeight and outputWidth specifically, or we can validate all dimensions of outputShape, or both. I would personally prefer to just validate the individual dimensions and trust chat batches/channels are pre-validated, but maybe there are subtle reasons to keep both. Thoughts?

Copy link
Contributor

@huningxin huningxin left a comment

Choose a reason for hiding this comment

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

Thanks for fixing those edge cases! Looks good except having two comments for convTranspose2d, please take a look.

index.bs Outdated
@@ -2852,6 +2856,10 @@ partial dictionary MLOpSupportLimits {
1. Otherwise, if |options|.{{MLConvTranspose2dOptions/outputPadding}}'s [=list/size=] is not 2, then [=exception/throw=] a {{TypeError}}.
1. If |options|.{{MLConvTranspose2dOptions/outputSizes}} [=map/exists=]:
1. If its [=list/size=] is not 2, then [=exception/throw=] a {{TypeError}}.
1. If any of its [=list/items=] is not a [=valid dimension=], then [=exception/throw=] a {{TypeError}}.

Issue: The preceding step appears redundant with the validation of |outputHeight| and |outputWidth| below. Remove it?
Copy link
Contributor

Choose a reason for hiding this comment

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

sgtm

But I suppose we still need to validate the user-supplied output size according to stride and calculated output size which is computed by ignoring output padding, and ensure the user-supplied output size satisfying

calculated output size <= user-supplied output size < calculated output size + stride

like Chromium impl does: https://source.chromium.org/chromium/chromium/src/+/main:services/webnn/public/cpp/graph_validation_utils.cc;l=782;drc=8636bb104c0e28b695adfe050dd1b70bfe05cdc8

Copy link
Member Author

Choose a reason for hiding this comment

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

Removed the step (and issue), added that validation in a0ab8c7 - please verify?

index.bs Outdated
@@ -2892,6 +2901,9 @@ partial dictionary MLOpSupportLimits {
:: Let |outputShape| be « |batches|, floor( |outputHeight| ), floor( |outputWidth| ), |outputChannels| ».
</dl>
1. If any [=list/item=] in |outputShape| is not a [=valid dimension=], then [=exception/throw=] a {{TypeError}}.

Issue: The preceding step appears redundant with the validation of |outputHeight| and |outputWidth| above. Remove it?
Copy link
Contributor

Choose a reason for hiding this comment

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

outputChannels is calculated by step

Let |outputChannels| be |filterOutputChannels| * |options|.{{MLConvTranspose2dOptions/groups}}.

We may need to validate it right after that step? Like Chromium impl does: https://source.chromium.org/chromium/chromium/src/+/main:services/webnn/public/cpp/graph_validation_utils.cc;l=747;drc=8636bb104c0e28b695adfe050dd1b70bfe05cdc8

Copy link
Member Author

@inexorabletash inexorabletash Feb 21, 2025

Choose a reason for hiding this comment

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

Good point. Added validation in a0ab8c7. Please verify?

Copy link
Contributor

@huningxin huningxin left a comment

Choose a reason for hiding this comment

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

LGTM!

1. Otherwise:
1. Let |outputHeight| be the result of [=MLGraphBuilder/calculating convtranspose output size=] given |inputHeight|, |filterHeight|, |padding|[0], |padding|[1], |strides|[0], |dilations|[0], and |outputPadding|[0].
1. Let |outputWidth| be the result of [=MLGraphBuilder/calculating convtranspose output size=] given |inputWidth|, |filterWidth|, |padding|[2], |padding|[3], |strides|[1], |dilations|[1] and |outputPadding|[1].
1. Let |outputHeight| be |calculatedOutputHeight| + |options|.{{MLConvTranspose2dOptions/outputPadding}}[0].
Copy link
Contributor

Choose a reason for hiding this comment

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

This algorithm is simpler and clearer, the Chromium impl should be updated to this version. Thanks @inexorabletash !

Copy link
Contributor

Choose a reason for hiding this comment

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

/cc @miaobin

@inexorabletash inexorabletash marked this pull request as ready for review February 22, 2025 05:17
@inexorabletash
Copy link
Member Author

@fdwr can you take a look too please?

Copy link
Collaborator

@fdwr fdwr left a comment

Choose a reason for hiding this comment

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

👍

@fdwr fdwr merged commit 9f58451 into webmachinelearning:main Feb 22, 2025
2 checks passed
github-actions bot added a commit that referenced this pull request Feb 22, 2025
SHA: 9f58451
Reason: push, by fdwr

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@inexorabletash inexorabletash deleted the missing-validation branch February 22, 2025 07:28
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Validate user-supplied outputSizes of MLConvTranspose2dOptions and MLPool2dOptions
3 participants