From 21f076915f584cf3c9f1715548c48e1463d98b88 Mon Sep 17 00:00:00 2001 From: Zoltan Kis Date: Mon, 30 Jan 2023 20:10:03 +0200 Subject: [PATCH 01/16] Add internal slots to MLOperand and MLActivation Signed-off-by: Zoltan Kis --- index.bs | 80 +++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 68 insertions(+), 12 deletions(-) diff --git a/index.bs b/index.bs index 97bcff75..01e4f433 100644 --- a/index.bs +++ b/index.bs @@ -947,7 +947,48 @@ For instance, an {{MLOperand}} may represent a constant feeding to an operation interface MLOperand {}; -See also [[#security-new-ops]] +{{MLOperand}} has the following internal slots: +
+ : \[[kind]] of type `enum { "input", "constant", "output"}` + :: + The {{MLOperand}}'s kind + : \[[type]] of type {{MLOperandType}} + :: + The {{MLOperand}}'s type + : \[[dimensions]] of type `sequence` + :: + The {{MLOperand}}'s dimensions + : \[[rank]] of type `unsigned long` + :: + The {{MLOperand}}'s rank + : \[[name]] of type [=string=] + :: + The {{MLOperand}}'s name (only for input operands) + : \[[data]] of type {{ArrayBufferView}} + :: + The {{MLOperand}}'s data buffer (only for constant operands) + : \[[activation]] of type {{MLActivation}} + :: + The {{MLOperand}}'s associated activation function object + : \[[builder]] of type {{MLGraphBuilder}} + :: + The {{MLOperand}}'s associated builder object +
+ +
+ The rank of an {{MLOperand}} |operand| is the value returned by the following steps: + 1. If |operand|.{{MLOperand/[[rank]]}} [=map/exists=], return its value. + 1. Let |rank| be 0. + 1. For each |dimension| of |operand|.{{MLOperand/[[dimensions]]}}: + 1. Add 1 to |rank|. + 1. Set |operand|.{{MLOperand/[[rank]]}} to |rank|. + 1. Return rank. +
+ +Since the {{MLOperand/[[builder]]}} object is bound by the {{MLGraphBuilder/constructor()}} constructor to an {{MLContext}} object, an {{MLOperand}} is also always bound to the same {{MLContext}} object. + +The guidelines in [[#security-new-ops]] also apply for operands. + ## The MLActivation interface ## {#api-mlactivation} @@ -958,6 +999,21 @@ Objects implementing the {{MLActivation}} interface represent activation functio interface MLActivation {}; +{{MLActivation}} has the following internal slots: +
+ : \[[name]] of type [=string=] + :: + The {{MLActivation}}'s name + +
+
These activations function types are used to create other operations. One such use of this interface is for when an activation function is fused into another operation such as [[#api-mlgraphbuilder-conv2d]] or [[#api-mlgraphbuilder-batchnorm]] during a graph construction session.
@@ -1478,8 +1534,8 @@ dictionary MLGruOptions { }; partial interface MLGraphBuilder { - sequence gru(MLOperand input, MLOperand weight, MLOperand recurrentWeight, - unsigned long steps, unsigned long hiddenSize, + sequence gru(MLOperand input, MLOperand weight, MLOperand recurrentWeight, + unsigned long steps, unsigned long hiddenSize, optional MLGruOptions options = {}); }; @@ -1577,7 +1633,7 @@ dictionary MLGruCellOptions { partial interface MLGraphBuilder { MLOperand gruCell(MLOperand input, MLOperand weight, MLOperand recurrentWeight, - MLOperand hiddenState, unsigned long hiddenSize, + MLOperand hiddenState, unsigned long hiddenSize, optional MLGruCellOptions options = {}); }; @@ -1598,7 +1654,7 @@ partial interface MLGraphBuilder { **Returns:** an {{MLOperand}}. The 2-D tensor of shape [batch_size, hidden_size], the cell output hidden state of a single time step of the recurrent network.
- The behavior of this operation can be generically emulated via other operations as shown below, when the weight layout is the default *"zrn"* layout, and the activation functions of the update/reset gate and new gate are of the operator types *sigmoid* and *tanh* respectively. + The behavior of this operation can be generically emulated via other operations as shown below, when the weight layout is the default *"zrn"* layout, and the activation functions of the update/reset gate and new gate are of the operator types *sigmoid* and *tanh* respectively.
     const one = builder.constant(1);
     const zero = builder.constant(0);
@@ -1924,8 +1980,8 @@ dictionary MLLstmOptions {
 };
 
 partial interface MLGraphBuilder {
-  sequence lstm(MLOperand input, MLOperand weight, MLOperand recurrentWeight, 
-                           unsigned long steps, unsigned long hiddenSize, 
+  sequence lstm(MLOperand input, MLOperand weight, MLOperand recurrentWeight,
+                           unsigned long steps, unsigned long hiddenSize,
                            optional MLLstmOptions options = {});
 };
 
@@ -2041,7 +2097,7 @@ dictionary MLLstmCellOptions {
 
 partial interface MLGraphBuilder {
   sequence lstmCell(MLOperand input, MLOperand weight, MLOperand recurrentWeight,
-                               MLOperand hiddenState, MLOperand cellState, unsigned long hiddenSize, 
+                               MLOperand hiddenState, MLOperand cellState, unsigned long hiddenSize,
                                optional MLLstmCellOptions options = {});
 };
 
@@ -2063,7 +2119,7 @@ partial interface MLGraphBuilder {
     **Returns:** a sequence of {{MLOperand}}. The first element of the sequence is the output hidden state of the current time step of the recurrent network. The following element is the output cell state. Both elements are 2-D tensors of shape [batch_size, hidden_size].
 
     
- The behavior of this operation can be generically emulated via other operations as shown below, when the weight layout is the default *"iofg"* layout, and the activation functions of the input/forget/output gate and the cell gate/the cell state's filter for the output hidden state are of the operator types *sigmoid* and *tanh* respectively. + The behavior of this operation can be generically emulated via other operations as shown below, when the weight layout is the default *"iofg"* layout, and the activation functions of the input/forget/output gate and the cell gate/the cell state's filter for the output hidden state are of the operator types *sigmoid* and *tanh* respectively.
     const zero = builder.constant(0);
 
@@ -2309,8 +2365,8 @@ partial interface MLGraphBuilder {
             is interpreted according to the value of *options.layout*.
         - *options*: an optional {{MLPool2dOptions}}. The optional parameters of the operation.
             - *windowDimensions*: a sequence of {{unsigned long}} of length 2. The dimensions of the sliding window,
-                [window_height, window_width]. If not present, the window dimensions are assumed to be the height  
-                and width dimensions of the input shape. 
+                [window_height, window_width]. If not present, the window dimensions are assumed to be the height
+                and width dimensions of the input shape.
             - *padding*: a sequence of {{unsigned long}} of length 4. The additional rows and columns added to the beginning and ending of each spatial dimension of *input*, [beginning_height, ending_height, beginning_width, ending_width]. If not present, the values are assumed to be [0,0,0,0].
             - *strides*: a sequence of {{unsigned long}} of length 2. The stride of the
                 sliding window for each spatial dimension of *input*,
@@ -2545,7 +2601,7 @@ partial interface MLGraphBuilder {
     **Arguments:**
         - *x*: an {{MLOperand}}. The input 2-D tensor.
 
-    **Returns:** 
+    **Returns:**
         - an {{MLOperand}}. The output 2-D tensor that contains the softmax results, of the same shape as the input tensor.
         - an {{MLActivation}}. The activation function representing the softmax operation.
 

From 63aee6124180a3668a367ff2f27e94c998f4544f Mon Sep 17 00:00:00 2001
From: Zoltan Kis 
Date: Tue, 7 Feb 2023 21:39:25 +0200
Subject: [PATCH 02/16] Rename the [[data]] internal slot to non-conflicting
 [[tensorData]]

Signed-off-by: Zoltan Kis 
---
 index.bs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/index.bs b/index.bs
index c8000a6d..c5dd8e5e 100644
--- a/index.bs
+++ b/index.bs
@@ -712,7 +712,7 @@ interface MLOperand {};
     : \[[name]] of type [=string=]
     ::
         The {{MLOperand}}'s name (only for input operands)
-    : \[[data]] of type {{ArrayBufferView}}
+    : \[[tensorData]] of type {{ArrayBufferView}}
     ::
         The {{MLOperand}}'s data buffer (only for constant operands)
     : \[[activation]] of type {{MLActivation}}

From 9b888aae8b2c8aa17e09aa68286577214e9f9ae1 Mon Sep 17 00:00:00 2001
From: Zoltan Kis 
Date: Tue, 7 Feb 2023 21:59:18 +0200
Subject: [PATCH 03/16] Remove the [[rank]] internal slot from MLOperand

Signed-off-by: Zoltan Kis 
---
 index.bs | 18 +-----------------
 1 file changed, 1 insertion(+), 17 deletions(-)

diff --git a/index.bs b/index.bs
index c5dd8e5e..509701eb 100644
--- a/index.bs
+++ b/index.bs
@@ -706,9 +706,6 @@ interface MLOperand {};
     : \[[dimensions]] of type `sequence`
     ::
         The {{MLOperand}}'s dimensions
-    : \[[rank]] of type `unsigned long`
-    ::
-        The {{MLOperand}}'s rank
     : \[[name]] of type [=string=]
     ::
         The {{MLOperand}}'s name (only for input operands)
@@ -725,12 +722,7 @@ interface MLOperand {};
 
 
The rank of an {{MLOperand}} |operand| is the value returned by the following steps: - 1. If |operand|.{{MLOperand/[[rank]]}} [=map/exists=], return its value. - 1. Let |rank| be 0. - 1. For each |dimension| of |operand|.{{MLOperand/[[dimensions]]}}: - 1. Add 1 to |rank|. - 1. Set |operand|.{{MLOperand/[[rank]]}} to |rank|. - 1. Return rank. + 1. Return the size of |operand|.{{MLOperand/[[dimensions]]}}.
Since the {{MLOperand/[[builder]]}} object is bound by the {{MLGraphBuilder/constructor()}} constructor to an {{MLContext}} object, an {{MLOperand}} is also always bound to the same {{MLContext}} object. @@ -751,14 +743,6 @@ interface MLActivation {}; : \[[name]] of type [=string=] :: The {{MLActivation}}'s name -
From 3e6fa5bec7e65adea4627de4dd6726fbae4c4de7 Mon Sep 17 00:00:00 2001 From: Zoltan Kis Date: Thu, 2 Mar 2023 16:13:37 +0200 Subject: [PATCH 04/16] Add constructors for MLOperand and MLActivation - experimental Signed-off-by: Zoltan Kis --- index.bs | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 79 insertions(+), 3 deletions(-) diff --git a/index.bs b/index.bs index 509701eb..a2ee9bc0 100644 --- a/index.bs +++ b/index.bs @@ -691,13 +691,14 @@ An {{MLOperand}} represents an intermediary graph being constructed as a result For instance, an {{MLOperand}} may represent a constant feeding to an operation or the result from combining multiple constants together into an operation. See also [[#programming-model]]. {{MLOperand}} has the following internal slots:
- : \[[kind]] of type `enum { "input", "constant", "output"}` + : \[[kind]] of type {{MLOperandKind}} :: The {{MLOperand}}'s kind : \[[type]] of type {{MLOperandType}} @@ -720,6 +721,7 @@ interface MLOperand {}; The {{MLOperand}}'s associated builder object
+
The rank of an {{MLOperand}} |operand| is the value returned by the following steps: 1. Return the size of |operand|.{{MLOperand/[[dimensions]]}}. @@ -729,13 +731,69 @@ Since the {{MLOperand/[[builder]]}} object is bound by the {{MLGraphBuilder/cons The guidelines in [[#security-new-ops]] also apply for operands. +#### The {{MLOperand}} constructor #### {#api-mloperand-constructor} +The [=new=] {{MLOperand}} constructor steps are: +1. If [=this=]'s [=relevant global object=]'s [=associated Document=] is not [=allowed to use=] the [=webnn-feature|webnn=] feature, throw a "{{SecurityError}}" {{DOMException}} and abort these steps. +1. Let |builder| be the first argument. +1. If |builder| is not an instance of {{MLGraphBuilder}}, throw a "{{TypeError}}" and abort these steps. +1. Set [=this=]'s {{MLOperand/[[builder]]}} to |builder|. +1. Let |kind| be the second argument. +1. If |kind| is not an {{MLOperandKind}}, throw a "{{TypeError}}" {{DOMException}} and abort these steps. +1. Set [=this=]'s {{MLOperand/[[kind]]}} to |kind|. +1. Let |type| be the third argument. +1. If |type| is not an {{MLOperandType}}, throw a "{{TypeError}}" {{DOMException}} and abort these steps. +1. Set [=this=]'s {{MLOperand/[[type]]}} to |type|. +1. If |kind| is `"constant"`: + 1. Let |name| be the fourth argument. + 1. If |name| is not a [=string=], throw a "{{TypeError}}" {{DOMException}} and abort these steps. + 1. Set [=this=]'s {{MLOperand/[[name]]}} to |name|. + 1. Let |desc| be the fifth argument. + 1. If |desc| is not an {{MLOperandDescriptor}}, throw a "{{TypeError}}" {{DOMException}} and abort these steps. + 1. If |type| is not equal to |desc|'s {{MLOperandDescriptor/type}}, throw a "{{DataError}}" {{DOMException}} and abort these steps. + 1. Set [=this=]'s {{MLOperand/[[dimensions]]}} to |desc|.{{MLOperandDescriptor/dimensions}}. + 1. Let |bufferView| be the sixth argument. + 1. If |bufferView| is not an {{MLBufferView}}, throw a "{{DataError}}" {{DOMException}} and abort these steps. + 1. If |type| is not equal to |bufferView|'s [=element type=], throw a "{{DataError}}" {{DOMException}} and abort these steps. + 1. If the [=byte length=] of |desc| is not supported by the implementation, throw a "{{DataError}}" {{DOMException}} and abort these steps. + 1. If the [=byte length=] of |desc| is not equal with |bufferView|.\[[ByteLength]], throw a "{{DataError}}" {{DOMException}} and abort these steps. + 1. Set [=this=]'s {{MLOperand/[[tensorData]]}} to |bufferView|. +1. Otherwise, of |kind| is `"input"`: + 1. Let |name| be the fourth argument. + 1. If |name| is not a [=string=], throw a "{{TypeError}}" {{DOMException}} and abort these steps. + 1. Set [=this=]'s {{MLOperand/[[name]]}} to |name|. + 1. Let |desc| be the fifth argument. + 1. If |desc| is not an {{MLOperandDescriptor}}, throw a "{{TypeError}}" {{DOMException}} and abort these steps. + 1. If |type| is not equal to |desc|'s {{MLOperandDescriptor/type}}, throw a "{{DataError}}" {{DOMException}} and abort these steps. + 1. If the [=byte length=] of |desc| is not supported by the implementation, throw a "{{DataError}}" {{DOMException}} and abort these steps. + 1. Set [=this=]'s {{MLOperand/[[dimensions]]}} to |desc|.{{MLOperandDescriptor/dimensions}}. +1. Otherwise, of |kind| is `"output"`: + 1. Let |dimensions| be the fourth argument. + 1. If the [=check dimensions=] steps given |type| and |dimensions| return `false`, throw a "{{DataError}}" {{DOMException}} and abort these steps. + 1. Let |activation| be the fifth argument. + 1. If |activation| is not `undefined` and is not a [=string=] or a [=function=], throw a "{{DataError}}" {{DOMException}} and abort these steps. + 1. If |activation| is a [=string=] and is not supported by the implementation as an activation function, throw a "{{DataError}}" {{DOMException}} and abort these steps. + 1. Make a request to the underlying platform to register |activation| as an activation function for [=this=]. +1. Return [=this=]. + +To check dimensions given |dimensions| and |type|, run the following steps: +1. If |dimensions| is not an array of positive numbers, return `false`; +1. If |dimensions|.length is 0, return `false`. +1. If |dimensions|.length is too large to be supported by the implementation, return `false`. +1. If any element of |dimensions| is too large to be supported by the implementation, return `false`. +1. Return `true`. + ### The MLActivation interface ### {#api-mlactivation} Objects implementing the {{MLActivation}} interface represent activation function types. {{MLActivation}} has the following internal slots: @@ -743,6 +801,12 @@ interface MLActivation {}; : \[[name]] of type [=string=] :: The {{MLActivation}}'s name + : \[[builder]] of type {{MLGraphBuilder}} + :: + The graph builder object this {{MLActivation}} belongs to. + : \[[options]] of type [=object=] + :: + An {{MLActivationOptions}} dictionary containing {{MLActivation}}'s options.
@@ -753,6 +817,19 @@ These activations function types are used to create other operations. One such u The implementation of the {{MLActivation}} interface can simply be a struct that holds a string type of the activation function along with other properties needed. The actual creation of the activation function e.g. a [[#api-mlgraphbuilder-sigmoid]] or [[#api-mlgraphbuilder-relu]] can then be deferred until when the rest of the graph is ready to connect with it such as during the construction of [[#api-mlgraphbuilder-conv2d]] for example.
+#### The {{MLActivation}} constructor #### {#api-mlactivation-constructor} +The [=new=] {{MLActivation}} constructor steps are: +1. If [=this=]'s [=relevant global object=]'s [=associated Document=] is not [=allowed to use=] the [=webnn-feature|webnn=] feature, throw a "{{SecurityError}}" {{DOMException}} and abort these steps. +1. Let |builder| be the first argument. +1. If |builder| is not an instance of {{MLGraphBuilder}}, throw a "{{TypeError}}" and abort these steps. +1. Set [=this=]'s {{MLActivation/[[builder]]}} to |builder|. +1. Let |name| be the second argument. +1. If |name| is `undefined` or `null`, throw a "{{TypeError}}" and abort these steps. +1. Set [=this=]'s {{MLActivation/[[name]]}} to |name|. +1. Let |options| be the third argument. +1. If |options| is an instance of {{MLActivationOptions}}, set [=this=]'s {{MLActivation/[[options]]}} to |options|. +1. Return [=this=]. + ## The MLContext interface ## {#api-mlcontext} The {{MLContext}} interface represents a global state of neural network compute workload and execution processes. Each {{MLContext}} object has associated [=context type=], [=device type=] and [=power preference=]. @@ -1188,7 +1265,6 @@ The [=new=] {{MLGraphBuilder}} constructor steps are: 1. If [=this=]'s [=relevant global object=]'s [=associated Document=] is not [=allowed to use=] the [=webnn-feature|webnn=] feature, throw a "{{SecurityError}}" {{DOMException}} and abort these steps. 1. Let |context| be the first argument. 1. If the validate MLContext steps given |context| return `false`, throw a "{{TypeError}}" and abort these steps. - 1. Set {{MLGraphBuilder/[[context]]}} to |context|. ### The batchNormalization() method ### {#api-mlgraphbuilder-batchnorm} From ba97a1535d9387b7eb196de761980868399e9015 Mon Sep 17 00:00:00 2001 From: Zoltan Kis Date: Thu, 16 Mar 2023 15:42:25 +0200 Subject: [PATCH 05/16] Address review comments: make MLOperand and MLActivation constructors private, add operator internal slot, improve steps Signed-off-by: Zoltan Kis --- index.bs | 78 +++++++++++++++++++++++++------------------------------- 1 file changed, 35 insertions(+), 43 deletions(-) diff --git a/index.bs b/index.bs index a2ee9bc0..d0cfc92b 100644 --- a/index.bs +++ b/index.bs @@ -700,25 +700,25 @@ interface MLOperand {};
: \[[kind]] of type {{MLOperandKind}} :: - The {{MLOperand}}'s kind + The {{MLOperand}}'s kind. : \[[type]] of type {{MLOperandType}} :: - The {{MLOperand}}'s type + The {{MLOperand}}'s type. : \[[dimensions]] of type `sequence` :: - The {{MLOperand}}'s dimensions + The {{MLOperand}}'s dimensions. : \[[name]] of type [=string=] :: - The {{MLOperand}}'s name (only for input operands) + The {{MLOperand}}'s name (only for input operands). : \[[tensorData]] of type {{ArrayBufferView}} :: - The {{MLOperand}}'s data buffer (only for constant operands) - : \[[activation]] of type {{MLActivation}} - :: - The {{MLOperand}}'s associated activation function object + The {{MLOperand}}'s data buffer (only for constant operands). : \[[builder]] of type {{MLGraphBuilder}} :: - The {{MLOperand}}'s associated builder object + The {{MLOperand}}'s associated builder object. + : \[[operator]] of type [=function=] + :: + The {{MLOperand}}'s associated operator function.
@@ -729,10 +729,8 @@ interface MLOperand {}; Since the {{MLOperand/[[builder]]}} object is bound by the {{MLGraphBuilder/constructor()}} constructor to an {{MLContext}} object, an {{MLOperand}} is also always bound to the same {{MLContext}} object. -The guidelines in [[#security-new-ops]] also apply for operands. - -#### The {{MLOperand}} constructor #### {#api-mloperand-constructor} -The [=new=] {{MLOperand}} constructor steps are: +#### Creating {{MLOperand}} #### {#api-mloperand-create} +To create MLOperand, run the following steps: 1. If [=this=]'s [=relevant global object=]'s [=associated Document=] is not [=allowed to use=] the [=webnn-feature|webnn=] feature, throw a "{{SecurityError}}" {{DOMException}} and abort these steps. 1. Let |builder| be the first argument. 1. If |builder| is not an instance of {{MLGraphBuilder}}, throw a "{{TypeError}}" and abort these steps. @@ -740,39 +738,30 @@ The [=new=] {{MLOperand}} constructor steps are: 1. Let |kind| be the second argument. 1. If |kind| is not an {{MLOperandKind}}, throw a "{{TypeError}}" {{DOMException}} and abort these steps. 1. Set [=this=]'s {{MLOperand/[[kind]]}} to |kind|. -1. Let |type| be the third argument. -1. If |type| is not an {{MLOperandType}}, throw a "{{TypeError}}" {{DOMException}} and abort these steps. -1. Set [=this=]'s {{MLOperand/[[type]]}} to |type|. +1. Let |desc| be the third argument. +1. If |desc| is not an {{MLOperandDescriptor}}, throw a "{{TypeError}}" {{DOMException}} and abort these steps. +1. If the [=byte length=] of |desc| is not supported by the implementation, throw a "{{DataError}}" {{DOMException}} and abort these steps. +1. If the [=check dimensions=] steps given |descr|.{{MLOperandDescriptor/type}} and |desc|.{{MLOperandDescriptor/dimensions}} return `false`, throw a "{{DataError}}" {{DOMException}} and abort these steps. +1. Set [=this=]'s {{MLOperand/[[type]]}} to |descr|.{{MLOperandDescriptor/type}}. +1. Set [=this=]'s {{MLOperand/[[dimensions]]}} to |desc|.{{MLOperandDescriptor/dimensions}}. 1. If |kind| is `"constant"`: - 1. Let |name| be the fourth argument. - 1. If |name| is not a [=string=], throw a "{{TypeError}}" {{DOMException}} and abort these steps. - 1. Set [=this=]'s {{MLOperand/[[name]]}} to |name|. - 1. Let |desc| be the fifth argument. - 1. If |desc| is not an {{MLOperandDescriptor}}, throw a "{{TypeError}}" {{DOMException}} and abort these steps. - 1. If |type| is not equal to |desc|'s {{MLOperandDescriptor/type}}, throw a "{{DataError}}" {{DOMException}} and abort these steps. - 1. Set [=this=]'s {{MLOperand/[[dimensions]]}} to |desc|.{{MLOperandDescriptor/dimensions}}. - 1. Let |bufferView| be the sixth argument. + 1. Let |bufferView| be the next argument. 1. If |bufferView| is not an {{MLBufferView}}, throw a "{{DataError}}" {{DOMException}} and abort these steps. - 1. If |type| is not equal to |bufferView|'s [=element type=], throw a "{{DataError}}" {{DOMException}} and abort these steps. + 1. If [=this=]'s {{MLOperand/[[type]]}} is not equal to |bufferView|'s [=element type=], throw a "{{DataError}}" {{DOMException}} and abort these steps. 1. If the [=byte length=] of |desc| is not supported by the implementation, throw a "{{DataError}}" {{DOMException}} and abort these steps. 1. If the [=byte length=] of |desc| is not equal with |bufferView|.\[[ByteLength]], throw a "{{DataError}}" {{DOMException}} and abort these steps. 1. Set [=this=]'s {{MLOperand/[[tensorData]]}} to |bufferView|. -1. Otherwise, of |kind| is `"input"`: - 1. Let |name| be the fourth argument. + 1. Make a request to the underlying platform to register [=this=] as a constant. + 1. If that fails, throw a "{{TypeError}}" {{DOMException}} and abort these steps. +1. Otherwise, if |kind| is `"input"`: + 1. Let |name| be the next argument. 1. If |name| is not a [=string=], throw a "{{TypeError}}" {{DOMException}} and abort these steps. 1. Set [=this=]'s {{MLOperand/[[name]]}} to |name|. - 1. Let |desc| be the fifth argument. - 1. If |desc| is not an {{MLOperandDescriptor}}, throw a "{{TypeError}}" {{DOMException}} and abort these steps. - 1. If |type| is not equal to |desc|'s {{MLOperandDescriptor/type}}, throw a "{{DataError}}" {{DOMException}} and abort these steps. - 1. If the [=byte length=] of |desc| is not supported by the implementation, throw a "{{DataError}}" {{DOMException}} and abort these steps. - 1. Set [=this=]'s {{MLOperand/[[dimensions]]}} to |desc|.{{MLOperandDescriptor/dimensions}}. + 1. Make a request to the underlying platform to register [=this=] as an input. + 1. If that fails, throw a "{{TypeError}}" {{DOMException}} and abort these steps. 1. Otherwise, of |kind| is `"output"`: - 1. Let |dimensions| be the fourth argument. - 1. If the [=check dimensions=] steps given |type| and |dimensions| return `false`, throw a "{{DataError}}" {{DOMException}} and abort these steps. - 1. Let |activation| be the fifth argument. - 1. If |activation| is not `undefined` and is not a [=string=] or a [=function=], throw a "{{DataError}}" {{DOMException}} and abort these steps. - 1. If |activation| is a [=string=] and is not supported by the implementation as an activation function, throw a "{{DataError}}" {{DOMException}} and abort these steps. - 1. Make a request to the underlying platform to register |activation| as an activation function for [=this=]. + 1. Make a request to the underlying platform to register [=this=] as an output. + 1. If that fails, throw a "{{TypeError}}" {{DOMException}} and abort these steps. 1. Return [=this=]. To check dimensions given |dimensions| and |type|, run the following steps: @@ -791,8 +780,6 @@ typedef object MLActivationOptions; [SecureContext, Exposed=(Window, DedicatedWorker)] interface MLActivation { - constructor(MLGraphBuilder builder, DOMString name, - optional MLActivationOptions options); }; @@ -800,13 +787,16 @@ interface MLActivation {
: \[[name]] of type [=string=] :: - The {{MLActivation}}'s name + The {{MLActivation}}'s name. : \[[builder]] of type {{MLGraphBuilder}} :: The graph builder object this {{MLActivation}} belongs to. : \[[options]] of type [=object=] :: An {{MLActivationOptions}} dictionary containing {{MLActivation}}'s options. + : \[[implementation]] of type [=function=] + :: + The underlying implementation of the activation function.
@@ -817,8 +807,8 @@ These activations function types are used to create other operations. One such u The implementation of the {{MLActivation}} interface can simply be a struct that holds a string type of the activation function along with other properties needed. The actual creation of the activation function e.g. a [[#api-mlgraphbuilder-sigmoid]] or [[#api-mlgraphbuilder-relu]] can then be deferred until when the rest of the graph is ready to connect with it such as during the construction of [[#api-mlgraphbuilder-conv2d]] for example.
-#### The {{MLActivation}} constructor #### {#api-mlactivation-constructor} -The [=new=] {{MLActivation}} constructor steps are: +#### Creating {{MLActivation}} #### {#api-mlactivation-create} +To create MLActivation, run the following steps: 1. If [=this=]'s [=relevant global object=]'s [=associated Document=] is not [=allowed to use=] the [=webnn-feature|webnn=] feature, throw a "{{SecurityError}}" {{DOMException}} and abort these steps. 1. Let |builder| be the first argument. 1. If |builder| is not an instance of {{MLGraphBuilder}}, throw a "{{TypeError}}" and abort these steps. @@ -828,6 +818,8 @@ The [=new=] {{MLActivation}} constructor steps are: 1. Set [=this=]'s {{MLActivation/[[name]]}} to |name|. 1. Let |options| be the third argument. 1. If |options| is an instance of {{MLActivationOptions}}, set [=this=]'s {{MLActivation/[[options]]}} to |options|. +1. Make a request to the underlying platform to bind the implementation for |name| to [=this=]'s {{MLActivation/[[implementation]]}}. + 1. If that fails, throw a "{{TypeError}}" and abort these steps. 1. Return [=this=]. ## The MLContext interface ## {#api-mlcontext} From 66ec9d89095b6af0e2a1da926e04ebc66686baaa Mon Sep 17 00:00:00 2001 From: Zoltan Kis Date: Sat, 18 Mar 2023 15:08:37 +0200 Subject: [PATCH 06/16] Add clarifying notes to creating MLOperand and MLActivation Signed-off-by: Zoltan Kis --- index.bs | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/index.bs b/index.bs index d0cfc92b..2f6d99e0 100644 --- a/index.bs +++ b/index.bs @@ -730,6 +730,9 @@ interface MLOperand {}; Since the {{MLOperand/[[builder]]}} object is bound by the {{MLGraphBuilder/constructor()}} constructor to an {{MLContext}} object, an {{MLOperand}} is also always bound to the same {{MLContext}} object. #### Creating {{MLOperand}} #### {#api-mloperand-create} +
+ The {{MLOperand}} objects are created internally by the methods of {{MLGraphBuilder}}. Based on these steps, exposing a constructor would be possible as well, but needs an explicit use case. +
To create MLOperand, run the following steps: 1. If [=this=]'s [=relevant global object=]'s [=associated Document=] is not [=allowed to use=] the [=webnn-feature|webnn=] feature, throw a "{{SecurityError}}" {{DOMException}} and abort these steps. 1. Let |builder| be the first argument. @@ -775,6 +778,10 @@ To check dimensions given |dimensions| and |type|, run the following Objects implementing the {{MLActivation}} interface represent activation function types. +
+These activations function types are used to create other operations. One such use of this interface is for when an activation function is fused into another operation such as [[#api-mlgraphbuilder-conv2d]] or [[#api-mlgraphbuilder-batchnorm]] during a graph construction session. Such fused activation functions can provide a significant performance improvement when supported natively by the underlying implementation. This is intended as an optimization opportunity for implementers. +
+ @@ -727,9 +726,7 @@ interface MLOperand {}; Since the {{MLOperand/[[builder]]}} object is bound by the {{MLGraphBuilder/constructor()}} constructor to an {{MLContext}} object, an {{MLOperand}} is also always bound to the same {{MLContext}} object. #### Creating {{MLOperand}} #### {#api-mloperand-create} -
- The {{MLOperand}} objects are created by the methods of {{MLGraphBuilder}}. -
+The {{MLOperand}} objects are created by the methods of {{MLGraphBuilder}}, internally using the following algorithms. To create MLOperand given |builder| and |desc|, run the following steps: