From 81a986cd34179d8199b5f75ee2b70c59d301cc86 Mon Sep 17 00:00:00 2001 From: Joshua Bell Date: Fri, 15 Mar 2024 17:09:00 -0700 Subject: [PATCH 1/2] Synchronously validate input operands/validations Previously the spec had a "validate `MLOperand`" helper that (1) ensured the operand was from the passed `MLGraphBuilder` and (2) that the operand was internally consistent, and this was called during (3) `build()` and (4) only `concat()` among the vending methods. - (1) is needed but can be done when the `MLOperand` is created, giving better feedback, so (3) isn't needed. - (2) is not needed - `MLOperands` are immutable so they can't be created in a bad state. - (4) should be expanded to all `MLOperand` creations that take input `MLOperand`s. This renames the helper, ensures it is called by every `MLOperand` vending method that takes `MLOperand` inputs, and drops it from `build()` (although that will probably collide with PR #603 which should land first). Similar validation is added for `MLActivation`s. For #572 --- index.bs | 65 ++++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 54 insertions(+), 11 deletions(-) diff --git a/index.bs b/index.bs index e0e0dce0..c581f036 100644 --- a/index.bs +++ b/index.bs @@ -1116,15 +1116,9 @@ The {{MLOperand}} objects are created by the methods of {{MLGraphBuilder}}, inte 1. Return |result|. -
- - To validate MLOperand given {{MLOperand}} |operand| and {{MLGraphBuilder}} |builder|, run the following steps: - - 1. If |builder| is not equal to |operand|.{{MLOperand/[[builder]]}}, return false. - 1. Let |desc| be |operand|.{{MLOperand/[[descriptor]]}}. - 1. If [=MLOperandDescriptor/checking dimensions=] given |desc| returns false, then return false. - 1. Return true. -
+

+To validate input operand given {{MLGraphBuilder}} |builder| and {{MLOperand}} |operand|, return true if |operand|.{{MLOperand/[[builder]]}} is |builder|, and false otherwise. +

### {{MLOperand/dataType()}} ### {#api-mloperand-datatype} Return a data type of the {{MLOperand}}. @@ -1205,6 +1199,10 @@ The {{MLActivation}} objects (including the ones passed as input to methods) are 1. Return |activation|. +

+To validate activation given {{MLGraphBuilder}} |builder| and {{MLActivation}} |activation|, return true if |activation|.{{MLOperand/[[builder]]}} is |builder|, and false otherwise. +

+ ## {{MLGraphBuilder}} interface ## {#api-mlgraphbuilder} The {{MLGraphBuilder}} interface defines a set of operations as identified by the [[#usecases]] that can be composed into a computational graph. It also represents the intermediate state of a graph building session. @@ -1400,7 +1398,6 @@ Build a composed graph up to a given output operand into a computational graph a 1. Set |graph|.{{MLGraph/[[implementation]]}} to |graphImpl|. 1. Make a request to the underlying platform to initialize the graph: 1. [=map/For each=] |name| → |operand| of |outputs|: - 1. If [=MLOperand/validating MLOperand=] given |operand| and [=this=] returns false, then [=queue an ML task=] with |global| to [=reject=] |promise| with a {{TypeError}}, and abort these steps. 1. If |operand| was created as an input by the underlying platform: 1. If |operand|.{{MLOperand/[[name]]}} is not unique for |graphImpl|, then [=queue an ML task=] with |global| to [=reject=] |promise| with a {{TypeError}}, and abort these steps. 1. Add |operand|.{{MLOperand/[[descriptor]]}} to |graph|.{{MLGraph/[[inputDescriptors]]}}[|operand|.{{MLOperand/[[name]]}}]. @@ -1461,6 +1458,7 @@ partial interface MLGraphBuilder { To create argMin/argMax operation given [=string=] |op|, {{MLOperand}} |input| and {{MLArgMinMaxOptions}} |options|, run the following steps: 1. [=Assert=]: |op| is one of "argMin", "argMax". + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. If |options|.{{MLArgMinMaxOptions/axes}} [=map/exists=], if any of its elements is not in [=the range=] 0 to |input|'s [=MLOperand/rank=], exclusive, then [=exception/throw=] a {{TypeError}}. 1. Let |outputShape| be the result of [=MLGraphBuilder/calculating reduction output sizes=] given |input|'s [=MLOperand/shape=], |options|.{{MLArgMinMaxOptions/axes}} (if it [=map/exists=]), and |options|.{{MLArgMinMaxOptions/keepDimensions}}. 1. Let |desc| be a new {{MLOperandDescriptor}}. @@ -1549,6 +1547,8 @@ partial interface MLGraphBuilder { The batchNormalization(|input|, |mean|, |variance|, |options|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and any of |input|, |mean|, |variance|, |options|.{{MLBatchNormalizationOptions/scale}} (if it [=map/exists=]), and |options|.{{MLBatchNormalizationOptions/bias}} (if it [=map/exists=]) returns false, then [=exception/throw=] a {{TypeError}}. + 1. If |options|.{{MLBatchNormalizationOptions/activation}} [=map/exists=], and [=MLGraphBuilder/validating activation=] with [=this=] and it returns false, then [=exception/throw=] a {{TypeError}}. 1. If |options|.{{MLBatchNormalizationOptions/axis}} is not in [=the range=] 0 to |input|'s [=MLOperand/rank=], exclusive, then [=exception/throw=] a {{TypeError}}. 1. If |mean|'s [=MLOperand/rank=] is not 1, then [=exception/throw=] a {{TypeError}}. 1. If |mean|'s [=MLOperand/shape=][0] is not equal to |input|'s [=MLOperand/shape=][|options|.{{MLBatchNormalizationOptions/axis}}], then [=exception/throw=] a {{TypeError}}. @@ -1612,6 +1612,7 @@ partial interface MLGraphBuilder { The cast(|input|, |type|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. *Make graph connections:* 1. Let |operator| be an [=operator=] for the cast operation, given |type|. 1. Let |output| be the result of [=copying an MLOperand=] given |input|. @@ -1686,6 +1687,7 @@ partial interface MLGraphBuilder { The clamp(|input|, |options|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. If [=checking clamp options=] given |options| returns false, then [=exception/throw=] a {{TypeError}}. 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. @@ -1742,6 +1744,7 @@ partial interface MLGraphBuilder {
The permissions and context validity have been checked by [[#api-mlgraphbuilder-constructor]] steps.
+ 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and any [=list/item=] in |inputs| returns false, then [=exception/throw=] a {{TypeError}}. 1. If |inputs| [=list/is empty=], then [=exception/throw=] a {{TypeError}}. 1. Let |first| be |inputs|[0]. 1. If |axis| is greater than or equal to |first|'s [=MLOperand/rank=], then [=exception/throw=] a {{TypeError}}. @@ -1751,7 +1754,6 @@ partial interface MLGraphBuilder { 1. Set |desc|.{{MLOperandDescriptor/dimensions}}[|axis|] to |first|'s [=MLOperand/shape=][|axis|]. 1. [=list/For each=] |index| in [=the range=] 1 to |inputs|'s [=list/size=], exclusive: 1. Let |input| be |inputs|[|index|]. - 1. If [=MLOperand/validating MLOperand=] given |input| and [=this=] returns false, then [=exception/throw=] a {{TypeError}}. 1. If |input|'s [=MLOperand/dataType=] is not equal to |first|'s [=MLOperand/dataType=], then [=exception/throw=] a {{TypeError}}. 1. If |input|'s [=MLOperand/rank=] is not equal to |first|'s [=MLOperand/rank=], then [=exception/throw=] a {{TypeError}}. 1. [=list/For each=] |dim| in [=the range=] 0 to |input|'s [=MLOperand/rank=], exclusive: @@ -1885,6 +1887,8 @@ partial interface MLGraphBuilder { The conv2d(|input|, |filter|, |options|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and any of |input|, |filter|, and |options|.{{MLConv2dOptions/bias}} (if it [=map/exists=]) returns false, then [=exception/throw=] a {{TypeError}}. + 1. If |options|.{{MLConv2dOptions/activation}} [=map/exists=], and [=MLGraphBuilder/validating activation=] with [=this=] and it returns false, then [=exception/throw=] a {{TypeError}}. 1. Let |inputSize| be |input|'s [=MLOperand/rank=]. 1. Let |filterSize| be |filter|'s [=MLOperand/rank=]. 1. If |inputSize| is not 4, then [=exception/throw=] a {{TypeError}}. @@ -2087,6 +2091,8 @@ partial interface MLGraphBuilder { The convTranspose2d(|input|, |filter|, |options|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and any of |input|, |filter|, and |options|.{{MLConvTranspose2dOptions/bias}} (if it [=map/exists=]) returns false, then [=exception/throw=] a {{TypeError}}. + 1. If |options|.{{MLConvTranspose2dOptions/activation}} [=map/exists=], and [=MLGraphBuilder/validating activation=] with [=this=] and it returns false, then [=exception/throw=] a {{TypeError}}. 1. Let |inputSize| be |input|'s [=MLOperand/rank=]. 1. Let |filterSize| be |filter|'s [=MLOperand/rank=]. 1. If |inputSize| is not 4, then [=exception/throw=] a {{TypeError}}. @@ -2207,6 +2213,7 @@ partial interface MLGraphBuilder { To create element-wise binary operation given [=string=] |op|, {{MLOperand}} |a| and {{MLOperand}} |b|, run the following steps: 1. [=Assert=]: |op| is one of "add", "sub", "mul", "div", "max", "min", "pow". + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and any of |a| and |b| returns false, then [=exception/throw=] a {{TypeError}}. 1. If |a|'s [=MLOperand/dataType=] is not equal to |b|'s [=MLOperand/dataType=], then [=exception/throw=] a {{TypeError}}. 1. Let |descriptor| be a new {{MLOperandDescriptor}}. 1. Set |descriptor|.{{MLOperandDescriptor/dataType}} to |a|'s [=MLOperand/dataType=]. @@ -2319,8 +2326,10 @@ Although operations {{MLGraphBuilder/greaterOrEqual()}} and {{MLGraphBuilder/les 1. [=Assert=]: |op| is one of "equal", "greater", "greaterOrEqual", "lesser", "lesserOrEqual", "not". 1. If |op| is "not". + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |a| returns false, then [=exception/throw=] a {{TypeError}}. 1. If |a|'s [=MLOperand/dataType=] isn't {{MLOperandDataType/"uint8"}}, then [=exception/throw=] a {{TypeError}}. 1. If |op| is anything else but "not". + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and any of |a| and |b| returns false, then [=exception/throw=] a {{TypeError}}. 1. If |a|'s [=MLOperand/dataType=] is not equal to |b|'s [=MLOperand/dataType=], then [=exception/throw=] a {{TypeError}}. 1. Let |descriptor| be a new {{MLOperandDescriptor}}. 1. Set |descriptor|.{{MLOperandDescriptor/dataType}} to {{MLOperandDataType/"uint8"}}. @@ -2433,6 +2442,7 @@ partial interface MLGraphBuilder { To create element-wise unary operation given [=string=] |op| and {{MLOperand}} |input|, run the following steps: 1. [=Assert=]: |op| is one of "abs", "ceil", "cos", "erf", "exp", "floor", "identity", "log", "neg", "reciprocal", "sin", "sqrt", "tan". + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. 1. Let |operator| be an [=operator=] for the unary operation |op|. @@ -2587,6 +2597,7 @@ partial interface MLGraphBuilder { The elu(|input|, |options|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. 1. Let |operator| be an [=operator=] for the ELU operation, given |options|. @@ -2636,6 +2647,7 @@ partial interface MLGraphBuilder {
The permissions and context validity have been checked by [[#api-mlgraphbuilder-constructor]] steps.
+ 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. Let |outputDescriptor| be a new {{MLOperandDescriptor}}. 1. Set |outputDescriptor|.{{MLOperandDescriptor/dataType}} to |input|'s [=MLOperand/dataType=]. 1. Set |outputDescriptor|.{{MLOperandDescriptor/dimensions}} to the result of [=unidirectionally broadcasting the shapes=] |input|'s [=MLOperand/shape=] and |newShape|. @@ -2681,6 +2693,7 @@ partial interface MLGraphBuilder { The gather(|input|, |indices|, |options|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and any of |input| abd |indices| returns false, then [=exception/throw=] a {{TypeError}}. 1. If |indices|'s [=MLOperand/dataType=] is neither {{MLOperandDataType/"uint32"}} nor {{MLOperandDataType/"int64"}}, then [=exception/throw=] a {{TypeError}}. 1. Let |shapeInput| be |input|'s [=MLOperand/shape=] and |rankInput| be |shapeInput|'s [=MLOperand/rank=]. 1. Let |shapeIndices| be |indices|'s [=MLOperand/shape=]. @@ -2827,6 +2840,7 @@ partial interface MLGraphBuilder { The gemm(|a|, |b|, |options|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and any of |a| and |b| returns false, then [=exception/throw=] a {{TypeError}}. 1. Let |shapeA| be a [=list/clone=] of |a|'s [=MLOperand/shape=]. 1. Let |sizeA| be the [=list/size=] of |shapeA|. 1. Let |shapeB| be a [=list/clone=] of |b|'s [=MLOperand/shape=]. @@ -2957,6 +2971,8 @@ partial interface MLGraphBuilder { The gru(|input|, |weight|, |recurrentWeight|, |steps|, |hiddenSize|, |options|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and any of |input|, |weight|, |recurrentWeight|, |options|.{{MLGruOptions/bias}} (if it [=map/exists=]), |options|.{{MLGruOptions/recurrentBias}} (if it [=map/exists=]), and |options|.{{MLGruOptions/initialHiddenState}} returns false, then [=exception/throw=] a {{TypeError}}. + 1. If |options|.{{MLGruOptions/activations}} [=map/exists=], and [=MLGraphBuilder/validating activation=] with [=this=] and any [=list/item=] in it returns false, then [=exception/throw=] a {{TypeError}}. 1. If |input|'s [=MLOperand/rank=] or |weight| or |recurrentWeight| is not 3, then [=exception/throw=] a {{TypeError}}. 1. If |options|.{{MLGruOptions/bias}} [=map/exists=]. 1. If |options|.{{MLGruOptions/bias}}'s [=MLOperand/shape=][1] is not equal to 3 * |hiddenSize|, then [=exception/throw=] a {{TypeError}}. @@ -3122,6 +3138,8 @@ partial interface MLGraphBuilder { The gruCell(|input|, |weight|, |recurrentWeight|, |hiddenState|, |hiddenSize|, |options|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and any of |input|, |weight|, |recurrentWeight|, |hiddenState|, |options|.{{MLGruCellOptions/bias}} (if it [=map/exists=]), and |options|.{{MLGruCellOptions/recurrentBias}} (if it [=map/exists=]) returns false, then [=exception/throw=] a {{TypeError}}. + 1. If |options|.{{MLGruCellOptions/activations}} [=map/exists=], and [=MLGraphBuilder/validating activation=] with [=this=] and any [=list/item=] in it returns false, then [=exception/throw=] a {{TypeError}}. 1. If |input|'s [=MLOperand/rank=] or |weight| or |recurrentWeight| or |hiddenState| is not 2, then [=exception/throw=] a {{TypeError}}. 1. If |weight|'s [=MLOperand/shape=][0] is not equal to 3 * |hiddenSize|, then [=exception/throw=] a {{TypeError}}. 1. If |recurrentWeight|'s [=MLOperand/shape=][0] is not equal to 3 * |hiddenSize|, then [=exception/throw=] a {{TypeError}}. @@ -3301,6 +3319,7 @@ partial interface MLGraphBuilder { The hardSigmoid(|input|, |options|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. 1. Let |operator| be an [=operator=] for the hard sigmoid operation, given |options|. @@ -3372,6 +3391,7 @@ partial interface MLGraphBuilder { The hardSwish(|input|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. 1. Let |operator| be an [=operator=] for the hard-swish operation. @@ -3449,6 +3469,7 @@ partial interface MLGraphBuilder { The instanceNormalization(|input|, |options|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and any of |input|, |options|.{{MLInstanceNormalizationOptions/scale}} (if it [=map/exists=]), and |options|.{{MLInstanceNormalizationOptions/bias}} (if it [=map/exists=]) returns false, then [=exception/throw=] a {{TypeError}}. 1. If |input|'s [=MLOperand/rank=] is not 4, then [=exception/throw=] a {{TypeError}}. 1. If |options|.{{MLInstanceNormalizationOptions/scale}}'s [=MLOperand/rank=] is not equal to 1, then [=exception/throw=] a {{TypeError}}. 1. If |options|.{{MLInstanceNormalizationOptions/bias}}'s [=MLOperand/rank=] is not equal to 1, then [=exception/throw=] a {{TypeError}}. @@ -3545,6 +3566,7 @@ partial interface MLGraphBuilder { The layerNormalization(|input|, |options|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and any of |input|, |options|.{{MLLayerNormalizationOptions/scale}} (if it [=map/exists=]), and |options|.{{MLLayerNormalizationOptions/bias}} (if it [=map/exists=]) returns false, then [=exception/throw=] a {{TypeError}}. 1. If |options|.{{MLLayerNormalizationOptions/axes}} does not [=map/exist=], then set |options|.{{MLLayerNormalizationOptions/axes}} to a new [=/list=], either equal to [=the range=] from 1 to |input|'s [=MLOperand/rank=], exclusive, if |input|'s [=MLOperand/rank=] is greater than 1, or an empty [=/list=] otherwise. 1. If |options|.{{MLLayerNormalizationOptions/scale}}'s [=MLOperand/rank=] is not equal to |options|.{{MLLayerNormalizationOptions/axes}}'s [=list/size=], then [=exception/throw=] a {{TypeError}}. 1. If |options|.{{MLLayerNormalizationOptions/bias}}'s [=MLOperand/rank=] is not equal to |options|.{{MLLayerNormalizationOptions/axes}}'s [=list/size=], then [=exception/throw=] a {{TypeError}}. @@ -3650,6 +3672,7 @@ partial interface MLGraphBuilder { The leakyRelu(|input|, |options|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. 1. Let |operator| be an [=operator=] for the Leaky RELU operation, given |options|. @@ -3732,6 +3755,7 @@ partial interface MLGraphBuilder { The linear(|input|, |options|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. 1. Let |operator| be an [=operator=] for the linear operation, given |options|. @@ -3845,6 +3869,8 @@ partial interface MLGraphBuilder { The lstm(|input|, |weight|, |recurrentWeight|, |steps|, |hiddenSize|, |options|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and any of |input|, |weight|, |recurrentWeight|, |options|.{{MLLstmOptions/bias}} (if it [=map/exists=]), |options|.{{MLLstmOptions/recurrentBias}} (if it [=map/exists=]), |options|.{{MLLstmOptions/peepholeWeight}} (if it [=map/exists=]), |options|.{{MLLstmOptions/initialHiddenState}} (if it [=map/exists=]), and |options|.{{MLLstmOptions/initialCellState}} returns false, then [=exception/throw=] a {{TypeError}}. + 1. If |options|.{{MLLstmOptions/activations}} [=map/exists=], and [=MLGraphBuilder/validating activation=] with [=this=] and any [=list/item=] in it returns false, then [=exception/throw=] a {{TypeError}}. 1. Let |numDirections| be 1 if |options|.{{MLLstmOptions/direction}} is {{MLRecurrentNetworkDirection/"forward"}}, or otherwise let it be 2. 1. If |input|'s [=MLOperand/rank=] or |weight| or |recurrentWeight| is not 3, then [=exception/throw=] a {{TypeError}}. 1. If |input|'s [=MLOperand/shape=][0] is not equal to |steps|, then [=exception/throw=] a {{TypeError}}. @@ -4050,6 +4076,8 @@ partial interface MLGraphBuilder { The lstmCell(|input|, |weight|, |recurrentWeight|, |hiddenState|, |cellState|, |hiddenSize|, |options|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and any of |input|, |weight|, |recurrentWeight|, |hiddenState|, |cellState|, |options|.{{MLLstmCellOptions/bias}} (if it [=map/exists=]), |options|.{{MLLstmCellOptions/recurrentBias}} (if it [=map/exists=]), and |options|.{{MLLstmCellOptions/peepholeWeight}} returns false, then [=exception/throw=] a {{TypeError}}. + 1. If |options|.{{MLLstmCellOptions/activations}} [=map/exists=], and [=MLGraphBuilder/validating activation=] with [=this=] and any [=list/item=] in it returns false, then [=exception/throw=] a {{TypeError}}. 1. If |input|'s [=MLOperand/rank=], |weight|, |recurrentWeight|, |hiddenState| or |cellState| is not 2, then [=exception/throw=] a {{TypeError}}. 1. Let |batchSize| be |input|'s [=MLOperand/shape=][0]. 1. If |options|.{{MLLstmCellOptions/bias}} [=map/exists=]: @@ -4245,6 +4273,7 @@ partial interface MLGraphBuilder { The matmul(|a|, |b|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and any of |a| and |b| returns false, then [=exception/throw=] a {{TypeError}}. 1. Let |desc| be a new {{MLOperandDescriptor}}. 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to the result of [=MLGraphBuilder/calculating matmul output sizes=] given |a| and |b|. 1. If that throws an error, re-[=exception/throw=] the error. @@ -4319,6 +4348,7 @@ partial interface MLGraphBuilder { The pad(|input|, |beginningPadding|, |endingPadding|, |options|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 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}}". 1. Let |desc| be a copy of |input|.{{MLOperand/[[descriptor]]}}. 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to the result of [=MLGraphBuilder/calculating padding output sizes=] given |input|, |beginningPadding| and |endingPadding|. @@ -4523,6 +4553,7 @@ partial interface MLGraphBuilder { To create pooling operation given [=string=] |op|, {{MLOperand}} |input| and {{MLPool2dOptions}} |options|, run the following steps: 1. [=Assert=]: |op| is one of "averagePool2d", "l2Pool2d", "maxPool2d". + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. If |input|'s [=MLOperand/rank=] is not 4, then [=exception/throw=] a {{TypeError}}. 1. If |options|.{{MLPool2dOptions/windowDimensions}} [=map/exists=] and its [=list/size=] is not 2, then [=exception/throw=] a {{TypeError}}. 1. Otherwise, set |options|.{{MLPool2dOptions/windowDimensions}} to the height and width dimensions of the shape of |input|. @@ -4604,6 +4635,7 @@ partial interface MLGraphBuilder { The prelu(|input|, |slope|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. Let |descriptor| be a new {{MLOperandDescriptor}}. 1. Set |descriptor|.{{MLOperandDescriptor/dataType}} to |input|'s [=MLOperand/dataType=]. 1. Set |descriptor|.{{MLOperandDescriptor/dimensions}} to the result of [=unidirectionally broadcasting the shapes=] |slope|'s [=MLOperand/shape=] and |input|'s [=MLOperand/shape=]. @@ -4709,6 +4741,7 @@ partial interface MLGraphBuilder { To create reduce operation given [=string=] |op|, {{MLOperand}} |input| and {{MLReduceOptions}} |options|, run the following steps: 1. [=Assert=]: |op| is one of "reduceL1", "reduceL2", "reduceLogSum", "reduceLogSumExp", "reduceMax", "reduceMean", "reduceMin", "reduceProduct", "reduceSum", "reduceSumSquare". + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. If |options|.{{MLReduceOptions/axes}} [=map/exists=], if any of its elements is not in [=the range=] 0 to |input|'s [=MLOperand/rank=], exclusive, then [=exception/throw=] a {{TypeError}}. 1. Let |outputShape| be the result of [=MLGraphBuilder/calculating reduction output sizes=] given |input|'s [=MLOperand/shape=], |options|.{{MLReduceOptions/axes}} (if it [=map/exists=]), and |options|.{{MLReduceOptions/keepDimensions}}. 1. Let |desc| be a new {{MLOperandDescriptor}}. @@ -4835,6 +4868,7 @@ partial interface MLGraphBuilder { The relu(|input|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. 1. Let |operator| be an [=operator=] for the ReLU operation. @@ -4940,6 +4974,7 @@ partial interface MLGraphBuilder { The resample2d(|input|, |options|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. If |input|'s [=MLOperand/rank=] is not 4, then [=exception/throw=] a {{TypeError}}. 1. If [=MLGraphBuilder/checking resample options=] given |options| returns false, then [=exception/throw=] a {{TypeError}}. 1. Let |desc| be the result of [=MLGraphBuilder/calculating resample output sizes=] given |input| and |options|. @@ -4975,6 +5010,7 @@ partial interface MLGraphBuilder { The reshape(|input|, |newShape|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. Let |outputShape| be an empty array of {{unsigned long}}. 1. If |newShape|'s [=list/size=] is 0, set |outputShape| to an empty [=/list=] for a scalar. 1. If any value in |newShape| is 0, then [=exception/throw=] a {{TypeError}}. @@ -5068,6 +5104,7 @@ partial interface MLGraphBuilder { The sigmoid(|input|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. 1. Let |operator| be an [=operator=] for the sigmoid operation. @@ -5117,6 +5154,7 @@ partial interface MLGraphBuilder { The slice(|input|, |starts|, |sizes|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. If |sizes|'s [=list/size=] is 0, then [=exception/throw=] a {{TypeError}}. 1. If |starts|'s [=list/size=] and |sizes|'s [=list/size=] are not both equal to |input|'s [=MLOperand/rank=], then [=exception/throw=] a {{TypeError}}. 1. *Make graph connections:* @@ -5172,6 +5210,7 @@ partial interface MLGraphBuilder { The softmax(|input|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. If |input|'s [=MLOperand/rank=] is not 2, then [=exception/throw=] a {{TypeError}}. 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. @@ -5253,6 +5292,7 @@ partial interface MLGraphBuilder { The softplus(|input|, |options|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. 1. Let |operator| be an [=operator=] for the softplus operation, given |options|. @@ -5316,6 +5356,7 @@ partial interface MLGraphBuilder { The softsign(|input|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. 1. Let |operator| be an [=operator=] for the softsign operation. @@ -5377,6 +5418,7 @@ partial interface MLGraphBuilder { The split(|input|, |splits|, |options|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. Let |axis| be |options|.{{MLSplitOptions/axis}}. 1. If |splits| is an {{unsigned long}}: 1. If |input|'s [=MLOperand/shape=][|axis|] % |splits| is not 0, then [=exception/throw=] a {{TypeError}}. @@ -5462,6 +5504,7 @@ partial interface MLGraphBuilder { The tanh(|input|) method steps are: + 1. If [=MLGraphBuilder/validating input operand=] with [=this=] and |input| returns false, then [=exception/throw=] a {{TypeError}}. 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. 1. Let |operator| be an [=operator=] for the hyperbolic tangent operation. From 3d97b98ee6d8e902782d98d2ab7c36acfd7663c0 Mon Sep 17 00:00:00 2001 From: Joshua Bell Date: Tue, 19 Mar 2024 09:24:46 -0700 Subject: [PATCH 2/2] Apply suggestions from code review Missed a few "if it exists" clauses Co-authored-by: Ningxin Hu --- index.bs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.bs b/index.bs index 0950f231..f7f87123 100644 --- a/index.bs +++ b/index.bs @@ -2981,7 +2981,7 @@ partial interface MLGraphBuilder { The gru(|input|, |weight|, |recurrentWeight|, |steps|, |hiddenSize|, |options|) method steps are: - 1. If [=MLGraphBuilder/validating operand=] with [=this=] and any of |input|, |weight|, |recurrentWeight|, |options|.{{MLGruOptions/bias}} (if it [=map/exists=]), |options|.{{MLGruOptions/recurrentBias}} (if it [=map/exists=]), and |options|.{{MLGruOptions/initialHiddenState}} returns false, then [=exception/throw=] a {{TypeError}}. + 1. If [=MLGraphBuilder/validating operand=] with [=this=] and any of |input|, |weight|, |recurrentWeight|, |options|.{{MLGruOptions/bias}} (if it [=map/exists=]), |options|.{{MLGruOptions/recurrentBias}} (if it [=map/exists=]), and |options|.{{MLGruOptions/initialHiddenState}} (if it [=map/exists=]) returns false, then [=exception/throw=] a {{TypeError}}. 1. If |options|.{{MLGruOptions/activations}} [=map/exists=], and [=MLGraphBuilder/validating activation=] with [=this=] and any [=list/item=] in it returns false, then [=exception/throw=] a {{TypeError}}. 1. If |input|'s [=MLOperand/rank=] or |weight| or |recurrentWeight| is not 3, then [=exception/throw=] a {{TypeError}}. 1. If |options|.{{MLGruOptions/bias}} [=map/exists=]. @@ -3879,7 +3879,7 @@ partial interface MLGraphBuilder { The lstm(|input|, |weight|, |recurrentWeight|, |steps|, |hiddenSize|, |options|) method steps are: - 1. If [=MLGraphBuilder/validating operand=] with [=this=] and any of |input|, |weight|, |recurrentWeight|, |options|.{{MLLstmOptions/bias}} (if it [=map/exists=]), |options|.{{MLLstmOptions/recurrentBias}} (if it [=map/exists=]), |options|.{{MLLstmOptions/peepholeWeight}} (if it [=map/exists=]), |options|.{{MLLstmOptions/initialHiddenState}} (if it [=map/exists=]), and |options|.{{MLLstmOptions/initialCellState}} returns false, then [=exception/throw=] a {{TypeError}}. + 1. If [=MLGraphBuilder/validating operand=] with [=this=] and any of |input|, |weight|, |recurrentWeight|, |options|.{{MLLstmOptions/bias}} (if it [=map/exists=]), |options|.{{MLLstmOptions/recurrentBias}} (if it [=map/exists=]), |options|.{{MLLstmOptions/peepholeWeight}} (if it [=map/exists=]), |options|.{{MLLstmOptions/initialHiddenState}} (if it [=map/exists=]), and |options|.{{MLLstmOptions/initialCellState}} (if it [=map/exists=]) returns false, then [=exception/throw=] a {{TypeError}}. 1. If |options|.{{MLLstmOptions/activations}} [=map/exists=], and [=MLGraphBuilder/validating activation=] with [=this=] and any [=list/item=] in it returns false, then [=exception/throw=] a {{TypeError}}. 1. Let |numDirections| be 1 if |options|.{{MLLstmOptions/direction}} is {{MLRecurrentNetworkDirection/"forward"}}, or otherwise let it be 2. 1. If |input|'s [=MLOperand/rank=] or |weight| or |recurrentWeight| is not 3, then [=exception/throw=] a {{TypeError}}. @@ -4086,7 +4086,7 @@ partial interface MLGraphBuilder { The lstmCell(|input|, |weight|, |recurrentWeight|, |hiddenState|, |cellState|, |hiddenSize|, |options|) method steps are: - 1. If [=MLGraphBuilder/validating operand=] with [=this=] and any of |input|, |weight|, |recurrentWeight|, |hiddenState|, |cellState|, |options|.{{MLLstmCellOptions/bias}} (if it [=map/exists=]), |options|.{{MLLstmCellOptions/recurrentBias}} (if it [=map/exists=]), and |options|.{{MLLstmCellOptions/peepholeWeight}} returns false, then [=exception/throw=] a {{TypeError}}. + 1. If [=MLGraphBuilder/validating operand=] with [=this=] and any of |input|, |weight|, |recurrentWeight|, |hiddenState|, |cellState|, |options|.{{MLLstmCellOptions/bias}} (if it [=map/exists=]), |options|.{{MLLstmCellOptions/recurrentBias}} (if it [=map/exists=]), and |options|.{{MLLstmCellOptions/peepholeWeight}} (if it [=map/exists=]) returns false, then [=exception/throw=] a {{TypeError}}. 1. If |options|.{{MLLstmCellOptions/activations}} [=map/exists=], and [=MLGraphBuilder/validating activation=] with [=this=] and any [=list/item=] in it returns false, then [=exception/throw=] a {{TypeError}}. 1. If |input|'s [=MLOperand/rank=], |weight|, |recurrentWeight|, |hiddenState| or |cellState| is not 2, then [=exception/throw=] a {{TypeError}}. 1. Let |batchSize| be |input|'s [=MLOperand/shape=][0].