From 4f07efbe55304f85a5abdada5b27dae6afbd2c49 Mon Sep 17 00:00:00 2001 From: Joshua Bell Date: Wed, 28 Feb 2024 13:50:31 -0800 Subject: [PATCH 1/7] Content: Define operand concept, simplify graph connection steps As discussed in #572: - Define an "operator" concept, with inputs, outputs, activations. - Defer "platform operator" and "platform operand" to build. - Standardize the graph connection steps across builder methods. - Simplify activation, input and constant steps. Not covered in this change: - Erroring if input's [[builder]] doesn't match `this` - Build algorithm - covered by #448 and #457 - gru() is missing steps to populate output. Added "Issue" note. - Introducing "Validate arguments" section for each method. - Introducing "Calculate output shape" section for each method. For #549 and #572. --- index.bs | 648 ++++++++++++++++++++++--------------------------------- 1 file changed, 253 insertions(+), 395 deletions(-) diff --git a/index.bs b/index.bs index e3c7f4a7..2bbfded8 100644 --- a/index.bs +++ b/index.bs @@ -694,21 +694,11 @@ graphs of neural networks. The {{MLGraph}} interface represents a compiled computational graph that is immutable (that is, a model). -The {{MLGraphBuilder}} interface serves as a builder (factory) to create an {{MLGraph}}. -An {{MLOperand}} is a representation of data that flows within the computational graph, -which include input-values for inference, constants (including trained weights) -used for inference, intermediate values (often referred to as activations) computed -during inference, as well as the output values of inference. -At inference time, every {{MLOperand}} will be bound to a tensor (the actual data). - -The {{MLGraphBuilder}} interface enables the creation of {{MLOperand}}s. -A key part of the {{MLGraphBuilder}} interface are the operations (such as -{{MLGraphBuilder}}.{{MLGraphBuilder/gemm()}} and {{MLGraphBuilder}}.{{MLGraphBuilder/softmax()}}). The operations have a functional -semantics, with no side effects. -Each operation invocation conceptually returns a distinct new value, without -changing the value of any other {{MLOperand}}. - -Internally, the {{MLGraphBuilder}} methods such as {{MLGraphBuilder/gemm()}} create an [=implementation-defined=] platform operator which is held by the {{MLOperand}} or {{MLActivation}}, which performs the actual operation on the input data when the computation is run. An {{MLOperand}} also holds an [=implementation-defined=] platform operand, which references the operand in the underlying computational graph, and is connected to [=platform operators=] as input and/or output. +The {{MLGraphBuilder}} interface serves as a builder (factory) to construct the computation graph that is then compiled to create an MLGraph. + +In WebNN, the computational graph is composed of operators which act on data, and are the nodes of the graph. An [=operator=]'s input is one or more {{MLOperand}}s representing the data flow for the computation, and are the edges of the graph. Operands include input values, constants (including trained weights), and intermediate values (often referred to as activations). An [=operator=]'s output is one or more {{MLOperand}}s, representing the output values of the computation. [=Operators=] have operator-specific parameters that control their behavior, which can include zero or more activation functions, which are {{MLActivation}}s. The operations have functional semantics, with no side effects. Each operation invocation conceptually returns a distinct new value, without changing the value of any other {{MLOperand}}. + +A key part of the {{MLGraphBuilder}} interface are methods such as {{MLGraphBuilder/gemm()}} and {{MLGraphBuilder/softmax()}} which create an operator which represents actual operation to perform on the input data when the computation is run, and return a new {{MLOperand}} or {{MLActivation}} holding the operator. Methods that create an {{MLOperand}} connect any [=operator/inputs=] and [=operator/activations=] to the operator. The runtime values (of {{MLOperand}}s) are tensors, which are essentially multidimensional arrays. The representation of the tensors is implementation dependent, but it typically @@ -726,6 +716,8 @@ Before the execution, the computation graph that is used to compute one or more The {{MLGraphBuilder}}.{{MLGraphBuilder/build()}} method compiles the graph in the background without blocking the calling thread, and returns a {{Promise}} that resolves to an {{MLGraph}}. The compilation step produces an {{MLGraph}} that represents a compiled graph for optimal execution. +The {{MLGraph}} is composed of platform operators and platform operands which correspond to the [=operators=] and {{MLOperand}}s, but are not script-visible and may be compositions or decompositions of the graph as constructed by script. + Once the {{MLGraph}} is constructed, the {{MLContext}}.{{MLContext/compute()}} method performs the execution of the graph asynchronously either on a parallel timeline in a separate worker thread for the CPU execution or on a GPU timeline in a GPU command queue. This method returns immediately without blocking the calling thread while the actual execution is offloaded to a different timeline. The caller supplies the input values using {{MLNamedArrayBufferViews}}, binding the input {{MLOperand}}s to their values. The caller then supplies pre-allocated buffers for output {{MLOperand}}s using {{MLNamedArrayBufferViews}}. The execution produces the results of the computation from all the inputs bound to the graph. The computation results will be placed at the bound outputs at the time the operation is successfully completed on the offloaded timeline at which time the calling thread is signaled. This type of execution supports both the CPU and GPU device. ## Device Selection ## {#programming-model-device-selection} @@ -1148,13 +1140,9 @@ interface MLOperand { :: The {{MLOperand}}'s name (only for input operands). - : \[[operand]] of type [=platform operand=] + : \[[operator]] of type [=operator=] :: - Reference to {{MLOperand}}'s corresponding [=platform operand=]. - - : \[[operator]] of type [=platform operator=] - :: - Reference to {{MLOperand}}'s corresponding [=platform operator=]. + Reference to {{MLOperand}}'s corresponding [=operator=]. @@ -1259,9 +1247,9 @@ interface MLActivation {}; : \[[options]] of type [=ordered map=] :: A dictionary containing {{MLActivation}} options. - : \[[operator]] of type [=platform operator=] + : \[[operator]] of type [=operator=] :: - Reference to {{MLActivation}}'s corresponding [=platform operator=]. + Reference to {{MLActivation}}'s corresponding [=operator=]. @@ -1283,12 +1271,10 @@ The {{MLActivation}} objects (including the ones passed as input to methods) are 1. Set |activation|.{{MLActivation/[[builder]]}} to |builder|. 1. Set |activation|.{{MLActivation/[[name]]}} to |name|. 1. If |options| is given, set |activation|.{{MLActivation/[[options]]}} to |options|. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. - 1. Make a request to the underlying platform to: - 1. Create [=platform operator=] |opImpl| for the given |name| operation. - 1. Set |activation|.{{MLActivation/[[operator]]}} to |opImpl|. - 1. If |init-steps| are given, run |init-steps| with |options|. - 1. Otherwise, initialize |activation|.{{MLActivation/[[operator]]}} given |options| in an [=implementation-defined=] way for the given |name| operation. + 1. Let |operator| be an [=operator=] for the |name| operation. + 1. Set |activation|.{{MLActivation/[[operator]]}} to |operator|. + 1. If |init-steps| are given, run |init-steps| with |options|. + 1. Otherwise, initialize |activation|.{{MLActivation/[[operator]]}} given |options| in an [=implementation-defined=] way for the given |name| operation. 1. Return |activation|. @@ -1367,13 +1353,10 @@ Create a named {{MLOperand}} based on a descriptor, that can be used as an input 1. If |name| is empty, then [=exception/throw=] a {{TypeError}}. 1. If [=MLOperandDescriptor/checking dimensions=] given |descriptor| returns false, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |operand| be the result of [=creating an MLOperand=] given [=this=] and |descriptor|. 1. Set |operand|.{{MLOperand/[[name]]}} to |name|. - 1. Make a request to the underlying platform to: - 1. Create an [=implementation-defined=] platform input operand |operandImpl| given |descriptor|. - 1. Set |operand|.{{MLOperand/[[operand]]}} to |operandImpl|. - 1. Register |operand| as an input. + 1. Register |operand| as an input. 1. Return |operand|. @@ -1401,13 +1384,10 @@ Create a constant {{MLOperand}} of the specified data type and shape that contai 1. If [=MLOperandDescriptor/checking dimensions=] given |descriptor| returns false, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. If [=validating buffer with descriptor=] given |bufferView| and |descriptor| returns false, then [=exception/throw=] a {{TypeError}}. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |operand| be the result of [=creating an MLOperand=] given [=this=] and |descriptor|. 1. Let |bytes| be the result of [=getting a copy of the bytes held by the buffer source=] given |bufferView|. - 1. Make a request to the underlying platform to: - 1. Create an [=platform operand=] |constantImpl| to represent a constant, given |descriptor|. - 1. Set |operand|.{{MLOperand/[[operand]]}} to |constantImpl|. - 1. Register |operand| as a tensor constant with |bytes| as value. + 1. Register |operand| as a tensor constant with |bytes| as value. 1. Return |operand|. @@ -1437,12 +1417,9 @@ Data truncation will occur when the specified value exceeds the range of the spe 1. Let |descriptor| be a new {{MLOperandDescriptor}}. 1. Set |descriptor|.{{MLOperandDescriptor/dataType}} to |type|. 1. Set |descriptor|.{{MLOperandDescriptor/dimensions}} to an empty [=/list=]. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |operand| be the result of [=creating an MLOperand=] given [=this=] and |descriptor|. - 1. Make a request to the underlying platform to: - 1. Create an [=platform operand=] |constantImpl| to represent a constant, given |descriptor|. - 1. Set |operand|.{{MLOperand/[[operand]]}} to |constantImpl|. - 1. Register |operand| as a scalar constant with |value| as value. + 1. Register |operand| as a scalar constant with |value| as value. 1. Return |operand|. @@ -1473,19 +1450,14 @@ Data truncation will occur when the values in the range exceed the range of the 1. Let |descriptor| be a new {{MLOperandDescriptor}}. 1. Set |descriptor|.{{MLOperandDescriptor/dataType}} to |type|. - 1. Let |size| be *max(0, ceil((end - start)/step))*. + 1. Let |size| be max(0, ceil((|end| - |start|)/|step|)). 1. Set |descriptor|.{{MLOperandDescriptor/dimensions}} to the [=/list=] « |size| ». - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. - 1. Let |operand| be the result of [=creating an MLOperand=] given [=this=], |start|, |end|, |step|, and |type|. - 1. Make a request to the underlying platform to: - 1. Create an [=implementation-defined=] platform memory buffer the size of |size| multiplied by sizeof(|descriptor|.{{MLOperandDescriptor/dataType}}). - 2. Store the beginning address to that memory buffer as a pointer |buffer| of the corresponding data type. + 1. *Make graph connections:* + 1. Let |operand| be the result of [=creating an MLOperand=] given [=this=] and |descriptor|. + 1. Let |buffer| be an [=implementation-defined=] platform memory buffer the size of |size| multiplied by sizeof(|descriptor|.{{MLOperandDescriptor/dataType}}). 1. [=list/For each=] |index| in [=the range=] 0 to |size|, exclusive: 1. Set |buffer|[|index|] to |start| + (|index| * |step|). - 1. Make a request to the underlying platform to: - 1. Create an [=platform operand=] |constantImpl| to represent a constant operand, given |descriptor|. - 1. Set |operand|.{{MLOperand/[[operand]]}} to |constantImpl|. - 1. Register |operand| as a constant with |buffer| as value. + 1. Register |operand| as a constant with |buffer| as value. 1. Return |operand|. @@ -1517,14 +1489,16 @@ Build a composed graph up to a given output operand into a computational graph a 1. Add |operand|.{{MLOperand/[[descriptor]]}} to |graph|.{{MLGraph/[[inputDescriptors]]}}[|operand|.{{MLOperand/[[name]]}}]. 1. If |operand| was created as a constant by the underlying platform: 1. Implementations MAY preprocess and optimize the tensor data of |operand| for the underlying platform. - 1. Register |operand|.{{MLOperand/[[operand]]}} in |graphImpl| as graph output. - 1. Register |operand|.{{MLOperand/[[operator]]}} to |graphImpl|. - + 1. Register a [=platform operand=] representing |operand| in |graphImpl| as graph output. + 1. Register a [=platform operator=] representing |operand|.{{MLOperand/[[operator]]}} to |graphImpl|. + Issue(552): Decide how to specify graph initialization. 1. [=Resolve=] |promise| with |graph|. +Issue(448): More fully specify the behavior of {{MLGraphBuilder/build()}} in terms of traversing the graph of [=operators=] and {{MLOperand}}s, creating the corresponding [=platform operators=] and [=platform operands=], and connecting [=operator/inputs=], [=operator/outputs=], and [=operator/activations=]. + ### argMin/argMax operations ### {#api-mlgraphbuilder-argminmax} Return the index location of the minimum or maxmium values of all the input values along the axes. @@ -1576,15 +1550,12 @@ partial interface MLGraphBuilder { 1. Let |desc| be a new {{MLOperandDescriptor}}. 1. Set |desc|.{{MLOperandDescriptor/dataType}} to {{MLOperandDataType/"int64"}}. 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to |outputShape|. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* + 1. Let |operator| be an [=operator=] for the operation |op|, given |options|. 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the |op| argMin or argMax operation, given |options|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -1677,12 +1648,13 @@ partial interface MLGraphBuilder { 1. If |options|.{{MLBatchNormalizationOptions/bias}} [=map/exists=]: 1. If its [=list/size=] is not 1, then [=exception/throw=] a {{TypeError}}. 1. If |options|.{{MLBatchNormalizationOptions/bias}}'s [=MLOperand/shape=][0] is not equal to |input|'s [=MLOperand/shape=][|options|.{{MLBatchNormalizationOptions/axis}}], then [=exception/throw=] a {{TypeError}}. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* + 1. Let |operator| be an [=operator=] for the batchNormalization operation, given |input|, |mean|, |variance| and |options|. 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |input|.{{MLOperand/[[descriptor]]}}, that may use the same underlying data as |input|. - 1. Make a request to the underlying platform to initialize the batch normalization: - 1. Create [=platform operator=] |batchNormImpl| for this method, given |input|, |mean|, |variance| and |options|. - 1. If |options|.{{MLBatchNormalizationOptions/activation}} [=map/exists=],register it as activation to |batchNormImpl|. - 1. Connect |output| as output to |batchNormImpl|. + 1. If |options|.{{MLBatchNormalizationOptions/activation}} [=map/exists=], then add it to |operator|'s [=operator/activation functions=]. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -1728,16 +1700,12 @@ partial interface MLGraphBuilder { The cast(|input|, |type|) method steps are:
- 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. - 1. Let |operand| be the result of [=creating an MLOperand=] given [=this=], |input| and |type|. + 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|. - 1. Make a request to the underlying platform to: - 1. Create [=platform operator=] |castImpl| for this method, given |type|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |castImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent an output, given |output| and |castImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |operand|.{{MLOperand/[[operand]]}} as input to |castImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |castImpl|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|.
@@ -1811,15 +1779,12 @@ partial interface MLGraphBuilder {
1. If [=checking clamp options=] given |options| returns false, then [=exception/throw=] a {{TypeError}}. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. - 1. Make a request to the underlying platform to: - 1. Create [=platform operator=] |clampImpl| for this method, given |options|.{{MLClampOptions/minValue}} and |options|.{{MLClampOptions/maxValue}}. - 1. Set |output|.{{MLOperand/[[operator]]}} to |clampImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent clamp output, given |output| and |clampImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |clampImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |clampImpl|. + 1. Let |operator| be an [=operator=] for the clamp operation, given |options|.{{MLClampOptions/minValue}} and |options|.{{MLClampOptions/maxValue}}. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|.
@@ -1893,15 +1858,12 @@ partial interface MLGraphBuilder { 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 "{{DataError}}" {{DOMException}}. 1. If |dim| is equal to |axis|, add to |desc|.{{MLOperandDescriptor/dimensions}}[|axis|] the value of |input|'s [=MLOperand/shape=][|dim|]. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|. - 1. Make a request to the underlying platform to: - 1. Create [=platform operator=] |concatImpl| for this method, given |inputs| and |axis|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |concatImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent output,given |output| and |concatImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |inputs| as input to |concatImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |concatImpl|. + 1. Let |operator| be an [=operator=] for the concat operation, given |inputs| and |axis|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -2090,16 +2052,13 @@ partial interface MLGraphBuilder { 1. Let |desc| be a new {{MLOperandDescriptor}}. 1. Set |desc|.{{MLOperandDescriptor/dataType}} to |input|'s [=MLOperand/dataType=]. 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to |outputShape|. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|. - 1. Make a request to the underlying platform to: - 1. Create [=platform operator=] |conv2dImpl| for this method, given |options| and |filter|. - 1. If |options|.{{MLConv2dOptions/activation}} [=map/exists=],register it as activation to |conv2dImpl|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |conv2dImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |conv2dImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |conv2dImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |conv2dImpl|. + 1. Let |operator| be an [=operator=] for the conv2d operation, given |options| and |filter|. + 1. If |options|.{{MLConv2dOptions/activation}} [=map/exists=], then add it to |operator|'s [=operator/activations=]. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -2305,16 +2264,13 @@ partial interface MLGraphBuilder { 1. Let |desc| be a new {{MLOperandDescriptor}}. 1. Set |desc|.{{MLOperandDescriptor/dataType}} to |input|'s [=MLOperand/dataType=]. 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to |outputShape|. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|. - 1. Make a request to the underlying platform to: - 1. Create [=platform operator=] |convTranspose2dImpl| for this method, given |options| and |filter|. - 1. If |options|.{{MLConvTranspose2dOptions/activation}} [=map/exists=],register it as activation to |convTranspose2dImpl|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |convTranspose2dImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |convTranspose2dImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |convTranspose2dImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |convTranspose2dImpl|. + 1. Let |operator| be an [=operator=] for the convTranspose2d operation, given |options| and |filter|. + 1. If |options|.{{MLConvTranspose2dOptions/activation}} [=map/exists=], add it to |operator|'s [=operator/activations=]. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -2369,15 +2325,12 @@ partial interface MLGraphBuilder { 1. Set |descriptor|.{{MLOperandDescriptor/dataType}} to |a|'s [=MLOperand/dataType=]. 1. Set |descriptor|.{{MLOperandDescriptor/dimensions}} to the result of [=bidirectionally broadcasting the shapes=] |a|'s [=MLOperand/shape=] and |b|'s [=MLOperand/shape=]. 1. If that returns failure, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |descriptor|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the binary operation |op|, given |a| and |b|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |a|.{{MLOperand/[[operand]]}} and |b|.{{MLOperand/[[operand]]}} as inputs to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the binary operation |op|, given |a| and |b|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/inputs=] to |a| and |b|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -2490,15 +2443,12 @@ Although operations {{MLGraphBuilder/greaterOrEqual()}} and {{MLGraphBuilder/les 1. Set |descriptor|.{{MLOperandDescriptor/dataType}} to {{MLOperandDataType/"uint8"}}. 1. Set |descriptor|.{{MLOperandDescriptor/dimensions}} to the result of [=bidirectionally broadcasting the shapes=] |a|'s [=MLOperand/shape=] and |b|'s [=MLOperand/shape=]. 1. If that returns failure, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |descriptor|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the binary operation |op|, given |a| and |b|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |a|.{{MLOperand/[[operand]]}} and |b|.{{MLOperand/[[operand]]}} as inputs to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the binary operation |op|, given |a| and |b|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/inputs=] to |a| and |b|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -2604,15 +2554,12 @@ partial interface MLGraphBuilder {
1. [=Assert=]: |op| is one of "abs", "ceil", "cos", "erf", "exp", "floor", "identity", "log", "neg", "reciprocal", "sin", "sqrt", "tan". - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the unary operation |op|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the unary operation |op|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|.
@@ -2765,15 +2712,12 @@ partial interface MLGraphBuilder { The elu(|input|, |options|) method steps are:
- 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the ELU operation, given |options|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the ELU operation, given |options|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|.
@@ -2826,15 +2770,12 @@ partial interface MLGraphBuilder { 1. Set |descriptor|.{{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|. 1. If that returns failure, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |outputDescriptor|. - 1. Make a request to the underlying platform to: - 1. Create [=platform operator=] |expandImpl| for this method, given |input| and |newShape|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |expandImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent output,given |output| and |expandImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input| as input to |expandImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |expandImpl|. + 1. Let |operator| be an [=operator=] for the expand operation, given |input| and |newShape|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -2901,15 +2842,12 @@ partial interface MLGraphBuilder { 1. Let |desc| be a new {{MLOperandDescriptor}}. 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to |shapeOutput|. 1. Set |desc|.{{MLOperandDescriptor/dataType}} to |input|'s [=MLOperand/dataType=]. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=creating an MLOperand=] given |desc|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the Gather operation, given |input|, |indices|, and |options|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} and |indices|.{{MLOperand/[[operand]]}} as inputs to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the Gather operation, given |input|, |indices|, and |options|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/inputs=] to |input| and |indices|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -3039,15 +2977,12 @@ partial interface MLGraphBuilder { 1. Let |desc| be a new {{MLOperandDescriptor}}. 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to the [=/list=] « |shapeA|[0], |shapeB|[1] ». 1. Set |desc|.{{MLOperandDescriptor/dataType}} to |a|'s [=MLOperand/dataType=]. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the GEMM operation, given |options|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |a|.{{MLOperand/[[operand]]}} and |b|.{{MLOperand/[[operand]]}} as inputs to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the GEMM operation, given |options|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/inputs=] to |a| and |b|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -3165,12 +3100,14 @@ partial interface MLGraphBuilder { 1. If its [=MLOperand/rank=] is not 3, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. If |options|.{{MLGruOptions/activations}} [=map/exists=] and its [=list/size=] is not 2, then [=exception/throw=] a {{TypeError}}. 1. If |steps| is not equal to |input|'s [=MLOperand/shape=][0], then [=exception/throw=] a {{TypeError}}. - 1. Let |output| be an empty sequence of {{MLOperand}} objects. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for "gru", given |weight|, |recurrentWeight|, |steps|, |hiddenSize| and |options| as parameters. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output| as output to |opImpl|. + 1. *Make graph connections:* + 1. Let |operator| be an [=operator=] for "gru", given |weight|, |recurrentWeight|, |steps|, |hiddenSize| and |options| as parameters. + 1. Let |output| be an empty sequence of {{MLOperand}} objects. + + Issue: Populate |output| + + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -3315,15 +3252,12 @@ partial interface MLGraphBuilder { 1. Let |desc| be a new {{MLOperandDescriptor}}. 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to the [=/list=] « |input|'s [=MLOperand/shape=][0], |hiddenSize| ». 1. Set |desc|.{{MLOperandDescriptor/dataType}} to |input|'s [=MLOperand/dataType=]. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for "gruCell", given |weight|, |recurrentWeight|, |hiddenState|, |hiddenSize| and |options| as parameters. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for "gruCell", given |weight|, |recurrentWeight|, |hiddenState|, |hiddenSize| and |options| as parameters. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -3489,15 +3423,12 @@ partial interface MLGraphBuilder { The hardSigmoid(|input|, |options|) method steps are:
- 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the hard sigmoid operation, given |options|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the hard sigmoid operation, given |options|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|.
@@ -3569,15 +3500,12 @@ partial interface MLGraphBuilder { The hardSwish(|input|) method steps are:
- 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the hard-swish operation. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the hard-swish operation. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|.
@@ -3656,15 +3584,12 @@ partial interface MLGraphBuilder { 1. If |input|'s [=MLOperand/rank=] is not 4, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. If |options|.{{MLInstanceNormalizationOptions/scale}}'s [=MLOperand/rank=] is not equal to 1, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. If |options|.{{MLInstanceNormalizationOptions/bias}}'s [=MLOperand/rank=] is not equal to 1, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the instance normalization operation, given |options|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the instance normalization operation, given |options|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -3762,15 +3687,12 @@ partial interface MLGraphBuilder { 1. Let |size| be |input|'s [=MLOperand/shape=][|axis|]. 1. If |options|.{{MLLayerNormalizationOptions/scale}}'s [=MLOperand/shape=][|index|] is not equal to |size|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. If |options|.{{MLLayerNormalizationOptions/bias}}'s [=MLOperand/shape=][|index|] is not equal to |size|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the instance normalization operation, given |options|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the instance normalization operation, given |options|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -3862,15 +3784,12 @@ partial interface MLGraphBuilder { The leakyRelu(|input|, |options|) method steps are:
- 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the Leaky RELU operation, given |options|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the Leaky RELU operation, given |options|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|.
@@ -3952,15 +3871,12 @@ partial interface MLGraphBuilder { The linear(|input|, |options|) method steps are:
- 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the linear operation, given |options|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the linear operation, given |options|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|.
@@ -4099,24 +4015,23 @@ partial interface MLGraphBuilder { 1. If |options|.{{MLLstmOptions/initialCellState}}'s [=MLOperand/shape=][2] is not |hiddenSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. If |options|.{{MLLstmOptions/activations}} [=map/exists=]: 1. If its [=list/size=] is not 3, then [=exception/throw=] a {{TypeError}}. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Calculate the output shape:* 1. Let |desc| be a new {{MLOperandDescriptor}}. 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to the [=/list=] « |numDirections|, |batchSize|, |hiddenSize| ». 1. Set |desc|.{{MLOperandDescriptor/dataType}} to |input|'s [=MLOperand/dataType=]. + 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to the [=/list=] « |steps|, |numDirections|, |batchSize|, |hiddenSize| ». + 1. *Make graph connections:* + 1. Let |operator| be an [=operator=] for the LSTM operation, given |weight|, |recurrentWeight|, |steps|, |hiddenSize| and |options|. 1. Let |output0| be the result of [=creating an MLOperand=] given [=this=] and |desc|. 1. Let |output1| be the result of [=creating an MLOperand=] given [=this=] and |desc|. - 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to the [=/list=] « |steps|, |numDirections|, |batchSize|, |hiddenSize| ». 1. If |options|.{{MLLstmOptions/returnSequence}} is set to true: 1. Let |output2| be the result of [=creating an MLOperand=] given [=this=] and |desc|. 1. Let |output| be the [=/list=] « |output0|, |output1|, |output2| ». - 1. Otherwise, let |output| be the [=/list=] « |output0|, |output1| ». - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the LSTM operation, given |weight|, |recurrentWeight|, |steps|, |hiddenSize| and |options|. - 1. Set |output0|.{{MLOperand/[[operator]]}}, |output1|.{{MLOperand/[[operator]]}} and |output2|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output0|.{{MLOperand/[[operand]]}}, |output1|.{{MLOperand/[[operand]]}} and |output2|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output| as output to |opImpl|. + 1. Otherwise: + 1. Let |output| be the [=/list=] « |output0|, |output1| ». + 1. Set |output0|.{{MLOperand/[[operator]]}}, |output1|.{{MLOperand/[[operator]]}} and |output2|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -4283,17 +4198,14 @@ partial interface MLGraphBuilder { 1. Let |desc| be a new {{MLOperandDescriptor}}. 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to the [=/list=] « |batchSize|, |hiddenSize| ». 1. Set |desc|.{{MLOperandDescriptor/dataType}} to |input|'s [=MLOperand/dataType=]. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output0| be the result of [=creating an MLOperand=] given [=this=] and |desc|. 1. Let |output1| be the result of [=creating an MLOperand=] given [=this=] and |desc|. 1. Let |output| be the [=/list=] « |output0|, |output1| ». - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the LSTM cell operation, given |weight|, |recurrentWeight|, |hiddenState|, |cellState|, |hiddenSize| and |options|. - 1. Set |output0|.{{MLOperand/[[operator]]}} and |output1|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output0|.{{MLOperand/[[operand]]}} and |output1|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output| as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the LSTM cell operation, given |weight|, |recurrentWeight|, |hiddenState|, |cellState|, |hiddenSize| and |options|. + 1. Set |output0|.{{MLOperand/[[operator]]}} and |output1|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -4471,15 +4383,12 @@ partial interface MLGraphBuilder { 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. 1. Set |desc|.{{MLOperandDescriptor/dataType}} to |a|'s [=MLOperand/dataType=]. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the matrix multiplication operation. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |a|.{{MLOperand/[[operand]]}} and |b|.{{MLOperand/[[operand]]}} as inputs to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the matrix multiplication operation. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/inputs=] to |a| and |b|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -4552,15 +4461,12 @@ partial interface MLGraphBuilder { 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|. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the padding operation, given |beginningPadding|, |endingPadding| and |options|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the padding operation, given |beginningPadding|, |endingPadding| and |options|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -4775,16 +4681,13 @@ partial interface MLGraphBuilder { 1. If |options|.{{MLPool2dOptions/dilations}}'s [=list/size=] is not 2, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. If any value in |options|.{{MLPool2dOptions/dilations}} is not greater than 0, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. Let |desc| be a copy of |input|.{{MLOperand/[[descriptor]]}}. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. - 1. Make a request to the underlying platform to: - 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=]). - 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|. - 1. Let |opImpl| be [=platform operator=] for the |op| pooling operation, given |options|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. *Make graph connections:* + 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=]). + 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|. + 1. Let |operator| be an [=operator=] for the|op| pooling operation, given |options|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -4853,15 +4756,12 @@ partial interface MLGraphBuilder { 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=]. 1. If that returns failure, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |descriptor|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the PreLU operation, given |slope|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the PreLU operation, given |slope|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -4966,15 +4866,12 @@ partial interface MLGraphBuilder { 1. Let |desc| be a new {{MLOperandDescriptor}}. 1. Set |desc|.{{MLOperandDescriptor/dataType}} to |input|'s [=MLOperand/dataType=]. 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to |outputShape|. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the |op| reduce operation, given |options|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the|op| reduce operation, given |options|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -5095,15 +4992,12 @@ partial interface MLGraphBuilder { The relu(|input|) method steps are:
- 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the ReLU operation. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the ReLU operation. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|.
@@ -5217,15 +5111,12 @@ partial interface MLGraphBuilder { 1. If |input|'s [=MLOperand/rank=] is not 4, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. If [=MLGraphBuilder/checking resample options=] given |options| returns false, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. Let |desc| be the result of [=MLGraphBuilder/calculating resample output sizes=] given |input| and |options|. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the resample 2D operation, given |options|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the resample 2D operation, given |options|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -5261,15 +5152,12 @@ partial interface MLGraphBuilder { 1. If product of all values in |newShape| is not equal to |inputElementCount|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. Let |desc| be a copy of |input|.{{MLOperand/[[descriptor]]}}. 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to |newShape|. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the reshape operation. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the reshape operation. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -5353,15 +5241,12 @@ partial interface MLGraphBuilder { The sigmoid(|input|) method steps are:
- 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the sigmoid operation. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the sigmoid operation. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|.
@@ -5410,15 +5295,12 @@ partial interface MLGraphBuilder {
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. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the slice operation, given |starts| and |sizes|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the slice operation, given |starts| and |sizes|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|.
@@ -5469,15 +5351,12 @@ partial interface MLGraphBuilder {
1. If |input|'s [=MLOperand/rank=] is not 2, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the softmax operation. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the softmax operation. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|.
@@ -5557,15 +5436,12 @@ partial interface MLGraphBuilder { The softplus(|input|, |options|) method steps are:
- 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the softplus operation, given |options|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the softplus operation, given |options|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|.
@@ -5629,15 +5505,12 @@ partial interface MLGraphBuilder { The softsign(|input|) method steps are:
- 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the softsign operation. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the softsign operation. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|.
@@ -5699,15 +5572,12 @@ partial interface MLGraphBuilder {
1. If |splits| is an {{unsigned long}}, and |input|'s [=MLOperand/shape=][|options|.{{MLSplitOptions/axis}}] % |splits| is not 0, then [=exception/throw=] a {{TypeError}}. 1. If |splits| is a sequence of {{unsigned long}}, and the sum of its elements is not equal to |input|'s [=MLOperand/shape=][|options|.{{MLSplitOptions/axis}}], then [=exception/throw=] a {{TypeError}}. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the split operation, given |splits| and |options|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the split operation, given |splits| and |options|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|.
@@ -5777,15 +5647,12 @@ partial interface MLGraphBuilder { The tanh(|input|) method steps are:
- 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the hyperbolic tangent operation. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the hyperbolic tangent operation. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|.
@@ -5849,15 +5716,12 @@ partial interface MLGraphBuilder { 1. If |options|.{{MLTransposeOptions/permutation}}'s [=MLOperand/rank=] is not the same as |input|'s [=MLOperand/rank=], then [=exception/throw=] a {{TypeError}}. 1. If the values in |options|.{{MLTransposeOptions/permutation}} are not in [=the range=] 0 and |input|'s [=MLOperand/rank=] exclusive, then [=exception/throw=] a {{TypeError}}. 1. If the values in |options|.{{MLTransposeOptions/permutation}} contain duplicate value, then [=exception/throw=] a {{TypeError}}. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the transpose operation, given |options|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the transpose operation, given |options|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -5900,15 +5764,12 @@ partial interface MLGraphBuilder {
1. If |input|'s [=MLOperand/rank=] is less than 2, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the triangular operation, given |options|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the triangular operation, given |options|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|.
@@ -6007,15 +5868,12 @@ partial interface MLGraphBuilder { 1. Set |descriptor|.{{MLOperandDescriptor/dimensions}} to the result of [=bidirectionally broadcasting the shapes=] |input|'s [=MLOperand/shape=] and |other|'s [=MLOperand/shape=]. 1. If that returns failure, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. If |condition| is not [=bidirectionally broadcastable=] to |descriptor|.{{MLOperandDescriptor/dimensions}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. *Make graph connections:* 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |descriptor|. - 1. Make a request to the underlying platform to: - 1. Let |opImpl| be [=platform operator=] for the where operation, given |condition|, |input| and |other|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |opImpl|. - 1. Create an [=platform operand=] |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Set |output|.{{MLOperand/[[operand]]}} to |outputImpl|. - 1. Connect |condition|.{{MLOperand/[[operand]]}}, |input| and |other|.{{MLOperand/[[operand]]}} as inputs to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Let |operator| be an [=operator=] for the where operation, given |condition|, |input| and |other|. + 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Set |operator|'s [=operator/inputs=] to |condition|, |input| and |other|. + 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. From dfee70d63a05866cbe6758c20fd8c0952ef17142 Mon Sep 17 00:00:00 2001 From: Joshua Bell Date: Wed, 28 Feb 2024 15:26:21 -0800 Subject: [PATCH 2/7] Trivial fixes - missing spaces, wrong operation name --- index.bs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/index.bs b/index.bs index 2bbfded8..fe3fd082 100644 --- a/index.bs +++ b/index.bs @@ -3689,7 +3689,7 @@ partial interface MLGraphBuilder { 1. If |options|.{{MLLayerNormalizationOptions/bias}}'s [=MLOperand/shape=][|index|] is not equal to |size|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. *Make graph connections:* 1. Let |output| be the result of [=copying an MLOperand=] given |input|. - 1. Let |operator| be an [=operator=] for the instance normalization operation, given |options|. + 1. Let |operator| be an [=operator=] for the layer normalization operation, given |options|. 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. 1. Set |operator|'s [=operator/input=] to |input|. 1. Set |operator|'s [=operator/output=] to |output|. @@ -4684,7 +4684,7 @@ partial interface MLGraphBuilder { 1. *Make graph connections:* 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=]). 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|. - 1. Let |operator| be an [=operator=] for the|op| pooling operation, given |options|. + 1. Let |operator| be an [=operator=] for the |op| pooling operation, given |options|. 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. 1. Set |operator|'s [=operator/input=] to |input|. 1. Set |operator|'s [=operator/output=] to |output|. @@ -4868,7 +4868,7 @@ partial interface MLGraphBuilder { 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to |outputShape|. 1. *Make graph connections:* 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|. - 1. Let |operator| be an [=operator=] for the|op| reduce operation, given |options|. + 1. Let |operator| be an [=operator=] for the |op| reduce operation, given |options|. 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. 1. Set |operator|'s [=operator/input=] to |input|. 1. Set |operator|'s [=operator/output=] to |output|. From d47d87c2cd698766c8c2ef1eb7dd455270efb072 Mon Sep 17 00:00:00 2001 From: Joshua Bell Date: Mon, 4 Mar 2024 09:53:47 -0800 Subject: [PATCH 3/7] lstm(): Fix output2 shape calculation In tip-of-tree, the "desc" MLOperandDescriptor is populated, used, then modified and conditionally used again (if `returnSequence` is true) when creating "output2". This was broken in previous commits in this branch. Restore the intent, using a separate "desc2" MLOperandDescriptor only conditionally populated and then conditionally used. --- index.bs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/index.bs b/index.bs index 4c5ca74d..aa3ab4ba 100644 --- a/index.bs +++ b/index.bs @@ -4028,13 +4028,16 @@ partial interface MLGraphBuilder { 1. Let |desc| be a new {{MLOperandDescriptor}}. 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to the [=/list=] « |numDirections|, |batchSize|, |hiddenSize| ». 1. Set |desc|.{{MLOperandDescriptor/dataType}} to |input|'s [=MLOperand/dataType=]. - 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to the [=/list=] « |steps|, |numDirections|, |batchSize|, |hiddenSize| ». + 1. If |options|.{{MLLstmOptions/returnSequence}} is true: + 1. Let |desc2| be a new {{MLOperandDescriptor}}. + 1. Set |desc2|.{{MLOperandDescriptor/dataType}} to |input|'s [=MLOperand/dataType=]. + 1. Set |desc2|.{{MLOperandDescriptor/dimensions}} to the [=/list=] « |steps|, |numDirections|, |batchSize|, |hiddenSize| ». 1. *Make graph connections:* 1. Let |operator| be an [=operator=] for the LSTM operation, given |weight|, |recurrentWeight|, |steps|, |hiddenSize| and |options|. 1. Let |output0| be the result of [=creating an MLOperand=] given [=this=] and |desc|. 1. Let |output1| be the result of [=creating an MLOperand=] given [=this=] and |desc|. - 1. If |options|.{{MLLstmOptions/returnSequence}} is set to true: - 1. Let |output2| be the result of [=creating an MLOperand=] given [=this=] and |desc|. + 1. If |options|.{{MLLstmOptions/returnSequence}} is true: + 1. Let |output2| be the result of [=creating an MLOperand=] given [=this=] and |desc2|. 1. Let |output| be the [=/list=] « |output0|, |output1|, |output2| ». 1. Otherwise: 1. Let |output| be the [=/list=] « |output0|, |output1| ». From aecbe7019f00853cdfd5a1b6467476d3bcb429ed Mon Sep 17 00:00:00 2001 From: Joshua Bell Date: Sun, 10 Mar 2024 11:46:35 -0700 Subject: [PATCH 4/7] Update index.bs Co-authored-by: Ningxin Hu --- index.bs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/index.bs b/index.bs index 7186038f..83944129 100644 --- a/index.bs +++ b/index.bs @@ -696,7 +696,7 @@ graphs of neural networks. The {{MLGraph}} interface represents a compiled computational graph that is immutable (that is, a model). -The {{MLGraphBuilder}} interface serves as a builder (factory) to construct the computation graph that is then compiled to create an MLGraph. +The {{MLGraphBuilder}} interface serves as a builder (factory) to construct the computational graph that is then compiled to create an {{MLGraph}}. In WebNN, the computational graph is composed of operators which act on data, and are the nodes of the graph. An [=operator=]'s input is one or more {{MLOperand}}s representing the data flow for the computation, and are the edges of the graph. Operands include input values, constants (including trained weights), and intermediate values (often referred to as activations). An [=operator=]'s output is one or more {{MLOperand}}s, representing the output values of the computation. [=Operators=] have operator-specific parameters that control their behavior, which can include zero or more activation functions, which are {{MLActivation}}s. The operations have functional semantics, with no side effects. Each operation invocation conceptually returns a distinct new value, without changing the value of any other {{MLOperand}}. From 2246810db4b46ec70c457813ea17cca6d3e34fc0 Mon Sep 17 00:00:00 2001 From: Joshua Bell Date: Mon, 11 Mar 2024 10:40:45 -0700 Subject: [PATCH 5/7] Initial review feedback: * Add other operand inputs * PreLU -> PReLU * Define split() output shapes calculations --- index.bs | 59 ++++++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 15 deletions(-) diff --git a/index.bs b/index.bs index 9a64cb05..67b1831e 100644 --- a/index.bs +++ b/index.bs @@ -1675,6 +1675,8 @@ partial interface MLGraphBuilder { 1. If |options|.{{MLBatchNormalizationOptions/activation}} [=map/exists=], then add it to |operator|'s [=operator/activation functions=]. 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. 1. Set |operator|'s [=operator/input=] to |input|. + 1. If |options|.{{MLBatchNormalizationOptions/scale}} [=map/exists=], then add it to |operator|'s [=operator/inputs=]. + 1. If |options|.{{MLBatchNormalizationOptions/bias}} [=map/exists=], then add it to |operator|'s [=operator/inputs=]. 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -1883,7 +1885,7 @@ partial interface MLGraphBuilder { 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|. 1. Let |operator| be an [=operator=] for the concat operation, given |inputs| and |axis|. 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. - 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/input=] to |inputs|. 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -2078,7 +2080,7 @@ partial interface MLGraphBuilder { 1. Let |operator| be an [=operator=] for the conv2d operation, given |options| and |filter|. 1. If |options|.{{MLConv2dOptions/activation}} [=map/exists=], then add it to |operator|'s [=operator/activations=]. 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. - 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/inputs=] to |input| and |filter|. 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -2288,9 +2290,9 @@ partial interface MLGraphBuilder { 1. *Make graph connections:* 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |desc|. 1. Let |operator| be an [=operator=] for the convTranspose2d operation, given |options| and |filter|. - 1. If |options|.{{MLConvTranspose2dOptions/activation}} [=map/exists=], add it to |operator|'s [=operator/activations=]. + 1. If |options|.{{MLConvTranspose2dOptions/activation}} [=map/exists=], then add it to |operator|'s [=operator/activations=]. 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. - 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/inputs=] to |input| and |filter|. 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -3003,6 +3005,7 @@ partial interface MLGraphBuilder { 1. Let |operator| be an [=operator=] for the GEMM operation, given |options|. 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. 1. Set |operator|'s [=operator/inputs=] to |a| and |b|. + 1. If |options|.{{MLGemmOptions/c}} [=map/exists=], then add it to |operator|'s [=operator/inputs=]. 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -3130,7 +3133,10 @@ partial interface MLGraphBuilder { Issue: Populate |output| - 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/inputs=] to |input|, |weight|, and |recurrentWeight|. + 1. If |options|.{{MLGruOptions/bias=] [=map/exists=], then add it to |operator|'s [=operator/inputs=]. + 1. If |options|.{{MLGruOptions/recurrentBias=] [=map/exists=], then add it to |operator|'s [=operator/inputs=]. + 1. If |options|.{{MLGruOptions/initialHiddenState=] [=map/exists=], then add it to |operator|'s [=operator/inputs=]. 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -3616,6 +3622,8 @@ partial interface MLGraphBuilder { 1. Let |operator| be an [=operator=] for the instance normalization operation, given |options|. 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. 1. Set |operator|'s [=operator/input=] to |input|. + 1. If |options|.{{MLInstanceNormalizationOptions/scale}} [=map/exists=], then add it to |operator|'s [=operator/inputs=]. + 1. If |options|.{{MLInstanceNormalizationOptions/bias}} [=map/exists=], then add it to |operator|'s [=operator/inputs=]. 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -3719,6 +3727,8 @@ partial interface MLGraphBuilder { 1. Let |operator| be an [=operator=] for the layer normalization operation, given |options|. 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. 1. Set |operator|'s [=operator/input=] to |input|. + 1. If |options|.{{MLLayerNormalizationOptions/scale}} [=map/exists=], then add it to |operator|'s [=operator/inputs=]. + 1. If |options|.{{MLLayerNormalizationOptions/bias}} [=map/exists=], then add it to |operator|'s [=operator/inputs=]. 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -4063,7 +4073,12 @@ partial interface MLGraphBuilder { 1. Otherwise: 1. Let |output| be the [=/list=] « |output0|, |output1| ». 1. Set |output0|.{{MLOperand/[[operator]]}}, |output1|.{{MLOperand/[[operator]]}} and |output2|.{{MLOperand/[[operator]]}} to |operator|. - 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/inputs=] to |input|, |weight|, and |recurrentWeight|. + 1. If |options|.{{MLLstmOptions/bias}} [=map/exists=], then add it to |operator|'s [=operator/inputs=]. + 1. If |options|.{{MLLstmOptions/recurrentBias}} [=map/exists=], then add it to |operator|'s [=operator/inputs=]. + 1. If |options|.{{MLLstmOptions/peepholeWeight}} [=map/exists=], then add it to |operator|'s [=operator/inputs=]. + 1. If |options|.{{MLLstmOptions/initialHiddenState}} [=map/exists=], then add it to |operator|'s [=operator/inputs=]. + 1. If |options|.{{MLLstmOptions/initialCellState}} [=map/exists=], then add it to |operator|'s [=operator/inputs=]. 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -4241,7 +4256,10 @@ partial interface MLGraphBuilder { 1. Let |output| be the [=/list=] « |output0|, |output1| ». 1. Let |operator| be an [=operator=] for the LSTM cell operation, given |weight|, |recurrentWeight|, |hiddenState|, |cellState|, |hiddenSize| and |options|. 1. Set |output0|.{{MLOperand/[[operator]]}} and |output1|.{{MLOperand/[[operator]]}} to |operator|. - 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/inputs=] to |input|, |weight|, |recurrentWeight|, |hiddenState|, and |cellState|. + 1. If |options|.{{MLLstmCellOptions/bias}} [=map/exists=], then add it to |operator|'s [=operator/inputs=]. + 1. If |options|.{{MLLstmCellOptions/recurrentBias}} [=map/exists=], then add it to |operator|'s [=operator/inputs=]. + 1. If |options|.{{MLLstmCellOptions/peepholeWeight}} [=map/exists=], then add it to |operator|'s [=operator/inputs=]. 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -4795,9 +4813,9 @@ partial interface MLGraphBuilder { 1. If that returns failure, then [=exception/throw=] a {{TypeError}}. 1. *Make graph connections:* 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |descriptor|. - 1. Let |operator| be an [=operator=] for the PreLU operation, given |slope|. + 1. Let |operator| be an [=operator=] for the PReLU operation, given |slope|. 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. - 1. Set |operator|'s [=operator/input=] to |input|. + 1. Set |operator|'s [=operator/inputs=] to |input| and |slope|. 1. Set |operator|'s [=operator/output=] to |output|. 1. Return |output|. @@ -5609,15 +5627,26 @@ partial interface MLGraphBuilder { The split(|input|, |splits|, |options|) method steps are:
- 1. If |splits| is an {{unsigned long}}, and |input|'s [=MLOperand/shape=][|options|.{{MLSplitOptions/axis}}] % |splits| is not 0, then [=exception/throw=] a {{TypeError}}. - 1. If |splits| is a sequence of {{unsigned long}}, and the sum of its elements is not equal to |input|'s [=MLOperand/shape=][|options|.{{MLSplitOptions/axis}}], 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}}. + 1. Otherwise, let |splitCount| be |splits|. + 1. If |splits| is a sequence of {{unsigned long}}: + 1. If the sum of its elements is not equal to |input|'s [=MLOperand/shape=][|axis|], then [=exception/throw=] a {{TypeError}}. + 1. Otherwise, let |splitCount| be the [=list/size=] of |splits|. 1. *Make graph connections:* - 1. Let |output| be the result of [=copying an MLOperand=] given |input|. 1. Let |operator| be an [=operator=] for the split operation, given |splits| and |options|. - 1. Set |output|.{{MLOperand/[[operator]]}} to |operator|. + 1. Let |outputs| be a new [=/list=]. + 1. [=list/For each=] |index| in [=the range=] 0 to |splitCount|, exclusive: + 1. Let |operand| be the result of [=copying an MLOperand=] given |input|. + 1. If |splits| is an {{unsigned long}}, then let |newDimension| be |operand|'s [=MLOperand/shape=][|axis|] / |splits|. + 1. Otherwise, let |newDimension| be |splits|[|index|]. + 1. Set |operand|'s [=MLOperand/shape=][|axis|] to |newDimension|. + 1. Set |operand|.{{MLOperand/[[operator]]}} to |operator|. + 1. [=list/Append=] |operand| to |outputs|. 1. Set |operator|'s [=operator/input=] to |input|. - 1. Set |operator|'s [=operator/output=] to |output|. - 1. Return |output|. + 1. Set |operator|'s [=operator/outputs=] to |outputs|. + 1. Return |outputs|.
From a3cd48f6c704a73941d73d7151edb425aea0a9bb Mon Sep 17 00:00:00 2001 From: Joshua Bell Date: Mon, 11 Mar 2024 11:28:23 -0700 Subject: [PATCH 6/7] Introduce definition for computational graph with inputs and constants --- index.bs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/index.bs b/index.bs index 67b1831e..8e2aeb32 100644 --- a/index.bs +++ b/index.bs @@ -688,7 +688,7 @@ The Working Group has started documenting ethical issues associated with using M # Programming Model # {#programming-model} ## Overview ## {#programming-model-overview} -At the heart of neural networks is a computational graph of mathematical operations. +At the heart of neural networks is a computational graph of mathematical operations. These operations are the building blocks of modern machine learning technologies in computer vision, natural language processing, and robotics. The WebNN API is a specification for constructing, compiling, and executing computational @@ -696,9 +696,9 @@ graphs of neural networks. The {{MLGraph}} interface represents a compiled computational graph that is immutable (that is, a model). -The {{MLGraphBuilder}} interface serves as a builder (factory) to construct the computational graph that is then compiled to create an {{MLGraph}}. +The {{MLGraphBuilder}} interface serves as a builder (factory) to construct a [=computational graph=] (its graph) that is then compiled to create an {{MLGraph}}. -In WebNN, the computational graph is composed of operators which act on data, and are the nodes of the graph. An [=operator=]'s input is one or more {{MLOperand}}s representing the data flow for the computation, and are the edges of the graph. Operands include input values, constants (including trained weights), and intermediate values (often referred to as activations). An [=operator=]'s output is one or more {{MLOperand}}s, representing the output values of the computation. [=Operators=] have operator-specific parameters that control their behavior, which can include zero or more activation functions, which are {{MLActivation}}s. The operations have functional semantics, with no side effects. Each operation invocation conceptually returns a distinct new value, without changing the value of any other {{MLOperand}}. +In WebNN, the [=computational graph=] is composed of operators which act on data, and are the nodes of the graph. An [=operator=]'s input is one or more {{MLOperand}}s representing the data flow for the computation, and are the edges of the graph. Operands include a [=computational graph=]'s input values, constants (including trained weights), and intermediate values (often referred to as activations). An [=operator=]'s output is one or more {{MLOperand}}s, representing the output values of the computation. [=Operators=] have operator-specific parameters that control their behavior, which can include zero or more activation functions, which are {{MLActivation}}s. The operations have functional semantics, with no side effects. Each operation invocation conceptually returns a distinct new value, without changing the value of any other {{MLOperand}}. A key part of the {{MLGraphBuilder}} interface are methods such as {{MLGraphBuilder/gemm()}} and {{MLGraphBuilder/softmax()}} which create an operator which represents actual operation to perform on the input data when the computation is run, and return a new {{MLOperand}} or {{MLActivation}} holding the operator. Methods that create an {{MLOperand}} connect any [=operator/inputs=] and [=operator/activations=] to the operator. @@ -1374,7 +1374,7 @@ Create a named {{MLOperand}} based on a descriptor, that can be used as an input 1. *Make graph connections:* 1. Let |operand| be the result of [=creating an MLOperand=] given [=this=] and |descriptor|. 1. Set |operand|.{{MLOperand/[[name]]}} to |name|. - 1. Register |operand| as an input. + 1. Add |operand| to [=this=]'s [=MLGraphBuilder/graph=]'s [=computational graph/inputs=]. 1. Return |operand|. @@ -1405,7 +1405,7 @@ Create a constant {{MLOperand}} of the specified data type and shape that contai 1. *Make graph connections:* 1. Let |operand| be the result of [=creating an MLOperand=] given [=this=] and |descriptor|. 1. Let |bytes| be the result of [=getting a copy of the bytes held by the buffer source=] given |bufferView|. - 1. Register |operand| as a tensor constant with |bytes| as value. + 1. Add |operand| to [=this=]'s [=MLGraphBuilder/graph=]'s [=computational graph/constants=] with |bytes| as value. 1. Return |operand|. @@ -1437,7 +1437,7 @@ Data truncation will occur when the specified value exceeds the range of the spe 1. Set |descriptor|.{{MLOperandDescriptor/dimensions}} to an empty [=/list=]. 1. *Make graph connections:* 1. Let |operand| be the result of [=creating an MLOperand=] given [=this=] and |descriptor|. - 1. Register |operand| as a scalar constant with |value| as value. + 1. Add |operand| to [=this=]'s [=MLGraphBuilder/graph=]'s [=computational graph/constants=] with |value| as value. 1. Return |operand|. @@ -1475,7 +1475,7 @@ Data truncation will occur when the values in the range exceed the range of the 1. Let |buffer| be an [=implementation-defined=] platform memory buffer the size of |size| multiplied by sizeof(|descriptor|.{{MLOperandDescriptor/dataType}}). 1. [=list/For each=] |index| in [=the range=] 0 to |size|, exclusive: 1. Set |buffer|[|index|] to |start| + (|index| * |step|). - 1. Register |operand| as a constant with |buffer| as value. + 1. Add |operand| to [=this=]'s [=MLGraphBuilder/graph=]'s [=computational graph/constants=] with |buffer| as value. 1. Return |operand|. From e818c3b0cd9d4c07a4c1caac3e7515e1bfd2fcf8 Mon Sep 17 00:00:00 2001 From: Joshua Bell Date: Mon, 11 Mar 2024 12:25:22 -0700 Subject: [PATCH 7/7] Revise Programming Model section --- index.bs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/index.bs b/index.bs index 8e2aeb32..d096cb64 100644 --- a/index.bs +++ b/index.bs @@ -698,16 +698,13 @@ The {{MLGraph}} interface represents a compiled computational graph that is immu The {{MLGraphBuilder}} interface serves as a builder (factory) to construct a [=computational graph=] (its graph) that is then compiled to create an {{MLGraph}}. -In WebNN, the [=computational graph=] is composed of operators which act on data, and are the nodes of the graph. An [=operator=]'s input is one or more {{MLOperand}}s representing the data flow for the computation, and are the edges of the graph. Operands include a [=computational graph=]'s input values, constants (including trained weights), and intermediate values (often referred to as activations). An [=operator=]'s output is one or more {{MLOperand}}s, representing the output values of the computation. [=Operators=] have operator-specific parameters that control their behavior, which can include zero or more activation functions, which are {{MLActivation}}s. The operations have functional semantics, with no side effects. Each operation invocation conceptually returns a distinct new value, without changing the value of any other {{MLOperand}}. +In WebNN, a [=computational graph=] is composed of operators which act on data, and are the nodes of the graph. {{MLOperand}}s are a representation of data that flows within the computational graph, and are the edges of the graph. {MLOperand}}s include a [=computational graph=]'s input values for inference, constants (including trained weights) used for inference, intermediate values (often referred to as activations) computed during inference, as well as the output values of inference. An [=operator=]'s input is one or more {{MLOperand}}s. An [=operator=]'s output is one or more {{MLOperand}}s. [=Operators=] have operator-specific parameters that control their behavior, which can include zero or more activation functions, which are {{MLActivation}}s. -A key part of the {{MLGraphBuilder}} interface are methods such as {{MLGraphBuilder/gemm()}} and {{MLGraphBuilder/softmax()}} which create an operator which represents actual operation to perform on the input data when the computation is run, and return a new {{MLOperand}} or {{MLActivation}} holding the operator. Methods that create an {{MLOperand}} connect any [=operator/inputs=] and [=operator/activations=] to the operator. +A key part of the {{MLGraphBuilder}} interface are methods such as {{MLGraphBuilder/gemm()}} and {{MLGraphBuilder/softmax()}} which create an [=operator=] which represents the actual operation to perform on the input data when the computation is run, and return a new {{MLOperand}} or {{MLActivation}} holding the operator. Methods that create an {{MLOperand}} connect any [=operator/inputs=] and [=operator/activations=] to the operator. Each method invocation returns a distinct new value, without changing the value of any other {{MLOperand}}. -The runtime values (of {{MLOperand}}s) are tensors, which are essentially multidimensional -arrays. The representation of the tensors is implementation dependent, but it typically -includes the array data stored in some buffer (memory) and some metadata describing the -array data (such as its shape). +At inference time, every {{MLOperand}} will be bound to a tensor (the actual data), which are essentially multidimensional arrays. The representation of the tensors is implementation dependent, but it typically includes the array data stored in some buffer (memory) and some metadata describing the array data (such as its shape). -As mentioned above, the operations have functional semantics. This allows the implementation +Operations within the computational graph have functional semantics. This allows the implementation to potentially share the array data between multiple tensors. For example, the implementation of operations such as reshape, or slice may return a view of its input tensor that shares the same buffer as the input tensor. (In the case of reshape,