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
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 26 additions & 14 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -2658,15 +2658,17 @@ partial dictionary MLOpSupportLimits {
1. If |options|.{{MLConv2dOptions/bias}} [=map/exists=]:
1. If its [=MLOperand/shape=] is not [=list/equal=] to « |outputChannels| », then [=exception/throw=] a {{TypeError}}.
1. If its [=MLOperand/dataType=] is not one of its [=/allowed data types=] (according to [this table](#constraints-conv2d)), then [=exception/throw=] a {{TypeError}}.
1. Let |outputSizes| be the result of [=MLGraphBuilder/calculating conv2d output sizes=] given |inputHeight|, |inputWidth|, |filterHeight|, |filterWidth|, |options|.{{MLConv2dOptions/padding}}, |options|.{{MLConv2dOptions/strides}}, and |options|.{{MLConv2dOptions/dilations}}.
1. Let « |outputHeight|, |outputWidth| » be the result of [=MLGraphBuilder/calculating conv2d output sizes=] given |inputHeight|, |inputWidth|, |filterHeight|, |filterWidth|, |options|.{{MLConv2dOptions/padding}}, |options|.{{MLConv2dOptions/strides}}, and |options|.{{MLConv2dOptions/dilations}}.
1. Set |outputHeight| to floor( |outputHeight| ).
1. Set |outputWidth| to floor( |outputWidth| ).
1. If either |outputHeight| or |outputWidth| is not a [=valid dimension=], then [=exception/throw=] a {{TypeError}}.
1. Switch on |options|.{{MLConv2dOptions/inputLayout}}:
<dl class=switch>
: {{MLInputOperandLayout/"nchw"}}
:: Let |outputShape| be « |batches|, |outputChannels|, floor( |outputSizes|[0] ), floor( |outputSizes|[1] ) ».
:: Let |outputShape| be « |batches|, |outputChannels|, |outputHeight|, |outputWidth| ».
: {{MLInputOperandLayout/"nhwc"}}
:: Let |outputShape| be « |batches|, floor( |outputSizes|[0] ), floor( |outputSizes|[1] ), |outputChannels| ».
:: Let |outputShape| be « |batches|, |outputHeight|, |outputWidth|, |outputChannels| ».
</dl>
1. If any [=list/item=] in |outputShape| is not a [=valid dimension=], then [=exception/throw=] a {{TypeError}}.
1. Let |desc| be the result of [=creating an MLOperandDescriptor=] given |input|'s [=MLOperand/dataType=] and |outputShape|.
1. *Make graph connections:*
1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|.
Expand Down Expand Up @@ -2823,10 +2825,10 @@ partial dictionary MLOpSupportLimits {

<details open algorithm>
<summary>
To <dfn for=MLGraphBuilder>calculate convtranspose output size</dfn> given unsigned integers |inputSize|, |filterSize|, |beginningPadding|, |endingPadding|, |stride|, |dilation|, and |outputPadding|, perform these steps. They return a number.
To <dfn for=MLGraphBuilder>calculate convtranspose output size</dfn> given unsigned integers |inputSize|, |filterSize|, |beginningPadding|, |endingPadding|, |stride|, and |dilation|, perform these steps. They return a number.
</summary>
1. Let |effectiveFilterSize| be ( |filterSize| - 1 ) * |dilation| + 1.
1. Let |outputSize| be ( |inputSize| - 1 ) * |stride| + |effectiveFilterSize| - |beginningPadding| - |endingPadding| + |outputPadding|.
1. Let |outputSize| be ( |inputSize| - 1 ) * |stride| + |effectiveFilterSize| - |beginningPadding| - |endingPadding|.
1. Return |outputSize|.
</details>

Expand Down Expand Up @@ -2876,22 +2878,27 @@ partial dictionary MLOpSupportLimits {
</dl>
1. If |inputChannels| is not equal to |filterInputChannels|, then [=exception/throw=] a {{TypeError}}.
1. Let |outputChannels| be |filterOutputChannels| * |options|.{{MLConvTranspose2dOptions/groups}}.
1. If |outputChannels| is not a [=valid dimension=], then [=exception/throw=] a {{TypeError}}.
1. If |options|.{{MLConvTranspose2dOptions/bias}} [=map/exists=]:
1. If its [=MLOperand/shape=] is not [=list/equal=] to « |outputChannels| », then [=exception/throw=] a {{TypeError}}.
1. If its [=MLOperand/dataType=] is not one of its [=/allowed data types=] (according to [this table](#constraints-convTranspose2d)), then [=exception/throw=] a {{TypeError}}.
1. Let |calculatedOutputHeight| be the result of [=MLGraphBuilder/calculating convtranspose output size=] given |inputHeight|, |filterHeight|, |padding|[0], |padding|[1], |strides|[0] and |dilations|[0].
1. Let |calculatedOutputWidth| be the result of [=MLGraphBuilder/calculating convtranspose output size=] given |inputWidth|, |filterWidth|, |padding|[2], |padding|[3], |strides|[1] and |dilations|[1].
1. If |options|.{{MLConvTranspose2dOptions/outputSizes}} [=map/exists=], then:
1. Let « |outputHeight|, |outputWidth| » be |options|.{{MLConvTranspose2dOptions/outputSizes}}.
1. If |outputHeight| is less than |calculatedOutputHeight|, or |outputHeight| is greater than or equal to |calculatedOutputHeight| + |strides|[0], then [=exception/throw=] a {{TypeError}}.
1. If |outputWidth| is less than |calculatedOutputWidth|, or |outputWidth| is greater than or equal to |calculatedOutputWidth| + |strides|[1], then [=exception/throw=] a {{TypeError}}.
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

1. Let |outputWidth| be |calculatedOutputWidth| + |options|.{{MLConvTranspose2dOptions/outputPadding}}[1].
1. If either |outputHeight| or |outputWidth| is not a [=valid dimension=], then [=exception/throw=] a {{TypeError}}.
1. Switch on |options|.{{MLConvTranspose2dOptions/inputLayout}}:
<dl class=switch>
: {{MLInputOperandLayout/"nchw"}}
:: Let |outputShape| be « |batches|, |outputChannels|, floor( |outputHeight| ), floor( |outputWidth| ) ».
: {{MLInputOperandLayout/"nhwc"}}
:: 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}}.
1. Let |desc| be the result of [=creating an MLOperandDescriptor=] given |input|'s [=MLOperand/dataType=] and |outputShape|.
1. *Make graph connections:*
1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|.
Expand Down Expand Up @@ -5602,6 +5609,7 @@ partial dictionary MLOpSupportLimits {
1. Let |numDirections| be 2 if |options|.{{MLLstmOptions/direction}} is {{MLRecurrentNetworkDirection/"both"}}, or 1 otherwise.
1. If the [=MLOperand/dataType=] of any of |input|, |weight| or |recurrentWeight| is not one of its [=/allowed data types=] (according to [this table](#constraints-lstm)), then [=exception/throw=] a {{TypeError}}.
1. If the [=MLOperand/rank=] of any of |input|, |weight| or |recurrentWeight| is not its [=/allowed rank=], then [=exception/throw=] a {{TypeError}}.
1. If |steps| is 0, then [=exception/throw=] a {{TypeError}}.
1. If |input|'s [=MLOperand/shape=][0] is not equal to |steps|, then [=exception/throw=] a {{TypeError}}.
1. Let |batchSize| be |input|'s [=MLOperand/shape=][1].
1. Let |inputSize| be |input|'s [=MLOperand/shape=][2].
Expand Down Expand Up @@ -6547,6 +6555,7 @@ partial dictionary MLOpSupportLimits {
</dl>
1. If |options|.{{MLPool2dOptions/windowDimensions}} does not [=map/exist=], set |options|.{{MLPool2dOptions/windowDimensions}} to « |inputHeight|, |inputWidth| ».
1. If |options|.{{MLPool2dOptions/windowDimensions}}'s [=list/size=] is not 2, then [=exception/throw=] a {{TypeError}}.
1. If any [=list/item=] in |options|.{{MLPool2dOptions/windowDimensions}} is equal to 0, then [=exception/throw=] a {{TypeError}}.
1. If |options|.{{MLPool2dOptions/outputSizes}} [=map/exists=], or if |options|.{{MLPool2dOptions/padding}} does not [=map/exist=], set |options|.{{MLPool2dOptions/padding}} to the [=/list=] « 0, 0, 0, 0 ».
1. If |options|.{{MLPool2dOptions/padding}}'s [=list/size=] is not 4, then [=exception/throw=] a {{TypeError}}.
1. If |options|.{{MLPool2dOptions/strides}} does not [=map/exist=], set |options|.{{MLPool2dOptions/strides}} to the [=/list=] « 1, 1 ».
Expand All @@ -6560,11 +6569,13 @@ partial dictionary MLOpSupportLimits {
1. If any value in |options|.{{MLPool2dOptions/dilations}} is not greater than 0, then [=exception/throw=] a {{TypeError}}.
1. Let |desc| be a copy of |input|.{{MLOperand/[[descriptor]]}}.
1. *Calculate the output shape:*
1. If |options|.{{MLPool2dOptions/outputSizes}} [=map/exists=], then let « |outputHeight|, |outputWidth| » be |options|.{{MLPool2dOptions/outputSizes}}.
1. Let « |windowHeight|, |windowWidth| » be |options|.{{MLPool2dOptions/windowDimensions}}.
1. Let « |calculatedOutputHeight|, |calculatedOutputWidth| » be the result of [=MLGraphBuilder/calculating conv2d output sizes=] given |inputHeight|, |inputWidth|, |windowHeight|, |windowWidth|, |options|.{{MLPool2dOptions/padding}}, |options|.{{MLPool2dOptions/strides}}, and |options|.{{MLPool2dOptions/dilations}}.
1. If |options|.{{MLPool2dOptions/outputSizes}} [=map/exists=], then:
1. Let « |outputHeight|, |outputWidth| » be |options|.{{MLPool2dOptions/outputSizes}}.
1. If neither |outputHeight| equals floor( |calculatedOutputHeight| ) and |outputWidth| equals floor( |calculatedOutputWidth| ), nor |outputHeight| equals ceil( |calculatedOutputHeight| ) and |outputWidth| equals ceil( |calculatedOutputWidth| ), then [=exception/throw=] a {{TypeError}}.
1. Otherwise:
1. Let « |windowHeight|, |windowWidth| » be |options|.{{MLPool2dOptions/windowDimensions}}.
1. Let |outputSizes| be the result of [=MLGraphBuilder/calculating conv2d output sizes=] given |inputHeight|, |inputWidth|, |windowHeight|, |windowWidth|, |options|.{{MLPool2dOptions/padding}}, |options|.{{MLPool2dOptions/strides}}, and |options|.{{MLPool2dOptions/dilations}}.
1. Let « |outputHeight|, |outputWidth| » be |outputSizes|.
1. Let « |outputHeight|, |outputWidth| » be « |calculatedOutputHeight|, |calculatedOutputWidth| ».
1. Switch on |options|.{{MLPool2dOptions/roundingType}}:
<dl class=switch>
: {{MLRoundingType/"floor"}}
Expand All @@ -6576,14 +6587,14 @@ partial dictionary MLOpSupportLimits {
1. Set |outputWidth| to ceiling(|outputWidth|).
1. Set |outputHeight| to ceiling(|outputHeight|).
</dl>
1. If either |outputHeight| or |outputWidth| is not a [=valid dimension=], then [=exception/throw=] a {{TypeError}}.
1. Switch on |options|.{{MLPool2dOptions/layout}}:
<dl class=switch>
: {{MLInputOperandLayout/"nchw"}}
:: Let |outputShape| be « |batches|, |channels|, |outputHeight|, |outputWidth| ».
: {{MLInputOperandLayout/"nhwc"}}
:: Let |outputShape| be « |batches|, |outputHeight|, |outputWidth|, |channels| ».
</dl>
1. If any [=list/item=] in |outputShape| is not a [=valid dimension=], then [=exception/throw=] a {{TypeError}}.
1. Set |desc|.{{MLOperandDescriptor/shape}} to |outputShape|.
1. *Make graph connections:*
1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|.
Expand Down Expand Up @@ -7816,6 +7827,7 @@ partial dictionary MLOpSupportLimits {
1. Let |axis| be |options|.{{MLSplitOptions/axis}}.
1. If |axis| is greater than or equal to |input|'s [=MLOperand/rank=], then [=exception/throw=] a {{TypeError}}.
1. If |splits| is an {{unsigned long}}:
1. If |splits| is 0, then [=exception/throw=] a {{TypeError}}.
1. If |input|'s [=MLOperand/shape=][|axis|] % |splits| is not 0, then [=exception/throw=] a {{TypeError}}.
1. Otherwise, let |splitCount| be |splits|.
1. If |splits| is a [=sequence=]<{{unsigned long}}>:
Expand Down