Skip to content

Commit db0ed6a

Browse files
inexorabletashhuningxinfdwr
authored
Introduce "valid dimension", used as needed when calculating operand shapes (#641)
* resample2d: Validate that dimensions are valid unsigned longs If explicit sizes aren't provided, the size of an output dimension is calculated as shape[i] * scales[i] which could be larger than can be represented as a dimension in MLOperandDescriptor. Explicitly validate and throw if this constraint isn't satisfied. Fixes #610 * Introduce 'valid dimension' term * Validate calculated dimensions when determining output shapes * Update index.bs Co-authored-by: Ningxin Hu <[email protected]> * Update index.bs Co-authored-by: Dwayne Robinson <[email protected]> --------- Co-authored-by: Ningxin Hu <[email protected]> Co-authored-by: Dwayne Robinson <[email protected]>
1 parent ee947fa commit db0ed6a

File tree

1 file changed

+26
-8
lines changed

1 file changed

+26
-8
lines changed

Diff for: index.bs

+26-8
Original file line numberDiff line numberDiff line change
@@ -1046,11 +1046,17 @@ dictionary MLOperandDescriptor {
10461046
1. Return |elementLength| * |elementSize|.
10471047
</details>
10481048

1049+
<p>
1050+
A <dfn>valid dimension</dfn> is an integer greater than zero in the range of {{unsigned long}}. Implementations may impose a smaller upper bound.
1051+
</p>
1052+
1053+
Issue(391): Should 0-size dimensions be supported?
1054+
10491055
<details open algorithm>
10501056
<summary>
10511057
To <dfn for="MLOperandDescriptor">check dimensions</dfn> given {{MLOperandDescriptor}} |descriptor|, run the following steps:
10521058
</summary>
1053-
1. If any element of |descriptor|.{{MLOperandDescriptor/dimensions}} is too large to be supported by the implementation, return false.
1059+
1. If any element of |descriptor|.{{MLOperandDescriptor/dimensions}} is not a [=valid dimension=], return false.
10541060
1. If |descriptor|.{{MLOperandDescriptor/dimensions}}'s [=list/size=] is too large to be supported by the implementation, return false.
10551061

10561062
Issue(456): The maximum number of operand dimensions is not defined, but native ML APIs usually have a maximum supported size.
@@ -1361,6 +1367,7 @@ Data truncation will occur when the values in the range exceed the range of the
13611367
1. Let |descriptor| be a new {{MLOperandDescriptor}}.
13621368
1. Set |descriptor|.{{MLOperandDescriptor/dataType}} to |type|.
13631369
1. Let |size| be max(0, ceil((|end| - |start|)/|step|)).
1370+
1. If |size| is not a [=valid dimension=], then [=exception/throw=] a {{TypeError}}.
13641371
1. Set |descriptor|.{{MLOperandDescriptor/dimensions}} to the [=/list=] « |size| ».
13651372
1. *Make graph connections:*
13661373
1. Let |operand| be the result of [=creating an MLOperand=] given [=this=] and |descriptor|.
@@ -1768,7 +1775,10 @@ partial interface MLGraphBuilder {
17681775
If the shape of each corresponding dimension and type of the operands, except for those of the dimension given by |axis|, is not the same, fail.
17691776
</div>
17701777
1. If |dim| is not equal to |axis| and if |input|'s [=MLOperand/shape=][|dim|] is not equal to |first|'s [=MLOperand/shape=][|dim|], then [=exception/throw=] a {{TypeError}}.
1771-
1. If |dim| is equal to |axis|, add to |desc|.{{MLOperandDescriptor/dimensions}}[|axis|] the value of |input|'s [=MLOperand/shape=][|dim|].
1778+
1. If |dim| is equal to |axis|:
1779+
1. Let |size| be the sum of |desc|.{{MLOperandDescriptor/dimensions}}[|axis|] and |input|'s [=MLOperand/shape=][|dim|].
1780+
1. If |size| is not a [=valid dimension=], then [=exception/throw=] a {{TypeError}}.
1781+
1. Set |desc|.{{MLOperandDescriptor/dimensions}}[|axis|] to |size|.
17721782
1. *Make graph connections:*
17731783
1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|.
17741784
1. Let |operator| be an [=operator=] for the concat operation, given |inputs| and |axis|.
@@ -1967,6 +1977,7 @@ partial interface MLGraphBuilder {
19671977
: {{MLInputOperandLayout/"nhwc"}}
19681978
:: Let |outputShape| be « |batches|, floor( |outputSizes|[0] ), floor( |outputSizes|[1] ), |outputChannels| ».
19691979
</dl>
1980+
1. If any [=list/item=] in |outputShape| is not a [=valid dimension=], then [=exception/throw=] a {{TypeError}}.
19701981
1. Let |desc| be a new {{MLOperandDescriptor}}.
19711982
1. Set |desc|.{{MLOperandDescriptor/dataType}} to |input|'s [=MLOperand/dataType=].
19721983
1. Set |desc|.{{MLOperandDescriptor/dimensions}} to |outputShape|.
@@ -2179,6 +2190,7 @@ partial interface MLGraphBuilder {
21792190
: {{MLInputOperandLayout/"nhwc"}}
21802191
:: Let |outputShape| be « |batches|, floor( |outputSizes|[0] ), floor( |outputSizes|[1] ), |outputChannels| ».
21812192
</dl>
2193+
1. If any [=list/item=] in |outputShape| is not a [=valid dimension=], then [=exception/throw=] a {{TypeError}}.
21822194
1. Let |desc| be a new {{MLOperandDescriptor}}.
21832195
1. Set |desc|.{{MLOperandDescriptor/dataType}} to |input|'s [=MLOperand/dataType=].
21842196
1. Set |desc|.{{MLOperandDescriptor/dimensions}} to |outputShape|.
@@ -4449,7 +4461,9 @@ partial interface MLGraphBuilder {
44494461
1. If [=MLGraphBuilder/validating operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}.
44504462
1. If |beginningPadding|'s [=list/size=] and |endingPadding|'s [=list/size=] are not both equal to |input|'s [=MLOperand/rank=], then [=exception/throw=] a "{{TypeError}}".
44514463
1. Let |desc| be a copy of |input|.{{MLOperand/[[descriptor]]}}.
4452-
1. Set |desc|.{{MLOperandDescriptor/dimensions}} to the result of [=MLGraphBuilder/calculating padding output sizes=] given |input|, |beginningPadding| and |endingPadding|.
4464+
1. Let |outputShape| be the result of [=MLGraphBuilder/calculating padding output sizes=] given |input|, |beginningPadding| and |endingPadding|.
4465+
1. If any [=list/item=] in |outputShape| is not a [=valid dimension=], then [=exception/throw=] a {{TypeError}}.
4466+
1. Set |desc|.{{MLOperandDescriptor/dimensions}} to |outputShape|.
44534467
1. *Make graph connections:*
44544468
1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|.
44554469
1. Let |operator| be an [=operator=] for the padding operation, given |beginningPadding|, |endingPadding| and |options|.
@@ -4667,8 +4681,10 @@ partial interface MLGraphBuilder {
46674681
1. If |options|.{{MLPool2dOptions/dilations}}'s [=list/size=] is not 2, then [=exception/throw=] a {{TypeError}}.
46684682
1. If any value in |options|.{{MLPool2dOptions/dilations}} is not greater than 0, then [=exception/throw=] a {{TypeError}}.
46694683
1. Let |desc| be a copy of |input|.{{MLOperand/[[descriptor]]}}.
4684+
1. Let |outputShape| be the result of [=MLGraphBuilder/calculating pool2d output sizes=] given |options|.{{MLPool2dOptions/layout}}, |input|'s [=MLOperand/shape=], |options|.{{MLPool2dOptions/roundingType}}, |options|.{{MLPool2dOptions/windowDimensions}}, |options|.{{MLPool2dOptions/padding}}, |options|.{{MLPool2dOptions/strides}}, |options|.{{MLPool2dOptions/dilations}}, and |options|.{{MLPool2dOptions/outputSizes}} (if it [=map/exists=]).
4685+
1. If any [=list/item=] in |outputShape| is not a [=valid dimension=], then [=exception/throw=] a {{TypeError}}.
4686+
1. Set |desc|.{{MLOperandDescriptor/dimensions}} to |outputShape|.
46704687
1. *Make graph connections:*
4671-
1. Set |desc|.{{MLOperandDescriptor/dimensions}} to the result of [=MLGraphBuilder/calculating pool2d output sizes=] given |options|.{{MLPool2dOptions/layout}}, |input|'s [=MLOperand/shape=], |options|.{{MLPool2dOptions/roundingType}}, |options|.{{MLPool2dOptions/windowDimensions}}, |options|.{{MLPool2dOptions/padding}}, |options|.{{MLPool2dOptions/strides}}, |options|.{{MLPool2dOptions/dilations}}, and |options|.{{MLPool2dOptions/outputSizes}} (if it [=map/exists=]).
46724688
1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|.
46734689
1. Let |operator| be an [=operator=] for the |op| pooling operation, given |options|.
46744690
1. Set |output|.{{MLOperand/[[operator]]}} to |operator|.
@@ -5083,8 +5099,10 @@ partial interface MLGraphBuilder {
50835099
</summary>
50845100
1. Let |desc| be a new {{MLOperandDescriptor}} initialized to |input|.{{MLOperand/[[descriptor]]}}.
50855101
1. For |index| in [=the range=] 0 to |options|.{{MLResample2dOptions/axes}}'s [=list/size=], exclusive:
5086-
1. If |options|.{{MLResample2dOptions/sizes}} [=map/exists=], set |desc|.{{MLOperandDescriptor/dimensions}}[|options|.{{MLResample2dOptions/axes}}[|index|]] to |options|.{{MLResample2dOptions/sizes}}[|index|].
5087-
1. Otherwise, set |desc|.{{MLOperandDescriptor/dimensions}}[|options|.{{MLResample2dOptions/axes}}[|index|]] to floor(|input|'s [=MLOperand/shape=][|options|.{{MLResample2dOptions/axes}}[|index|]] * |options|.{{MLResample2dOptions/scales}}[|index|]).
5102+
1. If |options|.{{MLResample2dOptions/sizes}} [=map/exists=], then let |size| be |options|.{{MLResample2dOptions/sizes}}[|index|].
5103+
1. Otherwise, let |size| be floor(|input|'s [=MLOperand/shape=][|options|.{{MLResample2dOptions/axes}}[|index|]] * |options|.{{MLResample2dOptions/scales}}[|index|]).
5104+
1. If |size| is not a [=valid dimension=], then return failure.
5105+
1. Set |desc|.{{MLOperandDescriptor/dimensions}}[|options|.{{MLResample2dOptions/axes}}[|index|]] to |size|.
50885106
1. Return |desc|.
50895107
</details>
50905108

@@ -5095,7 +5113,7 @@ partial interface MLGraphBuilder {
50955113
1. If [=MLGraphBuilder/validating operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}.
50965114
1. If |input|'s [=MLOperand/rank=] is not 4, then [=exception/throw=] a {{TypeError}}.
50975115
1. If [=MLGraphBuilder/checking resample options=] given |options| returns false, then [=exception/throw=] a {{TypeError}}.
5098-
1. Let |desc| be the result of [=MLGraphBuilder/calculating resample output sizes=] given |input| and |options|.
5116+
1. Let |desc| be the result of [=MLGraphBuilder/calculating resample output sizes=] given |input| and |options|. If that returns failure, then [=exception/throw=] a {{TypeError}}.
50995117
1. *Make graph connections:*
51005118
1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|.
51015119
1. Let |operator| be an [=operator=] for the resample 2D operation, given |options|.
@@ -5131,7 +5149,7 @@ partial interface MLGraphBuilder {
51315149
1. If [=MLGraphBuilder/validating operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}.
51325150
1. Let |outputShape| be an empty array of {{unsigned long}}.
51335151
1. If |newShape|'s [=list/size=] is 0, set |outputShape| to an empty [=/list=] for a scalar.
5134-
1. If any value in |newShape| is 0, then [=exception/throw=] a {{TypeError}}.
5152+
1. If any [=list/item=] in |newShape| is not a [=valid dimension=], then [=exception/throw=] a {{TypeError}}.
51355153
1. Let |inputElementCount| be the product of all elements in |input|'s [=MLOperand/shape=]. Empty dimensions yield an |inputElementCount| of 1.
51365154
1. If product of all values in |newShape| is not equal to |inputElementCount|, then [=exception/throw=] a {{TypeError}}.
51375155
1. Let |desc| be a copy of |input|.{{MLOperand/[[descriptor]]}}.

0 commit comments

Comments
 (0)