From e284f2acc4c8db0db5f2415adc8be7ef188299c6 Mon Sep 17 00:00:00 2001 From: Chai Chaoweeraprasit Date: Thu, 9 Nov 2023 22:53:23 -0800 Subject: [PATCH 01/19] almost done. --- index.bs | 2238 ++++++++++++++++++++++++++++++++---------------------- 1 file changed, 1327 insertions(+), 911 deletions(-) diff --git a/index.bs b/index.bs index 35ee539c..43a24d83 100644 --- a/index.bs +++ b/index.bs @@ -395,7 +395,7 @@ th, td { Introduction {#intro} ===================== -The Web Neural Network API defines a web-friendly hardware-agnostic abstraction layer that makes use of Machine Learning capabilities of operating systems and underlying hardware platforms without being tied to platform-specific capabilities. The abstraction layer addresses the requirements of key Machine Learning JavaScript frameworks and also allows web developers familiar with the ML domain to write custom code without the help of libraries. A complementary Model Loader API defines a higher-level abstraction targeting primarily web developers. +The Web Neural Network API defines a web-friendly hardware-agnostic abstraction layer that makes use of Machine Learning capabilities of operating systems and underlying hardware platforms without being tied to platform-specific capabilities. The abstraction layer addresses the requirements of key Machine Learning JavaScript frameworks and also allows web developers familiar with the ML domain to write custom code without the help of libraries. For an illustrated introduction, please see the explainer. @@ -671,8 +671,8 @@ array data (such as its shape). As mentioned above, the operations have a 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, or squeeze may return a view of its input tensor -that shares the same buffer as the input tensor. (In the case of reshape or squeeze, +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, the entire data is shared, while in the case of slice, a part of the input data is shared.) The implementation may use views, as above, for intermediate values. @@ -725,20 +725,7 @@ The following table summarizes the types of resource supported by the context cr API {#api} ===================== -## The navigator.ml interface ## {#api-navigator-ml} - -An {{ML}} object is available in the {{Window}} and {{DedicatedWorkerGlobalScope}} contexts through the {{Navigator}} -and {{WorkerNavigator}} interfaces respectively and is exposed via `navigator.ml`. - - - -## The ML interface ## {#api-ml} +## {{ML}} interface ## {#api-ml} - -
-{{MLGraph}} has the following internal slots: -
- : \[[context]] of type {{MLContext}} - :: - The context of type {{MLContext}} associated with this {{MLGraph}}. - - : \[[inputDescriptors]] of type [=record=]<{{DOMString}}, {{MLOperandDescriptor}}> - :: - Maps the name of an input {{MLOperand}} to its {{MLOperandDescriptor}} for all input {{MLOperand}}s of this {{MLGraph}}. - - : \[[outputDescriptors]] of type [=record=]<{{DOMString}}, {{MLOperandDescriptor}}> - :: - Maps the name of an output {{MLOperand}} to its {{MLOperandDescriptor}} for all output {{MLOperand}}s of this {{MLGraph}}. - - : \[[implementation]] - :: - The underlying implementation provided by the User Agent. -
-
- -### The MLOperandDescriptor dictionary ### {#api-mloperanddescriptor} - - -
- - The byte length of an {{MLOperandDescriptor}} |desc| is the value returned by the following steps: - -
- 1. Let |elementLength| be 1. - 1. [=map/For each=] |dimension| of |desc|.{{MLOperandDescriptor/dimensions}}: - 1. Set |elementLength| to |elementLength| × |dimension|. - 1. Let |elementSize| be the [=element size=] of one of the {{ArrayBufferView}} types that matches |desc|.{{MLOperandDescriptor/dataType}} according to [this table](#appendices-mloperanddatatype-arraybufferview-compatibility). - 1. Return |elementLength| × |elementSize|. -
-
- -### The MLOperand interface ### {#api-mloperand} - -An {{MLOperand}} represents an intermediary graph being constructed as a result of compositing parts of an operation into a fully composed operation. - -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: -
- : \[[builder]] of type {{MLGraphBuilder}} - :: - The {{MLOperand}}'s associated builder object. - - : \[[descriptor]] of type {{MLOperandDescriptor}} - :: - The {{MLOperand}}'s descriptor. - - : \[[name]] of type [=string=] - :: - The {{MLOperand}}'s name (only for input operands). - - : \[[operand]] of type [=object=] - :: - Reference to {{MLOperand}}'s corresponding [=implementation-defined=] platform operand object. - - : \[[operator]] of type [=object=] - :: - Reference to {{MLOperand}}'s corresponding [=implementation-defined=] platform operator object. -
-
- -
-To get the rank of an {{MLOperand}} |operand|, run the following steps: -
- 1. Return the [=list/size=] of |operand|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/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. - -#### Creating {{MLOperand}} #### {#api-mloperand-create} -The {{MLOperand}} objects are created by the methods of {{MLGraphBuilder}}, internally using the following algorithms. - -
- - To create an MLOperand given |builder| and |desc|, run the following steps: - -
- 1. [=Assert=]: the type of |builder| is {{MLGraphBuilder}}. - 1. [=Assert=]: the type of |desc| is {{MLOperandDescriptor}}. - 1. Let |operand| be a new [=object=]. - 1. Set |operand|.{{MLOperand/[[builder]]}} to |builder|. - 1. Set |operand|.{{MLOperand/[[descriptor]]}} to |desc|. - 1. Return |operand|. -
-
- -
- - To copy an MLOperand given |operand|, run the following steps: - -
- 1. [=Assert=]: the type of |operand| is {{MLOperand}}. - 1. Let |result| be a new [=object=]. - 1. Set |result|.{{MLOperand/[[builder]]}} to |operand|.{{MLOperand/[[builder]]}}. - 1. Set |result|.{{MLOperand/[[descriptor]]}} to |operand|.{{MLOperand/[[descriptor]]}}. - 1. If |operand|.{{MLOperand/[[name]]}} [=map/exists=], then set |result|.{{MLOperand/[[name]]}} to |operand|.{{MLOperand/[[name]]}}. - 1. Return |result|. -
-
- -
- - To check dimensions given |dimensions| and |type|, run the following steps: - -
- 1. If the [=list/size=] of |dimensions| is 0, return false. - 1. If the [=list/size=] of |dimensions| is too large to be supported by the implementation, return false. - 1. If any element of |dimensions| is not a positive number, or it is too large to be supported by the implementation given |type|, return false. - 1. Return true. -
-
- -
- - To validate MLOperand given |operand| and |builder|, run the following steps: - -
- 1. [=Assert=]: the type of |operand|.{{MLOperand/[[builder]]}} is {{MLGraphBuilder}}. - 1. If |builder| is not equal to |operand|.{{MLOperand/[[builder]]}}, return false. - 1. Let |desc| be |operand|.{{MLOperand/[[descriptor]]}}. - 1. If |desc|.{{MLOperandDescriptor/dimensions}} [=map/exists=] and invoking check dimensions given |desc|.{{MLOperandDescriptor/dimensions}} and |desc|.{{MLOperandDescriptor/dataType}} returns false, then return false. - 1. Return true. -
-
- -### The MLActivation interface ### {#api-mlactivation} +## {{MLActivation}} interface ## {#api-mlactivation} Objects implementing the {{MLActivation}} interface represent activation function types. @@ -1048,7 +867,7 @@ interface MLActivation { 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. -#### Creating {{MLActivation}} #### {#api-mlactivation-create} +### Creating {{MLActivation}} ### {#api-mlactivation-create}
The {{MLActivation}} objects (including the ones passed as input to methods) are created by the methods of {{MLGraphBuilder}} and are identified by their name. The |options| dictionary is defined by those methods. The actual creation of the activation function e.g. a [[#api-mlgraphbuilder-sigmoid-method]] or [[#api-mlgraphbuilder-relu-method]] 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.
@@ -1074,92 +893,221 @@ The {{MLActivation}} objects (including the ones passed as input to methods) are -## 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=]. - -The context type is the type of the execution context that manages the resources and facilitates the compilation and execution of the neural network graph: -
-
"default"
-
Context created per user preference options.
-
"webgpu"
-
Context created from WebGPU device.
-
- -The device type indicates the kind of device used for the context. It is one of the following: -
-
"cpu"
-
Provides the broadest compatibility and usability across all client devices with varying degrees of performance.
-
"gpu"
-
Provides the broadest range of achievable performance across graphics hardware platforms from consumer devices to professional workstations.
-
- -The power preference indicates preference as related to power consumption. It is one of the following: -
-
"default"
-
Let the user agent select the most suitable behavior.
-
"high-performance"
-
Prioritizes execution speed over power consumption.
-
"low-power"
-
Prioritizes power consumption over other considerations such as execution speed.
-
+## {{MLCommandEncoder}} interface ## {#api-mlcommandencoder} +The {{MLCommandEncoder}} interface represents a method of execution that synchronously records the computational workload of a compiled {{MLGraph}} to a {{GPUCommandBuffer}} on the calling thread. Since the workload is not immediately executed, just recorded, this method allows more flexibility for the caller to determine how and when the recorded commands will be submitted for execution on the GPU relative to other GPU workload on the same or different queue.
-{{MLContext}} has the following internal slots: -
- : \[[contextType]] of type [=context type=] - :: - The {{MLContext}}'s [=context type=]. - : \[[deviceType]] of type [=device type=] +{{MLCommandEncoder}} has the following internal slots: +
+ : \[[context]] of type {{MLContext}} :: - The {{MLContext}}'s [=device type=]. - : \[[powerPreference]] of type [=power preference=] + The context of type {{MLContext}} associated with this {{MLCommandEncoder}}. + + : \[[implementation]] :: - The {{MLContext}}'s [=power preference=]. + The underlying implementation provided by the User Agent.
-
-When the {{[[contextType]]}} is set to [=default-context|default=] with the {{MLContextOptions}}.{{deviceType}} set to [=device-type-gpu|gpu=], the user agent is responsible for creating an internal GPU device that operates within the context and is capable of ML workload submission on behalf of the calling application. In this setting however, only {{ArrayBufferView}} inputs and outputs are allowed in and out of the graph execution since the application has no way to know what type of internal GPU device is being created on their behalf. In this case, the user agent is responsible for automatic uploads and downloads of the inputs and outputs to and from the GPU memory using this said internal device. -
+### Graph Initialization ### {#api-mlcommandencoder-graph-initialization} +Record the initialization of the {{MLGraph}}. This is a necessary step for optimal performance during graph execution as it gives the platform an opportunity to prepare and optimize constant input data for the subsequent execution of the graph. This method should only be called once per graph. + + + +
+ **Arguments:** + - *graph*: an {{MLGraph}}. The compiled graph to be initialized with graph constant inputs. -### The {{MLContext}} validation algorithm ### {#api-mlcontext-validate} + **Returns:** {{undefined}}. +
- To validate MLContext, given |context|, run these steps: + The initializeGraph(graph) method steps are: -
- 1. If |context|.{{[[contextType]]}} is not "[=webgpu-context|webgpu=]" or "[=default-context|default=]", return false. - 1. If |context|.{{[[deviceType]]}} is not "[=device-type-cpu|cpu=]" or "[=device-type-gpu|gpu=]", return false. - 1. If |context|.{{[[powerPreference]]}} is not "[=power-preference-default|default=]" or "[=power-preference-high-performance|high-performance=]" or "[=power-preference-low-power|low-power=]", return false. - 1. If the user agent cannot support |context|.{{[[contextType]]}}, |context|.{{[[deviceType]]}} and |context|.{{[[powerPreference]]}}, return false. - 1. Return true; +
+
+ Graph initialization stage typically involves a process known as "weight preprocessing" where all the constant inputs to the graph are preprocessed and cached at the operating system level for subsequent graph execution calls. The initializing inputs are typically the constant weight data specified through the {{MLGraphBuilder/constant(descriptor, bufferView)|MLGraphBuilder/constant(value, type)}} method as constant operands during graph construction time. +
-### Synchronous Execution ### {#api-mlcontext-sync-execution} -Synchronously carries out the computational workload of a compiled graph {{MLGraph}} on the calling thread, which must be a worker thread, to produce results as defined by the operations in the graph. This method of execution requires an {{MLContext}} created with {{MLContextOptions}}. Otherwise, it[=exception/throws=] an "{{OperationError}}" {{DOMException}}. +### Dispatch Execution Commands ### {#api-mlcommandencoder-dispatch-commands} +Record the {{MLGraph}} execution with the inputs {{MLNamedGPUResources}} and outputs {{MLNamedGPUResources}}.
**Arguments:** - - *graph*: an {{MLGraph}}. The compiled graph to be executed. - - *inputs*: an {{MLNamedArrayBufferViews}}. The resources of inputs. - - *outputs*: an {{MLNamedArrayBufferViews}}. The pre-allocated resources of required outputs. + - *graph*: an {{MLGraph}}. The compiled graph to be executed. + - *inputs*: an {{MLNamedGPUResources}}. The resources of inputs. + - *outputs*: an {{MLNamedGPUResources}}. The pre-allocated resources of required outputs. + + **Returns:** {{undefined}}. +
+ +
+ + The dispatch(|graph|, |inputs|, |outputs|) method steps are: + +
+ 1. If any of the following requirements are unmet, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. +
+ 1. [=map/For each=] |key| → |value| of |inputs|: + 1. |graph|.{{MLGraph/[[inputDescriptors]]}}[|key|] must [=map/exist=]. + 1. Let |inputDesc| be |graph|.{{MLGraph/[[inputDescriptors]]}}[|key|]. + 1. If |value| is a {{GPUBuffer}}, then: + 1. |value|.{{GPUBuffer/size}} must equal to [=byte length=] of |inputDesc|. + 1. [=map/For each=] |key| → |value| of |outputs|: + 1. |graph|.{{MLGraph/[[outputDescriptors]]}}[|key|] must [=map/exist=]. + 1. Let |outputDesc| be |graph|.{{MLGraph/[[outputDescriptors]]}}[|key|]. + 1. If |value| is a {{GPUBuffer}}, then: + 1. |value|.{{GPUBuffer/size}} must equal to [=byte length=] of |outputDesc|. +
+ 1. [=map/For each=] |key| → |value| of |inputs|: + 1. Set the input of |graph|.{{MLGraph/[[implementation]]}} that is associated with |key| to |value|. + 1. [=map/For each=] |key| → |value| of |outputs|: + 1. Set the output of |graph|.{{MLGraph/[[implementation]]}} that is associated with |key| to |value|. + 1. Issue a compute request of |graph|.{{MLGraph/[[implementation]]}}. + 1. If there is an error returned by |graph|.{{MLGraph/[[implementation]]}}, then: + 1. Throw an "{{OperationError}}" {{DOMException}}. + 1. Return {{undefined}}. +
+
+ +### Generate GPU Command Buffer ### {#api-mlcommandencoder-generate-gpu-command-buffer} +Complete the recording of ML workload and return a WebGPU-compatible {{GPUCommandBuffer}} containing the recorded workload. + + + +
+ **Arguments:** + - *descriptor*: an optional {{GPUCommandBufferDescriptor}}. Descriptor of the command buffer. + + **Returns:** {{GPUCommandBuffer}}. +
+ +
+ + The finish(|descriptor|) method steps are: + +
+ 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. Make a request to the underlying platform to complete the recording of the ML workload, given |descriptor|. +
+ See the related WebGPU steps. +
+ 1. Return a {{GPUCommandBuffer}} containing the recorded workload. +
+
+ +## {{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=]. + +The context type is the type of the execution context that manages the resources and facilitates the compilation and execution of the neural network graph: +
+
"default"
+
Context created per user preference options.
+
"webgpu"
+
Context created from WebGPU device.
+
+ +The device type indicates the kind of device used for the context. It is one of the following: +
+
"cpu"
+
Provides the broadest compatibility and usability across all client devices with varying degrees of performance.
+
"gpu"
+
Provides the broadest range of achievable performance across graphics hardware platforms from consumer devices to professional workstations.
+
+ +The power preference indicates preference as related to power consumption. It is one of the following: +
+
"default"
+
Let the user agent select the most suitable behavior.
+
"high-performance"
+
Prioritizes execution speed over power consumption.
+
"low-power"
+
Prioritizes power consumption over other considerations such as execution speed.
+
+ + + +
+{{MLContext}} has the following internal slots: +
+ : \[[contextType]] of type [=context type=] + :: + The {{MLContext}}'s [=context type=]. + : \[[deviceType]] of type [=device type=] + :: + The {{MLContext}}'s [=device type=]. + : \[[powerPreference]] of type [=power preference=] + :: + The {{MLContext}}'s [=power preference=]. +
+
+ +
+When the {{[[contextType]]}} is set to [=default-context|default=] with the {{MLContextOptions}}.{{deviceType}} set to [=device-type-gpu|gpu=], the user agent is responsible for creating an internal GPU device that operates within the context and is capable of ML workload submission on behalf of the calling application. In this setting however, only {{ArrayBufferView}} inputs and outputs are allowed in and out of the graph execution since the application has no way to know what type of internal GPU device is being created on their behalf. In this case, the user agent is responsible for automatic uploads and downloads of the inputs and outputs to and from the GPU memory using this said internal device. +
+ +### {{MLContext}} validation algorithm ### {#api-mlcontext-validate} + +
+ + To validate MLContext, given |context|, run these steps: + +
+ 1. If |context|.{{[[contextType]]}} is not "[=webgpu-context|webgpu=]" or "[=default-context|default=]", return false. + 1. If |context|.{{[[deviceType]]}} is not "[=device-type-cpu|cpu=]" or "[=device-type-gpu|gpu=]", return false. + 1. If |context|.{{[[powerPreference]]}} is not "[=power-preference-default|default=]" or "[=power-preference-high-performance|high-performance=]" or "[=power-preference-low-power|low-power=]", return false. + 1. If the user agent cannot support |context|.{{[[contextType]]}}, |context|.{{[[deviceType]]}} and |context|.{{[[powerPreference]]}}, return false. + 1. Return true; +
+
+ +### Synchronous Execution ### {#api-mlcontext-sync-execution} +Synchronously carries out the computational workload of a compiled graph {{MLGraph}} on the calling thread, which must be a worker thread, to produce results as defined by the operations in the graph. This method of execution requires an {{MLContext}} created with {{MLContextOptions}}. Otherwise, it[=exception/throws=] an "{{OperationError}}" {{DOMException}}. + + + +
+ **Arguments:** + - *graph*: an {{MLGraph}}. The compiled graph to be executed. + - *inputs*: an {{MLNamedArrayBufferViews}}. The resources of inputs. + - *outputs*: an {{MLNamedArrayBufferViews}}. The pre-allocated resources of required outputs. **Returns:** {{undefined}}.
@@ -1198,7 +1146,7 @@ partial interface MLContext {
1. If |bufferView| is not an {{MLBufferView}}, return false. - 1. If |bufferView|'s [=element type=] does not match to |descriptor|.{{MLOperandDescriptor/dataType}} according to [this table](#appendices-mloperanddatatype-arraybufferview-compatibility), return false. + 1. If |bufferView|'s [=element type=] does not match to |descriptor|.{{MLOperandDescriptor/type}} according to [this table](#appendices-mloperanddatatype-arraybufferview-compatibility), return false. 1. If |bufferView|.\[[ByteLength]] is not equal to the [=byte length=] of |descriptor|, return false.
@@ -1242,12 +1190,12 @@ partial interface MLContext { // Build a graph with two outputs. const builder = new MLGraphBuilder(context); - const descA = {dataType: 'float32', dimensions: [3, 4]}; + const descA = {type: 'float32', dimensions: [3, 4]}; const a = builder.input('a', descA); - const descB = {dataType: 'float32', dimensions: [4, 3]}; + const descB = {type: 'float32', dimensions: [4, 3]}; const bufferB = new Float32Array(sizeOfShape(descB.dimensions)).fill(0.5); const b = builder.constant(descB, bufferB); - const descC = {dataType: 'float32', dimensions: [3, 3]}; + const descC = {type: 'float32', dimensions: [3, 3]}; const bufferC = new Float32Array(sizeOfShape(descC.dimensions)).fill(1); const c = builder.constant(descC, bufferC); const d = builder.matmul(a, b); @@ -1270,7 +1218,7 @@ partial interface MLContext { -### The {{MLNamedArrayBufferViews}} transfer algorithm ### {#mlnamedarraybufferviews-transfer-alg} +### {{MLNamedArrayBufferViews}} transfer algorithm ### {#mlnamedarraybufferviews-transfer-alg}
@@ -1344,7 +1292,7 @@ partial interface MLContext { The following code showcases the asynchronous computation.
-    const operandType = {dataType: 'float32', dimensions: [2, 2]};
+    const operandType = {type: 'float32', dimensions: [2, 2]};
     const context = await navigator.ml.createContext();
     const builder = new MLGraphBuilder(context);
     // 1. Create a computational graph 'C = 0.2 * A + B'.
@@ -1383,24 +1331,28 @@ partial interface MLContext {
     **Returns:** {{MLCommandEncoder}}. The command encoder used to record ML workload on the GPU.
 
 
-## The MLCommandEncoder interface ## {#api-mlcommandencoder}
-The {{MLCommandEncoder}} interface represents a method of execution that synchronously records the computational workload of a compiled {{MLGraph}} to a {{GPUCommandBuffer}} on the calling thread. Since the workload is not immediately executed, just recorded, this method allows more flexibility for the caller to determine how and when the recorded commands will be submitted for execution on the GPU relative to other GPU workload on the same or different queue.
+## {{MLGraph}} interface ## {#api-mlgraph}
+The {{MLGraph}} interface represents a compiled computational graph. A compiled graph once constructed is immutable and cannot be subsequently changed.
 
 
 
 
-{{MLCommandEncoder}} has the following internal slots: -
+{{MLGraph}} has the following internal slots: +
: \[[context]] of type {{MLContext}} :: - The context of type {{MLContext}} associated with this {{MLCommandEncoder}}. + The context of type {{MLContext}} associated with this {{MLGraph}}. + + : \[[inputDescriptors]] of type [=record=]<{{DOMString}}, {{MLOperandDescriptor}}> + :: + Maps the name of an input {{MLOperand}} to its {{MLOperandDescriptor}} for all input {{MLOperand}}s of this {{MLGraph}}. + + : \[[outputDescriptors]] of type [=record=]<{{DOMString}}, {{MLOperandDescriptor}}> + :: + Maps the name of an output {{MLOperand}} to its {{MLOperandDescriptor}} for all output {{MLOperand}}s of this {{MLGraph}}. : \[[implementation]] :: @@ -1408,111 +1360,7 @@ interface MLCommandEncoder {};
-### Graph Initialization ### {#api-mlcommandencoder-graph-initialization} -Record the initialization of the {{MLGraph}}. This is a necessary step for optimal performance during graph execution as it gives the platform an opportunity to prepare and optimize constant input data for the subsequent execution of the graph. This method should only be called once per graph. - - - -
- **Arguments:** - - *graph*: an {{MLGraph}}. The compiled graph to be initialized with graph constant inputs. - - **Returns:** {{undefined}}. -
- -
- - The initializeGraph(graph) method steps are: - -
-
- Graph initialization stage typically involves a process known as "weight preprocessing" where all the constant inputs to the graph are preprocessed and cached at the operating system level for subsequent graph execution calls. The initializing inputs are typically the constant weight data specified through the {{MLGraphBuilder/constant(descriptor, bufferView)|MLGraphBuilder/constant(value, dataType)}} method as constant operands during graph construction time. -
-
-
- -### Dispatch Execution Commands ### {#api-mlcommandencoder-dispatch-commands} -Record the {{MLGraph}} execution with the inputs {{MLNamedGPUResources}} and outputs {{MLNamedGPUResources}}. - - - -
- **Arguments:** - - *graph*: an {{MLGraph}}. The compiled graph to be executed. - - *inputs*: an {{MLNamedGPUResources}}. The resources of inputs. - - *outputs*: an {{MLNamedGPUResources}}. The pre-allocated resources of required outputs. - - **Returns:** {{undefined}}. -
- -
- - The dispatch(|graph|, |inputs|, |outputs|) method steps are: - -
- 1. If any of the following requirements are unmet, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. -
- 1. [=map/For each=] |key| → |value| of |inputs|: - 1. |graph|.{{MLGraph/[[inputDescriptors]]}}[|key|] must [=map/exist=]. - 1. Let |inputDesc| be |graph|.{{MLGraph/[[inputDescriptors]]}}[|key|]. - 1. If |value| is a {{GPUBuffer}}, then: - 1. |value|.{{GPUBuffer/size}} must equal to [=byte length=] of |inputDesc|. - 1. [=map/For each=] |key| → |value| of |outputs|: - 1. |graph|.{{MLGraph/[[outputDescriptors]]}}[|key|] must [=map/exist=]. - 1. Let |outputDesc| be |graph|.{{MLGraph/[[outputDescriptors]]}}[|key|]. - 1. If |value| is a {{GPUBuffer}}, then: - 1. |value|.{{GPUBuffer/size}} must equal to [=byte length=] of |outputDesc|. -
- 1. [=map/For each=] |key| → |value| of |inputs|: - 1. Set the input of |graph|.{{MLGraph/[[implementation]]}} that is associated with |key| to |value|. - 1. [=map/For each=] |key| → |value| of |outputs|: - 1. Set the output of |graph|.{{MLGraph/[[implementation]]}} that is associated with |key| to |value|. - 1. Issue a compute request of |graph|.{{MLGraph/[[implementation]]}}. - 1. If there is an error returned by |graph|.{{MLGraph/[[implementation]]}}, then: - 1. Throw an "{{OperationError}}" {{DOMException}}. - 1. Return {{undefined}}. -
-
- -### Generate GPU Command Buffer ### {#api-mlcommandencoder-generate-gpu-command-buffer} -Complete the recording of ML workload and return a WebGPU-compatible {{GPUCommandBuffer}} containing the recorded workload. - - - -
- **Arguments:** - - *descriptor*: an optional {{GPUCommandBufferDescriptor}}. Descriptor of the command buffer. - - **Returns:** {{GPUCommandBuffer}}. -
- -
- - The finish(|descriptor|) method steps are: - -
- 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. - 1. Make a request to the underlying platform to complete the recording of the ML workload, given |descriptor|. -
- See the related WebGPU steps. -
- 1. Return a {{GPUCommandBuffer}} containing the recorded workload. -
-
- -## The MLGraphBuilder interface ## {#api-mlgraphbuilder} +## {{MLGraphBuilder}} interface ## {#api-mlgraphbuilder} The {{MLGraphBuilder}} interface defines a set of operations as identified by the [[#usecases]] that can be composed into a computational graph. It also represents the intermediate state of a graph building session. @@ -1539,7 +1387,7 @@ interface MLGraphBuilder { MLOperand constant(MLOperandDescriptor descriptor, MLBufferView bufferView); // Create a single-value operand from the specified number of the specified type. - MLOperand constant(double value, optional MLOperandDataType dataType = "float32"); + MLOperand constant(double value, optional MLOperandDataType type = "float32"); // Compile the graph up to the specified output operands asynchronously. Promise build(MLNamedOperands outputs); @@ -1578,7 +1426,7 @@ Both {{MLGraphBuilder}}.{{MLGraphBuilder/build()}} and {{MLGraphBuilder}}.{{MLGr -### The {{MLGraphBuilder}} constructor ### {#api-mlgraphbuilder-constructor} +### {{MLGraphBuilder}} constructor ### {#api-mlgraphbuilder-constructor}
@@ -1591,45 +1439,108 @@ Both {{MLGraphBuilder}}.{{MLGraphBuilder/build()}} and {{MLGraphBuilder}}.{{MLGr
-### The {{MLGraphBuilder/input()}} method ### {#api-mlgraphbuilder-input} -Create a named {{MLOperand}} based on a descriptor, that can be used as an input. +### {{MLGraphBuilder/batchNormalization}} ### {#api-mlgraphbuilder-batchnorm} +Normalize the values of the input tensor using [[Batch-Normalization]]. For each input feature, the mean and variance values of that feature are computed across all the samples in the batch dimension while the model is trained. These mean and variance values are then subsequently given to this operation during model inference. + + + +{{MLBatchNormalizationOptions}} has the following members: +
+ : scale + :: + An {{MLOperand}}. Specifies the 1-D tensor of the scaling values whose is equal to the size of the input dimension denoted by {{MLBatchNormalizationOptions/axis}}. + + : bias + :: + An {{MLOperand}}. Specifies the 1-D tensor of the bias values whose [=list/size=] is equal to the size of the input dimension denoted by {{MLBatchNormalizationOptions/axis}}. + + : axis + :: + An {{unsigned long}} scalar. Specifies the index to the feature count dimension of the input shape for which the mean and variance values are. Its value must be in the range [0, N-1] where N is the [=rank=] of the input tensor. The default value is 1, corresponding to the channel (*"c"*) dimension in the *"nchw"* data layout. + + : epsilon + :: + A {{float}} scalar. Specifies A small value to prevent computational error due to divide-by-zero. + + : activation + :: + An {{MLActivation}} object. Specifies the optional activation function that immediately follows the normalization operation. +
**Arguments:** - - *name*: a [=string=] name of the input. - - *descriptor*: an {{MLOperandDescriptor}} object. - **Returns:**: an {{MLOperand}} object. + - *input*: an {{MLOperand}}. The input N-D tensor. + - *mean*: an {{MLOperand}}. Specifies the 1-D tensor of the mean values of the input features across the batch. Its [=list/size=] is equal to the size of the input dimension denoted by {{MLBatchNormalizationOptions/axis}}. + - *variance*: an {{MLOperand}}. The 1-D tensor of the variance values of the input features across the batch whose [=list/size=] is equal to the size of the input dimension denoted by {{MLBatchNormalizationOptions/axis}}. + - *options*: an optional {{MLBatchNormalizationOptions}}. Specifies the optional parameters of the operation. + + **Returns:** an {{MLOperand}}. The batch-normalized N-D tensor of the same shape as *input*.
- The input(|name|, |descriptor|) method steps are: + The batchNormalization(|input|, |mean|, |variance|, |options|) method steps are:
-
- The permissions and context validity have been checked by [[#api-mlgraphbuilder-constructor]] steps. -
- 1. If |name| is empty, then [=exception/throw=] a {{TypeError}}. - 1. [=Assert=]: the type of |descriptor| is {{MLOperandDescriptor}}. - 1. [=Assert=]: If |descriptor|.{{MLOperandDescriptor/dimensions}} does not [=map/exist=], then |descriptor| defines a scalar input. - 1. If |descriptor|.{{MLOperandDescriptor/dimensions}} [=map/exists=]: - 1. If the [=check dimensions=] steps given |descriptor|.{{MLOperandDescriptor/dataType}} and |descriptor|.{{MLOperandDescriptor/dimensions}} return false, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. - 1. If the [=byte length=] of |descriptor| is not supported by the underlying platform, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. [=Assert=]: the type of |input|, |mean| and |variance| is {{MLOperand}}. + 1. If |options|.axis is not in [=the range=] 0 to the [=rank=] of |input|, exclusive, then [=exception/throw=] a {{TypeError}}. + 1. If the [=list/size=] of |mean|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} is not 1, then [=exception/throw=] a {{TypeError}}. + 1. If |mean|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0] is not equal to |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[|options|.{{MLBatchNormalizationOptions/axis}}], then [=exception/throw=] a {{TypeError}}. + 1. If the [=list/size=] of |variance|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} is not 1, then [=exception/throw=] a {{TypeError}}. + 1. If |variance|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0] is not equal to |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[|options|.{{MLBatchNormalizationOptions/axis}}], then [=exception/throw=] a {{TypeError}}. + 1. If |options|.{{MLBatchNormalizationOptions/scale}} [=map/exists=]: + 1. If its [=list/size=] is not 1, then [=exception/throw=] a {{TypeError}}. + 1. If |options|.{{MLBatchNormalizationOptions/scale}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0] is not equal to |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[|options|.{{MLBatchNormalizationOptions/axis}}], then [=exception/throw=] a {{TypeError}}. + 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}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0] is not equal to |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[|options|.{{MLBatchNormalizationOptions/axis}}], then [=exception/throw=] a {{TypeError}}. 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=] 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. Store a reference of |operandImpl| in |operand|.{{MLOperand/[[operand]]}}. - 1. Register |operand| as an input. - 1. Return |operand|. + 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 an [=implementation-defined=] platform operator |batchNormImpl| for this method, given |input|, |mean|, |variance| and |options|. + 1. If |options|.activation [=map/exists=],register it as activation to |batchNormImpl|. + 1. Connect |output| as output to |batchNormImpl|. + 1. Return |output|.
-### The build() method ### {#api-mlgraphbuilder-build} +
+
+ + The behavior of this operation when the input tensor is 4-D of the *"nchw"* layout and the activation is of operator type *relu* can be generically emulated from the usage of other operations as follow. However, user agents typically have a more efficient implementation for it, therefore its usage is encouraged from the performance standpoint. + +
+    const shape = [1,null,1,1];
+    return builder.relu(
+      builder.add(
+        builder.mul(
+          builder.reshape(options.scale, shape),
+          builder.div(
+            builder.sub(input, builder.reshape(mean, shape)),
+            builder.sqrt(builder.add(builder.reshape(variance, shape), builder.constant(options.epsilon)))
+            )),
+        builder.reshape(options.bias, shape)));
+    
+
+
+ +### {{MLGraphBuilder/build}} ### {#api-mlgraphbuilder-build} Build a composed graph up to a given output operand into a computational graph, asynchronously or synchronously. -#### The {{MLGraphBuilder/build(outputs)}} method #### {#api-mlgraphbuilder-build-outputs} +#### {{MLGraphBuilder/build(outputs)}} #### {#api-mlgraphbuilder-build-outputs}
@@ -1646,7 +1557,7 @@ Build a composed graph up to a given output operand into a computational graph,
-#### The {{MLGraphBuilder/buildSync(outputs)}} method #### {#api-mlgraphbuilder-buildsync-outputs} +#### {{MLGraphBuilder/buildSync(outputs)}} #### {#api-mlgraphbuilder-buildsync-outputs}
@@ -1665,191 +1576,58 @@ Build a composed graph up to a given output operand into a computational graph, 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. 1. Let |graph| be a new {{MLGraph}}: 1. Set |graph|.{{MLGraph/[[context]]}} to [=this=].{{MLGraphBuilder/[[context]]}}. - 1. Make a request to the underlying platform to: - 1. Connect |graph| to a new [=implementation-defined=] graph implementation |graphImpl| given |graph|. - 1. Store a reference to |graphImpl| in |graph|.{{MLGraph/[[implementation]]}}. - 1. Make a request to the underlying platform to initialize the graph: - 1. [=map/For each=] |operand| in |outputs|: - 1. If validating MLOperand given |operand| and [=this=] returns false, then [=exception/throw=] a {{TypeError}}. - 1. If |operand| was created as an input by the underlying platform: - 1. If |operand|.{{MLOperand/[[name]]}}] is not unique for |graphImpl|, then [=exception/throw=] a {{TypeError}}. - 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. Return |graph|. - -
- -### The constant() method ### {#api-mlgraphbuilder-constant-method} -Create a constant {{MLOperand}} that can be used in {{MLGraphBuilder}} methods. - -#### The {{MLGraphBuilder/constant(descriptor, bufferView)}} method #### {#api-mlgraphbuilder-constant} -
- **Arguments:** - - *descriptor*: an {{MLOperandDescriptor}} object - - *bufferView*: an {{MLBufferView}} - **Returns:**: an {{MLOperand}} object. -
- -
- - The constant(|descriptor|, |bufferView|) method steps are: - -
-
- The permissions and context validity have been checked by [[#api-mlgraphbuilder-constructor]] steps. -
- 1. [=Assert=]: the type of |descriptor| is {{MLOperandDescriptor}}. - 1. If the [=byte length=] of |descriptor| is not supported by the underlying platform, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. - 1. If the [=check dimensions=] steps given |descriptor|.{{MLOperandDescriptor/dataType}} and |descriptor|.{{MLOperandDescriptor/dimensions}} return 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. Let |operand| be the result of creating an MLOperand given [=this=] and |descriptor|. - 1. Let |bytes| be the result of invoking the [=get a copy of the bytes held by the buffer source=] steps given |bufferView|. - 1. Make a request to the underlying platform to: - 1. Create an [=implementation-defined=] platform operand |constantImpl| to represent a constant, given |descriptor|. - 1. Store a reference of |constantImpl| in |operand|.{{MLOperand/[[operand]]}}. - 1. Register |operand| as a tensor constant with |bytes| as value. - 1. Return |operand|. -
-
- -#### The {{MLGraphBuilder/constant(value, dataType)}} method #### {#api-mlgraphbuilder-constant-value-datatype} - -
- **Arguments:** - - *value*: a number - - *dataType*: an optional {{MLOperandDataType}}, by default *"float32"*. - **Returns:**: an {{MLOperand}} object. -
- -
- - The constant(|value|, |dataType|) method steps are: - -
-
- The permissions and context validity have been checked by [[#api-mlgraphbuilder-constructor]] steps. -
- 1. Let |descriptor| be a new {{MLOperandDescriptor}}. - 1. Set |descriptor|.{{MLOperandDescriptor/dataType}} to |dataType|. - 1. Set |descriptor|.{{MLOperandDescriptor/dimensions}} to `undefined`. -
- In the case of a scalar constant, |descriptor|.{{MLOperandDescriptor/dimensions}} is ignored. -
- 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=] and |descriptor|. - 1. Make a request to the underlying platform to: - 1. Create an [=implementation-defined=] platform operand |constantImpl| to represent a constant, given |descriptor|. - 1. Store a reference of |constantImpl| in |operand|.{{MLOperand/[[operand]]}}. - 1. Register |operand| as a scalar constant with |value| as value. - 1. Return |operand|. -
-
- -### The batchNormalization() method ### {#api-mlgraphbuilder-batchnorm} -Normalize the tensor values of input features across the batch dimension using [[Batch-Normalization]]. For each input feature, the mean and variance values of that feature supplied in this calculation as parameters are previously computed across the batch dimension of the input during the model training phase of this operation. - - - -{{MLBatchNormalizationOptions}} has the following members: -
- : scale - :: - An {{MLOperand}}. Specifies the 1-D tensor of the scaling values whose is equal to the size of the input dimension denoted by {{MLBatchNormalizationOptions/axis}}. - - : bias - :: - An {{MLOperand}}. Specifies the 1-D tensor of the bias values whose [=list/size=] is equal to the size of the input dimension denoted by {{MLBatchNormalizationOptions/axis}}. - - : axis - :: - A {{long}} scalar. Specifies the index to the feature count dimension of the input shape for which the mean and variance values are. Its value must be in the range [0, N-1] where N is the [=rank=] of the input tensor. The default value is 1, corresponding to the channel (*"c"*) dimension in the *"nchw"* data layout. - - : epsilon - :: - A {{float}} scalar. Specifies A small value to prevent computational error due to divide-by-zero. - - : activation - :: - An {{MLActivation}} object. Specifies the optional activation function that immediately follows the normalization operation. -
+ 1. Make a request to the underlying platform to: + 1. Connect |graph| to a new [=implementation-defined=] graph implementation |graphImpl| given |graph|. + 1. Store a reference to |graphImpl| in |graph|.{{MLGraph/[[implementation]]}}. + 1. Make a request to the underlying platform to initialize the graph: + 1. [=map/For each=] |operand| in |outputs|: + 1. If validating MLOperand given |operand| and [=this=] returns false, then [=exception/throw=] a {{TypeError}}. + 1. If |operand| was created as an input by the underlying platform: + 1. If |operand|.{{MLOperand/[[name]]}}] is not unique for |graphImpl|, then [=exception/throw=] a {{TypeError}}. + 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. Return |graph|. + +
+### {{MLGraphBuilder/cast}} ### {#api-mlgraphbuilder-cast} +Cast each element in the input tensor to the target data type. +
**Arguments:** - *input*: an {{MLOperand}}. The input N-D tensor. - - *mean*: an {{MLOperand}}. Specifies the 1-D tensor of the mean values of the input features across the batch. Its [=list/size=] is equal to the size of the input dimension denoted by {{MLBatchNormalizationOptions/axis}}. - - *variance*: an {{MLOperand}}. The 1-D tensor of the variance values of the input features across the batch whose [=list/size=] is equal to the size of the input dimension denoted by {{MLBatchNormalizationOptions/axis}}. - - *options*: an optional {{MLBatchNormalizationOptions}}. Specifies the optional parameters of the operation. + - *type*: an {{MLOperandDataType}}. The target data type. - **Returns:** an {{MLOperand}}. The batch-normalized N-D tensor of the same shape as *input*. + **Returns:** an {{MLOperand}}. The N-D tensor of the same shape as *input* with each element casted to the target data type.
- The batchNormalization(|input|, |mean|, |variance|, |options|) method steps are: + The cast(|input|, |type|) method steps are:
- 1. [=Assert=]: the type of |input|, |mean| and |variance| is {{MLOperand}}. - 1. If |options|.axis is not in [=the range=] 0 to the [=rank=] of |input|, exclusive, then [=exception/throw=] a {{TypeError}}. - 1. If the [=list/size=] of |mean|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} is not 1, then [=exception/throw=] a {{TypeError}}. - 1. If |mean|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0] is not equal to |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[|options|.{{MLBatchNormalizationOptions/axis}}], then [=exception/throw=] a {{TypeError}}. - 1. If the [=list/size=] of |variance|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} is not 1, then [=exception/throw=] a {{TypeError}}. - 1. If |variance|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0] is not equal to |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[|options|.{{MLBatchNormalizationOptions/axis}}], then [=exception/throw=] a {{TypeError}}. - 1. If |options|.{{MLBatchNormalizationOptions/scale}} [=map/exists=]: - 1. If its [=list/size=] is not 1, then [=exception/throw=] a {{TypeError}}. - 1. If |options|.{{MLBatchNormalizationOptions/scale}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0] is not equal to |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[|options|.{{MLBatchNormalizationOptions/axis}}], then [=exception/throw=] a {{TypeError}}. - 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}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0] is not equal to |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[|options|.{{MLBatchNormalizationOptions/axis}}], then [=exception/throw=] a {{TypeError}}. + 1. [=Assert=]: the type of |input| is {{MLOperand}}. 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. - 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 an [=implementation-defined=] platform operator |batchNormImpl| for this method, given |input|, |mean|, |variance| and |options|. - 1. If |options|.activation [=map/exists=],register it as activation to |batchNormImpl|. - 1. Connect |output| as output to |batchNormImpl|. + 1. Let |output| be the result of copying an MLOperand given |input|. + 1. Make a request to the underlying platform to: + 1. Create an [=implementation-defined=] platform operator |castImpl| for this method, given |type|. + 1. Store a reference of |castImpl| in |output|.{{MLOperand/[[operator]]}}. + 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent clamp output, given |output| and |castImpl|. + 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. + 1. Connect |operand|.{{MLOperand/[[operand]]}} as input to |castImpl|. + 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |castImpl|. 1. Return |output|.
-
-
- - The behavior of this operation when the input tensor is 4-D of the *"nchw"* layout and the activation is of operator type *relu* can be generically emulated from the usage of other operations as follow. However, user agents typically have a more efficient implementation for it, therefore its usage is encouraged from the performance standpoint. - -
-    const shape = [1,null,1,1];
-    return builder.relu(
-      builder.add(
-        builder.mul(
-          builder.reshape(options.scale, shape),
-          builder.div(
-            builder.sub(input, builder.reshape(mean, shape)),
-            builder.pow(
-              builder.add(builder.reshape(variance, shape), builder.constant(options.epsilon)),
-              builder.constant(0.5))
-            )),
-        builder.reshape(options.bias, shape)));
-    
-
-
- -### The clamp() method ### {#api-mlgraphbuilder-clamp} +### {{MLGraphBuilder/clamp}} ### {#api-mlgraphbuilder-clamp} Clamp the input tensor element-wise within a range specified by the minimum and maximum values. @@ -1874,16 +1652,16 @@ partial interface MLGraphBuilder {
     if (options.minValue === undefined) {
       if (options.maxValue === undefined) {
-        return operand;
+        return input;
       } else {
-        return builder.min(operand, builder.constant(options.maxValue));
+        return builder.min(input, builder.constant(options.maxValue));
       }
     } else {
       if (options.maxValue === undefined) {
-        return builder.max(operand, builder.constant(options.minValue));
+        return builder.max(input, builder.constant(options.minValue));
       } else {
         return builder.min(
-            builder.max(operand, builder.constant(options.minValue)),
+            builder.max(input, builder.constant(options.minValue)),
             builder.constant(options.maxValue));
       }
     }
@@ -1901,10 +1679,10 @@ partial interface MLGraphBuilder {
   
 
 
-#### The {{MLGraphBuilder/clamp(operand, options)}} method #### {#api-mlgraphbuilder-clamp-operand-options}
+#### {{MLGraphBuilder/clamp(input, options)}} #### {#api-mlgraphbuilder-clamp-operand-options}
 
**Arguments:** - - *operand*: an {{MLOperand}}. The input tensor. + - *input*: an {{MLOperand}}. The input tensor. - *options*: an optional {{MLClampOptions}}. The optional parameters of the operation. - *minValue*: a {{float}} scalar. Specifies the minimum value of the range. When it is not specified, the clamping is not performed on the lower limit of the range. - *maxValue*: a {{float}} scalar. Specifies the maximum value of the range. When it is not specified, the clamping is not performed on the upper limit of the range. @@ -1913,27 +1691,26 @@ partial interface MLGraphBuilder {
- - The clamp(|operand|, |options|) method steps are: + The clamp(|input|, |options|) method steps are:
- 1. [=Assert=]: the type of |operand| is {{MLOperand}}. + 1. [=Assert=]: the type of |input| is {{MLOperand}}. 1. If running the check clamp options steps given |options| returns false, then [=exception/throw=] a {{TypeError}}. 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. - 1. Let |output| be the result of copying an MLOperand given |operand|. + 1. Let |output| be the result of copying an MLOperand given |input|. 1. Make a request to the underlying platform to: 1. Create an [=implementation-defined=] platform operator |clampImpl| for this method, given |options|.{{MLClampOptions/minValue}} and |options|.{{MLClampOptions/maxValue}}. 1. Store a reference of |clampImpl| in |output|.{{MLOperand/[[operator]]}}. 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent clamp output, given |output| and |clampImpl|. 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. - 1. Connect |operand|.{{MLOperand/[[operand]]}} as input to |clampImpl|. + 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |clampImpl|. 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |clampImpl|. 1. Return |output|.
-#### The {{MLGraphBuilder/clamp(options)}} method #### {#api-mlgraphbuilder-clamp-options} +#### {{MLGraphBuilder/clamp(options)}} #### {#api-mlgraphbuilder-clamp-options}
**Arguments:** - *options*: an optional {{MLClampOptions}}. The optional parameters of the operation. @@ -1956,7 +1733,7 @@ partial interface MLGraphBuilder {
-### The concat() method ### {#api-mlgraphbuilder-concat} +### {{MLGraphBuilder/concat}} ### {#api-mlgraphbuilder-concat} Concatenates the input tensors along a given axis. + +
+ **Arguments:** + - *a*: an {{MLOperand}}. The first input tensor. + - *b*: an {{MLOperand}}. The second input tensor. + + **Returns:** an {{MLOperand}}. The output tensor that contains the result of + element-wise comparison of the two input tensors. +
+ +
- The element-wise binary operation algorithms invoke the [=MLGraphBuilder/element-wise-binary-op | create element-wise binary operation=] steps as follows. + To create element-wise logical operation given |op|, |a| and |b|, run the following steps:
-
- The add(|a|, |b|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-binary-op | create element-wise binary operation=] given "add", |a| and |b|. - 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. - 1. Return |output|. -
+ 1. [=Assert=]: |op| is one of "equal", "greater", "greaterOrEqual", "lesser", "lesserOrEqual", "not". + 1. [=Assert=]: the type of |a| and |b| if available is {{MLOperand}}. + 1. If |a|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}} is not equal to |b|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}} if available, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |descriptor| be a new {{MLOperandDescriptor}}. + 1. Set |descriptor|.{{MLOperandDescriptor/type}} to "uint8". + 1. Let |descriptor|.{{MLOperandDescriptor/dimensions}} be the result of running the [=MLGraphBuilder/broadcast-shapes=] steps given |a|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} and |b|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. + 1. If that [=exception/throws=] an error, re-[=exception/throw=] the error. + 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 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 an [=implementation-defined=] platform operator for the binary operation |op|, given |a| and |b|. + 1. Store a reference of |opImpl| in |output|.{{MLOperand/[[operator]]}}. + 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent the output, given |output| and |opImpl|. + 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. + 1. Connect |a|.{{MLOperand/[[operand]]}} and |b|.{{MLOperand/[[operand]]}} as inputs to |opImpl|. + 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Return |output|. +
+
-
- The sub(|a|, |b|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-binary-op | create element-wise binary operation=] given "sub", |a| and |b|. - 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. - 1. Return |output|. -
+
+Although operations {{MLGraphBuilder/greaterOrEqual}} and {{MLGraphBuilder/lesserOrEqual}} can each be implemented in terms of operations {{MLGraphBuilder/not}}, {{MLGraphBuilder/lesser}}, and {{MLGraphBuilder/greater}} in other words `greater-or-equal(a, b)` is `not(lesser(a, b))`, they are specifically defined for performance reason to avoid double comparisons in each element-wise test. +
-
- The mul(|a|, |b|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-binary-op | create element-wise binary operation=] given "mul", |a| and |b|. - 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. - 1. Return |output|. -
+#### equal #### {#api-mlgraphbuilder-logical-equal} +Compare if the values of the two input tensors are equal, element-wise. See [[#api-mlgraphbuilder-logical]] for more detail. -
- The div(|a|, |b|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-binary-op | create element-wise binary operation=] given "div", |a| and |b|. - 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. - 1. Return |output|. -
+#### greater #### {#api-mlgraphbuilder-logical-greater} +Compare if the values of the first input tensor is greater, element-wise. See [[#api-mlgraphbuilder-logical]] for more detail. -
- The max(|a|, |b|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-binary-op | create element-wise binary operation=] given "max", |a| and |b|. - 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. - 1. Return |output|. -
+#### greaterOrEqual #### {#api-mlgraphbuilder-logical-greater-or-equal} +Compare if the values of the first input tensor is greater or equal, element-wise. See [[#api-mlgraphbuilder-logical]] for more detail. -
- The min(|a|, |b|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-binary-op | create element-wise binary operation=] given "min", |a| and |b|. - 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. - 1. Return |output|. -
+#### lesser #### {#api-mlgraphbuilder-logical-lesser} +Compare if the values of the first input tensor is lesser, element-wise. See [[#api-mlgraphbuilder-logical]] for more detail. -
- The pow(|a|, |b|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-binary-op | create element-wise binary operation=] given "pow", |a| and |b|. - 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. - 1. Return |output|. -
- - +#### lesserOrEqual #### {#api-mlgraphbuilder-logical-lesser-or-equal} +Compare if the values of the first input tensor is lesser or equal, element-wise. See [[#api-mlgraphbuilder-logical]] for more detail. + +#### not #### {#api-mlgraphbuilder-logical-not} +Invert the values of the input tensor to Boolean values 0 or 1, element-wise. See [[#api-mlgraphbuilder-logical]] for more detail. ### Element-wise unary operations ### {#api-mlgraphbuilder-unary} Compute the element-wise unary operation for input tensor. @@ -2505,12 +2375,16 @@ Compute the element-wise unary operation for input tensor. partial interface MLGraphBuilder { MLOperand abs(MLOperand input); MLOperand ceil(MLOperand input); + MLOperand copy(MLOperand input); MLOperand cos(MLOperand input); + MLOperand erf(MLOperand input); MLOperand exp(MLOperand input); MLOperand floor(MLOperand input); MLOperand log(MLOperand input); MLOperand neg(MLOperand input); + MLOperand reciprocal(MLOperand input); MLOperand sin(MLOperand input); + MLOperand sqrt(MLOperand input); MLOperand tan(MLOperand input); }; @@ -2523,26 +2397,12 @@ partial interface MLGraphBuilder { element-wise unary operation of the input tensor. The shape of the output tensor is the same as the shape of input tensor. -
- **Operation types:** - - *abs*: Compute the absolute value of the input tensor, element-wise. - - *ceil*: Compute the ceiling of the input tensor, element-wise. - - *cos*: Compute the cosine of the input tensor, element-wise. - - *exp*: Compute the exponential of the input tensor, element-wise. - - *floor*: Compute the floor of the input tensor, element-wise. - - *log*: Compute the natural logarithm of the input tensor, element-wise. - - *neg*: Compute the numerical negative value of the input tensor, element-wise. - - *sin*: Compute the sine of the input tensor, element-wise. - - *tan*: Compute the tangent of the input tensor, element-wise. -
-
- To create element-wise unary operation given |op| and |input|, run the following steps:
- 1. [=Assert=]: |op| is one of "abs", "ceil", "cos", "exp", "floor", "log", "neg", "sin", "tan". + 1. [=Assert=]: |op| is one of "abs", "ceil", "copy", "cos", "exp", "floor", "log", "neg", "reciprocal", "sin", "sqrt", "tan". 1. [=Assert=]: the type of |input| is {{MLOperand}}. 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. 1. Let |output| be the result of copying an MLOperand given |input|. @@ -2557,77 +2417,46 @@ partial interface MLGraphBuilder {
-
- - The element-wise unary operation algorithms invoke the [=MLGraphBuilder/element-wise-unary-op | create element-wise unary operation=] steps as follows. - -
-
- The abs(|input|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-unary-op | create element-wise unary operation=] given "abs" and |input|. - 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. - 1. Return |output|. -
+#### abs #### {#api-mlgraphbuilder-unary-abs} +Compute the absolute value of the input tensor, element-wise. See [[#api-mlgraphbuilder-unary]] for more detail. -
- The ceil(|input|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-unary-op | create element-wise unary operation=] given "ceil" and |input|. - 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. - 1. Return |output|. -
+#### ceil #### {#api-mlgraphbuilder-unary-ceil} +Compute the ceiling of the input tensor, element-wise. See [[#api-mlgraphbuilder-unary]] for more detail. -
- The cos(|input|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-unary-op | create element-wise unary operation=] given "cos" and |input|. - 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. - 1. Return |output|. -
+#### copy #### {#api-mlgraphbuilder-unary-copy} +Copy the value of the input tensor to the output tensor, element-wise. See [[#api-mlgraphbuilder-unary]] for more detail. -
- The exp(|input|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-unary-op | create element-wise unary operation=] given "exp" and |input|. - 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. - 1. Return |output|. -
+#### cos #### {#api-mlgraphbuilder-unary-cos} +Compute the cosine of the input tensor, element-wise. See [[#api-mlgraphbuilder-unary]] for more detail. -
- The floor(|input|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-unary-op | create element-wise unary operation=] given "floor" and |input|. - 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. - 1. Return |output|. -
+#### erf #### {#api-mlgraphbuilder-unary-erf} +Compute the error function [[Error-Function]] of the input tensor, element-wise. See [[#api-mlgraphbuilder-unary]] for more detail. -
- The log(|input|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-unary-op | create element-wise unary operation=] given "log" and |input|. - 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. - 1. Return |output|. -
+#### exp #### {#api-mlgraphbuilder-unary-exp} +Compute the exponential of the input tensor, element-wise. See [[#api-mlgraphbuilder-unary]] for more detail. -
- The neg(|input|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-unary-op | create element-wise unary operation=] given "neg" and |input|. - 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. - 1. Return |output|. -
+#### floor #### {#api-mlgraphbuilder-unary-floor} +Compute the floor of the input tensor, element-wise. See [[#api-mlgraphbuilder-unary]] for more detail. -
- The sin(|input|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-unary-op | create element-wise unary operation=] given "sin" and |input|. - 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. - 1. Return |output|. -
+#### log #### {#api-mlgraphbuilder-unary-log} +Compute the natural logarithm of the input tensor, element-wise. See [[#api-mlgraphbuilder-unary]] for more detail. -
- The tan(|input|) method steps are: - 1. Let |output| be the result of running the [=MLGraphBuilder/element-wise-unary-op | create element-wise unary operation=] given "tan" and |input|. - 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. - 1. Return |output|. -
-
-
+#### neg #### {#api-mlgraphbuilder-unary-neg} +Compute the numerical negative value of the input tensor, element-wise. See [[#api-mlgraphbuilder-unary]] for more detail. + +#### reciprocal #### {#api-mlgraphbuilder-unary-reciprocal} +Compute the reciprocal of the input tensor, element-wise. See [[#api-mlgraphbuilder-unary]] for more detail. + +#### sin #### {#api-mlgraphbuilder-unary-sin} +Compute the sine of the input tensor, element-wise. See [[#api-mlgraphbuilder-unary]] for more detail. + +#### sqrt #### {#api-mlgraphbuilder-unary-sqrt} +Compute the square root of the input tensor, element-wise. See [[#api-mlgraphbuilder-unary]] for more detail. + +#### tan #### {#api-mlgraphbuilder-unary-tan} +Compute the tangent of the input tensor, element-wise. See [[#api-mlgraphbuilder-unary]] for more detail. -### The elu() method ### {#api-mlgraphbuilder-elu} +### {{MLGraphBuilder/elu}} ### {#api-mlgraphbuilder-elu} Calculate the exponential linear unit function (ELU) on the input tensor element-wise. The calculation follows the expression `max(0, x) + alpha * (exp(min(0, x)) - 1)`. +
+ **Arguments:** + - *input*: an {{MLOperand}}. An input tensor + - *newShape*: a sequence of {{unsigned long}}. The new shape the input tensor is expanded to. + + **Returns:** an {{MLOperand}}. The tensor with expanded size dimensions. +
+ +
+ + The expand(|input|, |newShape|) method steps are: + +
+
+ The permissions and context validity have been checked by [[#api-mlgraphbuilder-constructor]] steps. +
+ 1. [=Assert=]: the type of |input| is {{MLOperand}} object. + 1. [=Assert=]: the type of |newShape| is a `sequence of unsigned long`. + 1. If any of the following steps fail, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |desc| be |input|.{{MLOperand/[[descriptor]]}}. + 1. If the sequence length of |newShape| is greater than the [=rank=] of |desc|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. [=map/For each=] |index| in [=the range=] 0 to the [=rank=] of |input|, exclusive: + 1. Let |size| be |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[index]. + 1. If |size| is not equal to 1 and not equal to |newShape|[index], then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 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 an [=implementation-defined=] platform operator |expandImpl| for this method, given |input| and |newShape|. + 1. Store a reference of |expandImpl| in |output|.{{MLOperand/[[operator]]}}. + 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent output,given |output| and |expandImpl|. + 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. + 1. Connect |input| as input to |expandImpl|. + 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |expandImpl|. + 1. Return |output|. +
+
+ +### {{MLGraphBuilder/gather}} ### {#api-mlgraphbuilder-gather} +Gather values of the input tensor along an axis according to the indices. + + +{{MLGatherOptions}} has the following members: +
+ : axis + :: + An {{unsigned long}} scalar specifying the axis along which the gathered values are obtained. Its value must be in the range [0, N-1] where N is the [=rank=] of the input tensor. +
+ +
+ **Arguments:** + - *input*: an {{MLOperand}}. The input N-D tensor from which the values are gathered. + - *indices*: an {{MLOperand}}. The indices N-D tensor of the input values to gather. The values must be in the range [0, N] where N is the value of the input shape indexed by *options.axis*. + - *options*: an optional {{MLGatherOptions}}. The optional parameters of the operation. + + **Returns:** an {{MLOperand}}. The output N-D tensor of [=rank=] equal to M + N - 1 where M and N are the [=rank=] of the *input* and *indices* tensor respectively. +
+ +
+ + The gather(|input|, |indices|, |options|) method steps are: + +
+ 1. [=Assert=]: the type of |input| and |indices| is {{MLOperand}}. + 1. Let |shapeInput| be |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} and |rankInput| the [=list/size=] of |shapeInput|. + 1. Let |shapeIndices| be |indices|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. + 1. Let |axis| be |options|.{{MLGatherOptions/axis}}. + 1. Let |axisSize| be |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[|axis|] + 1. If |axis| is greater than or equal to |rankInput|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. [=map/For each=] |index| → |value| of |indices|: + 1. If |index| is greater than or equal to |axisSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |dimCount| be zero. + 1. Let |rankOutput| be zero. + 1. Let |shapeOutput| be an empty list. + 1. [=map/For each=] |size| → |value| of |shapeInput|: + 1. If |dimCount| is equal to |axis| then [=break=]. + 1. Set |shapeOutput|[|dimCount|] to |size|. + 1. Increment |dimCount| by one. + 1. Set |rankOutput| to |dimCount|. + 1. Let |dimCount| be zero. + 1. [=map/For each=] |size| → |value| of |shapeIndices|: + 1. Set |shapeOutput|[|rankOutput| + |dimCount|] to |size|. + 1. Increment |dimCount| by one. + 1. Set |rankOutput| to |rankOutput| + |dimCount|. + 1. Let |dimCount| be zero. + 1. [=map/For each=] |size| → |value| of |shapeInput|: + 1. If |dimCount| is less than or equal to |axis| then [=continue=]. + 1. Set |shapeOutput|[|rankOutput| + |dimCount|] to |size|. + 1. Increment |dimCount| by one. + 1. Let |desc| a new {{MLOperandDescriptor}}. + 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to |shapeOutput|. + 1. Set |desc|.{{MLOperandDescriptor/type}} to |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}}. + 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 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 an [=implementation-defined=] platform operator for the Gather operation, given |input|, |indices|, and |options|. + 1. Store a reference of |opImpl| in |output|.{{MLOperand/[[operator]]}}. + 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent the output, given |output| and |opImpl|. + 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. + 1. Connect |input|.{{MLOperand/[[operand]]}} and |indices|.{{MLOperand/[[operand]]}} as inputs to |opImpl|. + 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Return |output|. +
+
+ +
+
+ + Examples of how gather works in different slicing schemes. + +
+    // input of shape [4,3]: [
+    //    [0,1,2], [10,11,12], [20,21,22], [30,31,32]
+    // ]
+    const input = builder.constant(
+    { dimensions: [4,3] }, new Float32Array([0,1,2,10,11,12,20,21,22,30,31,32]));
+
+    const indices1 = builder.constant(
+    { type: 'uint32', dimensions: [2] }, new Uint32Array([3,1]));
+
+    const indices2 = builder.constant(
+    { type: 'uint32', dimensions: [3] }, new Uint32Array([2,1,1]));
+
+    const indices3 = builder.constant(
+    { type: 'uint32', dimensions: [2,2] }, new Uint32Array([0,1,1,2]));
+
+    // axis = 0 (default)
+    // indices of shape [2]: [3,1]
+    // output of shape [2,3]: [
+    //    [30,31,32], [10,11,12]
+    // ]
+    const output1 = builder.gather(input, indices1);
+
+    // axis = 1
+    // indices of shape [3]: [2,1,1]
+    // output of shape [4,3]: [
+    //    [2,1,1], [12,11,11], [22,21,21], [32,31,31]
+    // ]
+    const output2 = builder.gather(input, indices2, { axis: 1 });
+
+    // axis = 1
+    // indices of shape [2,2]: [[0,1], [1,2]]
+    // output of shape [4,2,2]: [
+    //    [[0,1], [1,2]],
+    //    [[10,11], [11,12]],
+    //    [[20,21], [21,22]],
+    //    [[30,31], [31,32]]
+    // ]
+    const output3 = builder.gather(input, indices3, { axis: 1 });
+  
+
+
+ +### {{MLGraphBuilder/gemm}} ### {#api-mlgraphbuilder-gemm} Calculate the [general matrix multiplication of the Basic Linear Algebra Subprograms](https://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms#Level_3). The calculation follows the expression `alpha * A * B + beta * C`, where `A` is a 2-D tensor with shape [M, K] or [K, M], `B` is a 2-D tensor with shape [K, N] or [N, K], and `C` is broadcastable to the shape [M, N]. `A` and `B` may optionally be transposed prior to the calculation. + +The {{MLLayerNormalizationOptions}} members are: +
+ : scale + :: + An {{MLOperand}}. Specifies the N-D tensor of the scaling values whose shape is determined by the |axes| member in that each value in |axes| indicates the dimension of the input tensor with scaling values. For example, for an |axes| values of [1,2,3], the shape of this tensor is the list of the corresponding sizes of the input dimension 1, 2 and 3. When this member is not present, the scaling value is assumed to be 1. + + : bias + :: + An {{MLOperand}}. Specifies the N-D tensor of the bias values whose shape is determined by the |axes| member in that each value in |axes| indicates the dimension of the input tensor with bias values. For example, for an |axes| values of [1,2,3], the shape of this tensor is the list of the corresponding sizes of the input dimension 1, 2 and 3. When this member is not present, the scaling value is assumed to be 0. + + : axes + :: + A sequence of {{unsigned long}}. The indices to the input dimensions to reduce. When this member is not present, it is assumed to be [1,2,3] that is, the reduction for the mean and variance values are calculated across all the input features for each individual sample in the batch. + + : epsilon + :: + A {{float}} scalar. Specifies a small value to prevent computational error due to divide-by-zero. +
+ +
+ **Arguments:** + - *input*: an {{MLOperand}}. The input 4-D tensor. + - *options*: an optional {{MLLayerNormalizationOptions}}. The optional parameters of the operation. + + **Returns:** an {{MLOperand}}. The layer-normalized 4-D tensor of the same shape as *input*. +
+ +
+ + The layerNormalization(|input|, |options|) method steps are: + +
+ 1. [=Assert=]: the type of |input| is {{MLOperand}}. + 1. If the [=rank=] of |input| is not 4, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. [=Assert=]: the type of |options|.{{MLLayerNormalizationOptions/scale}} is {{MLOperand}}. + 1. If the [=rank=] of |options|.{{MLLayerNormalizationOptions/scale}} is not equal to the [=list/size=] of |options|.{{MLBatchNormalizationOptions/axes}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. [=Assert=]: the type of |options|.{{MLLayerNormalizationOptions/bias}} is {{MLOperand}}. + 1. If the [=rank=] of |options|.{{MLLayerNormalizationOptions/bias}} is not equal to the [=list/size=] of |options|.{{MLBatchNormalizationOptions/axes}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 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 an [=implementation-defined=] platform operator for the instance normalization operation, given |options|. + 1. Store a reference of |opImpl| in |output|.{{MLOperand/[[operator]]}}. + 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent the output, given |output| and |opImpl|. + 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. + 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. + 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Return |output|. +
+
+ +
+
+ + The behavior of this operation when the axes parameter is set to [1,2,3] can be generically emulated from + the usage of other operations as follow. However, user agents typically have a more efficient implementation for it, + therefore its usage is encouraged from the performance standpoint. + +
+    // The reduction of the mean and variance values happens over the spatial dimensions 
+    // across all the input features (i.e. all channels) of the input tensor.
+    const reduceOptions = { axes: [1,2,3], keepDimensions: true };
+    const mean = builder.reduceMean(input, reduceOptions);
+    const variance = builder.reduceMean(
+      builder.pow(
+        builder.sub(input, mean),
+        buider.constant(2)),
+      reduceOptions
+      );
+
+    // Returns a new tensor with a dimension of size one inserted at the specified position.
+    function unsqueeze(input, axes) {
+      shape = Array.from(input.shape());
+      for(let axis in axes.sort())
+        shape.splice(axis, 0, 1);
+      return builder.reshape(input, shape);
+    }
+
+    // The scale and bias tensors are of the shape of the input dimensions specified 
+    // by the values in the axes parameter (i.e. [1,2,3]).
+    return builder.add(
+      builder.mul(
+        unsqueeze(options.scale, 0),
+        builder.div(
+          builder.sub(input, mean),
+          buidler.sqrt(builder.add(variance, options.epsilon))
+          )
+        ),
+      unsqueeze(options.bias, 0)
+      );
+  
+
+
+ +### {{MLGraphBuilder/leakyRelu}} ### {#api-mlgraphbuilder-leakyrelu} Calculate the leaky version of rectified linear function on the input tensor element-wise. The calculation follows the expression `max(0, x) + alpha ∗ min(0, x)`. -
- **Arguments:** - - *input*: an {{MLOperand}}. The input 4-D tensor. The logical shape - is interpreted according to the value of *options.layout*. - - *options*: an optional {{MLPool2dOptions}}. The optional parameters of the operation. - - **Returns:** an {{MLOperand}}. The output 4-D tensor that contains the - result of the reduction. The logical shape is interpreted according to the - value of *layout*. More specifically, if the *options.roundingType* is *"floor"*, the spatial dimensions of the output tensor can be calculated as follow: - - *output size = floor(1 + (input size - filter size + beginning padding + ending padding) / stride)* - - or if *options.roundingType* is *"ceil"*: - - *output size = ceil(1 + (input size - filter size + beginning padding + ending padding) / stride)* -
- -
- A *global* pooling operation such as one for the max pooling operation is a variant of pooling where the window dimensions is the spatial dimensions (last two dimensions) of the input shape, as follow. -
-    // 'global' max pooling
-    builder.maxPool2d(input);
-    
-
- {{MLPool2dOptions}} has the following members:
: windowDimensions @@ -4387,11 +4508,34 @@ partial interface MLGraphBuilder { Specifies the sizes of the two spacial dimensions of the output tensor. When the output sizes are explicitly specified, the {{MLPool2dOptions/roundingType}} is ignored. If not specified, the output sizes are automatically computed. -
-
+
+ **Arguments:** + - *input*: an {{MLOperand}}. The input 4-D tensor. The logical shape + is interpreted according to the value of *options.layout*. + - *options*: an optional {{MLPool2dOptions}}. The optional parameters of the operation. + + **Returns:** an {{MLOperand}}. The output 4-D tensor that contains the + result of the reduction. The logical shape is interpreted according to the + value of *layout*. More specifically, if the *options.roundingType* is *"floor"*, the spatial dimensions of the output tensor can be calculated as follow: + + *output size = floor(1 + (input size - filter size + beginning padding + ending padding) / stride)* + + or if *options.roundingType* is *"ceil"*: + + *output size = ceil(1 + (input size - filter size + beginning padding + ending padding) / stride)* +
+ +
+ A *global* pooling operation such as one for the max pooling operation is a variant of pooling where the window dimensions is the spatial dimensions (last two dimensions) of the input shape, as follow. +
+    // 'global' max pooling
+    builder.maxPool2d(input);
+    
+
+
To create pooling operation given |op|, |input| and |options|, run the following steps: @@ -4454,7 +4598,16 @@ partial interface MLGraphBuilder {
-### The prelu() method ### {#api-mlgraphbuilder-prelu} +#### {{MLGraphBuilder/averagePool2d}} #### {#api-mlgraphbuilder-pool2d-average} +Calculate the average value for patches of a feature map, and use it to create a pooled feature map. See [[#api-mlgraphbuilder-pool2d]] for more detail. + +#### {{MLGraphBuilder/l2Pool2d}} #### {#api-mlgraphbuilder-pool2d-l2} +Apply the L2 norm function to a region of the input feature map. The L2 norm is the square root of the sum of the squares of its elements. See [[#api-mlgraphbuilder-pool2d]] for more detail. + +#### {{MLGraphBuilder/maxPool2d}} #### {#api-mlgraphbuilder-pool2d-max} +Calculate the maximum value for patches of a feature map, and use it to create a pooled feature map. See [[#api-mlgraphbuilder-pool2d]] for more detail. + +### {{MLGraphBuilder/prelu}} ### {#api-mlgraphbuilder-prelu} Calculate the parametric version of rectified linear function (Parametric ReLU) on the input tensor element-wise. Parametric ReLU is a type of leaky ReLU that, instead of having a scalar slope like 0.01, making the slope (coefficient of leakage) into a parameter that is learned during the model training phase of this operation. The calculation follows the expression `max(0, x) + slope ∗ min(0, x)`. +{{MLReduceOptions}} has the following members: +
+ : axes + :: + A sequence of {{unsigned long}}. The dimensions to reduce. The values in the sequence must be in the range [0, N-1] where N is the [=rank=] of the input tensor. If not present, all dimensions are reduced. + + : keepDimensions + :: + A {{boolean}}. If true, retains reduced dimensions with [=list/size=] 1. The default value is false. +
+
**Arguments:** - *input*: an {{MLOperand}}. The input tensor. - *options*: an optional {{MLReduceOptions}}. The optional parameters of the operation. - - *axes*: a sequence of {{unsigned long}}. The dimensions to reduce. The values in the sequence must be in the range [0, N-1] where N is the [=rank=] of the input tensor. - If not present, all dimensions are reduced. - - *keepDimensions*: a {{boolean}}. If true, retains reduced dimensions with [=list/size=] 1. - The default value is false. **Returns:** an {{MLOperand}}. The reduced output tensor.
-
- **Reduction types:** - - *L1*: Compute the L1 norm of all the input values along the axes. - - *L2*: Compute the L2 norm of all the input values along the axes. - - *LogSum*: Compute the log value of the sum of all the input values along the axes. - - *LogSumExp*: Compute the log value of the sum of the exponent of all the input values along the axes. - - *Max*: Compute the maximum value of all the input values along the axes. - - *Mean*: Compute the average value of all the input values along the axes. - - *Min*: Compute the minimum value of all the input values along the axes. - - *Product*: Compute the product of all the input values along the axes. - - *Sum*: Compute the sum of all the input values along the axes. - - *SumSquare*: Compute the sum of the square of all the input values along the axes. -
-
- To create reduce operation given |op|, |input| and |options|, run the following steps:
- 1. [=Assert=]: |op| is one of "reduceL1", "reduceL2", "reduceLogSum", "reduceLogSumExp", "reduceMax", "reduceMean", "reduceMin", "reduceProduct", "reduceSum", "reduceSumSquare". + 1. [=Assert=]: |op| is one of "reduceArgMax", "reduceArgMin", "reduceL1", "reduceL2", "reduceLogSum", "reduceLogSumExp", "reduceMax", "reduceMean", "reduceMin", "reduceProduct", "reduceSum", "reduceSumSquare". 1. [=Assert=]: the type of |input| is {{MLOperand}}. 1. If |options|.{{MLReduceOptions/axes}} [=map/exists=], if any of its elements is not in [=the range=] 0 to the [=rank=] of |input|, exclusive, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. @@ -4584,6 +4731,20 @@ partial interface MLGraphBuilder { The following reduce algorithms are supported. +
+ The reduceArgMax(|input|, |options|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/reduce-op | create reduce operation=] given "reduceArgMax", |input| and |options|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. +
+ +
+ The reduceArgMin(|input|, |options|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/reduce-op | create reduce operation=] given "reduceArgMin", |input| and |options|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. +
+
The reduceL1(|input|, |options|) method steps are: 1. Let |output| be the result of running the [=MLGraphBuilder/reduce-op | create reduce operation=] given "reduceL1", |input| and |options|. @@ -4655,7 +4816,43 @@ partial interface MLGraphBuilder {
-### The relu() method ### {#api-mlgraphbuilder-relu-method} +#### reduceArgMax #### {#api-mlgraphbuilder-reduce-argmax} +Return the index location of the maxmium value of all the input values along the axes. See [[#api-mlgraphbuilder-reduce]] for more detail. + +#### reduceArgMin #### {#api-mlgraphbuilder-reduce-argmin} +Return the index location of the minimum value of all the input values along the axes. See [[#api-mlgraphbuilder-reduce]] for more detail. + +#### reduceL1 #### {#api-mlgraphbuilder-reduce-l1} +Compute the L1 norm of all the input values along the axes. See [[#api-mlgraphbuilder-reduce]] for more detail. + +#### reduceL2 #### {#api-mlgraphbuilder-reduce-l2} +Compute the L2 norm of all the input values along the axes. See [[#api-mlgraphbuilder-reduce]] for more detail. + +#### reduceLogSum #### {#api-mlgraphbuilder-reduce-logsum} +Compute the log value of the sum of all the input values along the axes. See [[#api-mlgraphbuilder-reduce]] for more detail. + +#### reduceLogSumExp #### {#api-mlgraphbuilder-reduce-logSumExp} +Compute the log value of the sum of the exponent of all the input values along the axes. See [[#api-mlgraphbuilder-reduce]] for more detail. + +#### reduceMax #### {#api-mlgraphbuilder-reduce-max} +Compute the maximum value of all the input values along the axes. See [[#api-mlgraphbuilder-reduce]] for more detail. + +#### reduceMean #### {#api-mlgraphbuilder-reduce-mean} +Compute the average value of all the input values along the axes. See [[#api-mlgraphbuilder-reduce]] for more detail. + +#### reduceMin #### {#api-mlgraphbuilder-reduce-min} +Compute the minimum value of all the input values along the axes. See [[#api-mlgraphbuilder-reduce]] for more detail. + +#### reduceProduct #### {#api-mlgraphbuilder-reduce-product} +Compute the product of all the input values along the axes. See [[#api-mlgraphbuilder-reduce]] for more detail. + +#### reduceSum #### {#api-mlgraphbuilder-reduce-sum} +Compute the sum of all the input values along the axes. See [[#api-mlgraphbuilder-reduce]] for more detail. + +#### reduceSumSquare #### {#api-mlgraphbuilder-reduce-sumsquare} +Compute the sum of the square of all the input values along the axes. See [[#api-mlgraphbuilder-reduce]] for more detail. + +### {{MLGraphBuilder/relu}} ### {#api-mlgraphbuilder-relu-method} Compute the rectified linear function of the input tensor. - -
- **Arguments:** - - *input*: an {{MLOperand}}. The input tensor. - - *options*: an optional {{MLSqueezeOptions}}. The optional parameters of the operation. - - **Returns:** an {{MLOperand}}. The output tensor of the same or reduced rank with the shape dimensions of size 1 eliminated. -
- -{{MLSqueezeOptions}} has the following members: -
- : axes - :: - A sequence of {{unsigned long}}. - Specifies the indices to the shape dimensions of size 1 to eliminate. The values in the sequence must be in the range [0, N-1] where N is the [=rank=] of the input tensor. - When not specified, every shape dimensions of size 1 in the tensor are eliminated. -
- -
- - - The squeeze(|input|, |options|) method steps are: - -
- 1. [=Assert=]: the type of |input| is {{MLOperand}}. - 1. If |options|.{{MLSqueezeOptions/axes}} [=map/exists=], then: - 1. Let |dimensions| be |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. - 1. Let |axesLength| be the [=list/size=] of |options|.{{MLSqueezeOptions/axes}}. - 1. If |axesLength| is not smaller than the rank of |dimensions|, - 1. For |index| in [=the range=] 0 to |axesLength|, exclusive: - 1. Let |oneDimIndex| be |options|.{{MLSqueezeOptions/axes}}[|index|]. - 1. If |dimensions|[|oneDimIndex|] is not 1, then [=exception/throw=] a {{TypeError}}. - 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. - 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 an [=implementation-defined=] platform operator for the squeeze operation, given |options|. - 1. Store a reference of |opImpl| in |output|.{{MLOperand/[[operator]]}}. - 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent the output, given |output| and |opImpl|. - 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. - 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. - 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. - 1. Return |output|. -
-
- -### The tanh() method ### {#api-mlgraphbuilder-tanh-method} +### {{MLGraphBuilder/tanh}} ### {#api-mlgraphbuilder-tanh-method} Compute the hyperbolic tangent function of the input tensor. The calculation follows the expression `(exp(2 * x) - 1) / (exp(2 * x) + 1)`. + +
+ **Arguments:** + - *condition*: an {{MLOperand}}. The condition tensor. + - *input*: an {{MLOperand}}. The input tensor from which the value is selected when the condition of the corresponding element is set to true. + - *other*: an {{MLOperand}}. The other tensor from which the value is selected when the condition of the corresponding element is set to false. + + **Returns:** an {{MLOperand}}. The output tensor that contains the values selected element-wise from either the input or the other tensor. +
+ +
+ + The where(|condition|, |input|, |other|) method steps are: + +
+ 1. [=Assert=]: the type of |condition|, |input| and |other| is {{MLOperand}}. + 1. If |condition|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}} is not equal to "uint8", then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}} is not equal to |other|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |descriptor| be a new {{MLOperandDescriptor}}. + 1. Set |descriptor|.{{MLOperandDescriptor/type}} to |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}}. + 1. Let |descriptor|.{{MLOperandDescriptor/dimensions}} be the result of running the [=MLGraphBuilder/broadcast-shapes=] steps given |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} and |other|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. + 1. If that [=exception/throws=] an error, re-[=exception/throw=] the error. + 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 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 an [=implementation-defined=] platform operator for |where|, given |condition|, |input| and |other|. + 1. Store a reference of |opImpl| in |output|.{{MLOperand/[[operator]]}}. + 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent the output, given |output| and |opImpl|. + 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. + 1. Connect |condition|.{{MLOperand/[[operand]]}}, |input| and |other|.{{MLOperand/[[operand]]}} as inputs to |opImpl|. + 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Return |output|. +
+
+ +
+
+ + The behavior of this operation can be generically emulated from the usage of other operations as follow. However, user agents typically have a more efficient implementation for it, therefore its usage is encouraged from the performance standpoint. + +
+    builder.add(
+      builder.mul(
+        input,
+        builder.cast(condition, input.type())),
+      builder.mul(
+        other,
+        builder.cast(builder.not(condition), other.type())));
+    
+
+
+ +## {{MLOperand}} interface ## {#api-mloperand} + +An {{MLOperand}} represents an intermediary graph being constructed as a result of compositing parts of an operation into a fully composed operation. + +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: +
+ : \[[builder]] of type {{MLGraphBuilder}} + :: + The {{MLOperand}}'s associated builder object. + + : \[[descriptor]] of type {{MLOperandDescriptor}} + :: + The {{MLOperand}}'s descriptor. + + : \[[name]] of type [=string=] + :: + The {{MLOperand}}'s name (only for input operands). + + : \[[operand]] of type [=object=] + :: + Reference to {{MLOperand}}'s corresponding [=implementation-defined=] platform operand object. + + : \[[operator]] of type [=object=] + :: + Reference to {{MLOperand}}'s corresponding [=implementation-defined=] platform operator object. +
+
+ +
+To get the type of an {{MLOperand}} |operand|, run the following steps: +
+ 1. Return |operand|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}}. +
+
+ +
+To get the shape of an {{MLOperand}} |operand|, run the following steps: +
+ 1. Return |operand|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. +
+
+ +
+To get the rank of an {{MLOperand}} |operand|, run the following steps: +
+ 1. Return the [=list/size=] of |operand|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/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. + +### Creating {{MLOperand}} ### {#api-mloperand-create} +The {{MLOperand}} objects are created by the methods of {{MLGraphBuilder}}, internally using the following algorithms. + +
+ + To create an MLOperand given |builder| and |desc|, run the following steps: + +
+ 1. [=Assert=]: the type of |builder| is {{MLGraphBuilder}}. + 1. [=Assert=]: the type of |desc| is {{MLOperandDescriptor}}. + 1. Let |operand| be a new [=object=]. + 1. Set |operand|.{{MLOperand/[[builder]]}} to |builder|. + 1. Set |operand|.{{MLOperand/[[descriptor]]}} to |desc|. + 1. Return |operand|. +
+
+ +
+ + To copy an MLOperand given |operand|, run the following steps: + +
+ 1. [=Assert=]: the type of |operand| is {{MLOperand}}. + 1. Let |result| be a new [=object=]. + 1. Set |result|.{{MLOperand/[[builder]]}} to |operand|.{{MLOperand/[[builder]]}}. + 1. Set |result|.{{MLOperand/[[descriptor]]}} to |operand|.{{MLOperand/[[descriptor]]}}. + 1. If |operand|.{{MLOperand/[[name]]}} [=map/exists=], then set |result|.{{MLOperand/[[name]]}} to |operand|.{{MLOperand/[[name]]}}. + 1. Return |result|. +
+
+ +
+ + To check dimensions given |dimensions| and |type|, run the following steps: + +
+ 1. If the [=list/size=] of |dimensions| is 0, return false. + 1. If the [=list/size=] of |dimensions| is too large to be supported by the implementation, return false. + 1. If any element of |dimensions| is not a positive number, or it is too large to be supported by the implementation given |type|, return false. + 1. Return true. +
+
+ +
+ + To validate MLOperand given |operand| and |builder|, run the following steps: + +
+ 1. [=Assert=]: the type of |operand|.{{MLOperand/[[builder]]}} is {{MLGraphBuilder}}. + 1. If |builder| is not equal to |operand|.{{MLOperand/[[builder]]}}, return false. + 1. Let |desc| be |operand|.{{MLOperand/[[descriptor]]}}. + 1. If |desc|.{{MLOperandDescriptor/dimensions}} [=map/exists=] and invoking check dimensions given |desc|.{{MLOperandDescriptor/dimensions}} and |desc|.{{MLOperandDescriptor/type}} returns false, then return false. + 1. Return true. +
+
+ +## {{MLOperandDescriptor}} dictionary ## {#api-mloperanddescriptor} + + +
+ + The byte length of an {{MLOperandDescriptor}} |desc| is the value returned by the following steps: + +
+ 1. Let |elementLength| be 1. + 1. [=map/For each=] |dimension| of |desc|.{{MLOperandDescriptor/dimensions}}: + 1. Set |elementLength| to |elementLength| × |dimension|. + 1. Let |elementSize| be the [=element size=] of one of the {{ArrayBufferView}} types that matches |desc|.{{MLOperandDescriptor/type}} according to [this table](#appendices-mloperanddatatype-arraybufferview-compatibility). + 1. Return |elementLength| × |elementSize|. +
+
+ Examples {#examples} ===================== @@ -5539,7 +5937,7 @@ Given the following build graph: const builder = new MLGraphBuilder(context); // Create MLOperandDescriptor object. - const desc = {dataType: 'float32', dimensions: TENSOR_DIMS}; + const desc = {type: 'float32', dimensions: TENSOR_DIMS}; // constant1 is a constant MLOperand with the value 0.5. const constantBuffer1 = new Float32Array(TENSOR_SIZE).fill(0.5); @@ -5911,6 +6309,24 @@ Thanks to Jiewei Qian for Chromium implementation review and feedback. ], "date": "July 2016" }, + "Layer-Normalization": { + "href": "https://arxiv.org/abs/1607.06450", + "title": "Layer Normalization", + "authors": [ + "Jimmy Lei Ba", + "Jamie Ryan Kiros", + "Geoffrey E. Hinton" + ], + "date": "July 2016" + }, + "Error-Function": { + "href": "https://books.google.com/books?id=2CAqsF-RebgC&pg=PA110", + "title": "Special functions of mathematics for engineers", + "authors": [ + "Larry C. Andrews" + ], + "date": "1998" + }, "FaceForensics++": { "href": "https://github.com/ondyari/FaceForensics", "title": "FaceForensics++", @@ -5951,4 +6367,4 @@ Thanks to Jiewei Qian for Chromium implementation review and feedback. ] } } -
+ \ No newline at end of file From 00c355c5ddad3b03e9565e6eb67ce9f383408f14 Mon Sep 17 00:00:00 2001 From: Chai Chaoweeraprasit Date: Fri, 10 Nov 2023 21:26:07 -0800 Subject: [PATCH 02/19] Done. --- index.bs | 232 ++++++++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 194 insertions(+), 38 deletions(-) diff --git a/index.bs b/index.bs index 43a24d83..3908421e 100644 --- a/index.bs +++ b/index.bs @@ -1792,15 +1792,17 @@ partial interface MLGraphBuilder { -### {{MLGraphBuilder/constant}} ### {#api-mlgraphbuilder-constant-method} +### {{MLGraphBuilder/constant}} ### {#api-mlgraphbuilder-constant} Create a constant {{MLOperand}} that can be used in {{MLGraphBuilder}} methods. -#### {{MLGraphBuilder/constant(descriptor, bufferView)}} method #### {#api-mlgraphbuilder-constant} +#### {{MLGraphBuilder/constant(descriptor, bufferView)}} #### {#api-mlgraphbuilder-constant-bufferview} +Create a constant {{MLOperand}} of the specified data type and shape that contains the initializing data. +
**Arguments:** - - *descriptor*: an {{MLOperandDescriptor}} object - - *bufferView*: an {{MLBufferView}} - **Returns:**: an {{MLOperand}} object. + - *descriptor*: an {{MLOperandDescriptor}}. The descriptor of the output tensor. + - *bufferView*: an {{MLBufferView}}. The view of the buffer containing the initializing data. + **Returns:**: an {{MLOperand}}. The constant output tensor.
@@ -1826,13 +1828,18 @@ Create a constant {{MLOperand}} that can be used in {{MLGraphBuilder}} methods.
-#### {{MLGraphBuilder/constant(value, type)}} method #### {#api-mlgraphbuilder-constant-value-type} +#### {{MLGraphBuilder/constant(value, type)}} #### {#api-mlgraphbuilder-constant-value-type} +Create a constant {{MLOperand}} of the specified value and data type. + +
+Data truncation will occur when the specified value exceeds the range of the specified output data type e.g. when a float value is assigned to an *"int8"* data type, etc. +
**Arguments:** - - *value*: a number - - *type*: an optional {{MLOperandDataType}}, by default *"float32"*. - **Returns:**: an {{MLOperand}} object. + - *value*: a {{float}} number. The value of the constant. + - *type*: an optional {{MLOperandDataType}}. If not specified, it is assumed to be *"float32"*. + **Returns:**: an {{MLOperand}}. The constant output.
@@ -1859,6 +1866,49 @@ Create a constant {{MLOperand}} that can be used in {{MLGraphBuilder}} methods.
+#### {{MLGraphBuilder/constant(start, end, step, type)}} #### {#api-mlgraphbuilder-constant-range} +Create a constant {{MLOperand}} of the specified data type and shape that contains the data as specified by the range. + +
+Data truncation will occur when the values in the range exceed the range of the specified output data type e.g. when a float value is assigned to an *"int8"* data type, etc. +
+ +
+ **Arguments:** + - *start*: a {{float}} scalar. The starting value of the range. + - *end*: a {{float}} scalar. The ending value of the range. + - *step*: a {{float}} scalar. The gap value between two data points in the range. + - *type*: an optional {{MLOperandDataType}}. If not specified, it is assumed to be *"float32"*. + **Returns:**: an {{MLOperand}}. The constant 1-D output tensor of size `max(0, ceil((end - start)/step))`. +
+ +
+ + The constant(|start|, |end|, |step|, |type|) method steps are: + +
+
+ The permissions and context validity have been checked by [[#api-mlgraphbuilder-constructor]] steps. +
+ 1. Let |descriptor| be a new {{MLOperandDescriptor}}. + 1. Set |descriptor|.{{MLOperandDescriptor/type}} to |type|. + 1. Let |size| be *max(0, ceil((end - start)/step))*. + 1. Set |descriptor|.{{MLOperandDescriptor/dimensions}} to [|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=] and |descriptor|. + 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/type}}). + 2. Store the beginning address to that memory buffer as a pointer |buffer| of the corresponding data type. + 1. [=map/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 [=implementation-defined=] platform operand |constantImpl| to represent a constant operand, given |descriptor|. + 1. Store a reference of |constantImpl| in |operand|.{{MLOperand/[[operand]]}}. + 1. Register |operand| as a constant with |buffer| as value. + 1. Return |operand|. +
+
+ ### {{MLGraphBuilder/conv2d}} ### {#api-mlgraphbuilder-conv2d} Compute a 2-D convolution given 4-D input and filter tensors -
- **Arguments:** - - *input*: an {{MLOperand}}. The input N-D tensor. - - *options*: an optional {{MLTransposeOptions}}. The optional parameters of the operation. - - **Returns:** an {{MLOperand}}. The permuted or transposed N-D tensor. -
- {{MLTransposeOptions}} has the following members:
: permutation @@ -5659,6 +5705,14 @@ partial interface MLGraphBuilder { These default values cause the output to become a transposed tensor of the input. When specified, the number of values in the sequence must be the same as the [=rank=] of the input tensor, and the values in the sequence must be within the range from 0 to N-1 with no two or more same values found in the sequence.
+
+ **Arguments:** + - *input*: an {{MLOperand}}. The input N-D tensor. + - *options*: an optional {{MLTransposeOptions}}. The optional parameters of the operation. + + **Returns:** an {{MLOperand}}. The permuted or transposed N-D tensor. +
+
The transpose(|input|, |options|) method steps are: @@ -5683,6 +5737,108 @@ partial interface MLGraphBuilder {
+### {{MLGraphBuilder/tri}} ### {#api-mlgraphbuilder-tri} +Given a 2-D tensor (matrix), return a 2-D tensor containing either the upper or lower triangular part of the input tensor. + + + +{{MLTriOptions}} has the following members: +
+ : upper + :: + A {{boolean}} value. Indicate whether the output the upper or the lower part of the input matrix is retained. If not set, it is assumed to be true, indicating that the upper part is retained. + : diagonal + :: + A {{long}} value. Specify how many diagonals above or below the main diagonals of the input matrix are retained or excluded. If not set, this value is assumed to be 0, which means no diagonals other than the main diagonals are affected. +
+ +
+ **Arguments:** + - *input*: an {{MLOperand}}. The input 2-D tensor. + - *options*: an optional {{MLTriOptions}}. The optional parameters of the operation. + + **Returns:** an {{MLOperand}}. The output 2-D tensor representing a triangular matrix. +
+ +
+ + The tri(|input|, |options|) method steps are: + +
+ 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 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 an [=implementation-defined=] platform operator for the tri operation, given |options|. + 1. Store a reference of |opImpl| in |output|.{{MLOperand/[[operator]]}}. + 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent the output, given |output| and |opImpl|. + 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. + 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. + 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Return |output|. +
+
+ +
+
+ + Examples of how tri works in different diagonal settings. + +
+    // input:
+    //   [[7, 1, 2],
+    //    [9, 4, 8],
+    //    [2, 6, 3]]
+    const input = builder.constant(
+    { dimensions: [3,3] }, new Float32Array([7,1,2,9,4,8,2,6,3]));
+
+    // upper triangular matrix:
+    //   [[7, 1, 2], 
+    //    [0, 4, 8],
+    //    [0, 0, 3]]
+    const upper = builder.tri(input);
+
+    // upper triangular matrix with one additional set of diagonals excluded:
+    //   [[0, 1, 2], 
+    //    [0, 0, 8],
+    //    [0, 0, 0]]
+    const upperPositive = builder.tri(input, { diagonal: 1 });
+
+    // upper triangular matrix with one additional set of diagonals retained:
+    //   [[7, 1, 2], 
+    //    [9, 4, 8],
+    //    [0, 6, 3]]
+    const upperNegative = builder.tri(input, { diagonal: -1 });
+
+    // lower triangular matrix:
+    //   [[7, 0, 0],
+    //    [9, 4, 0],
+    //    [2, 6, 3]]
+    const lower = builder.tri(input, { upper: false });
+
+    // lower triangular matrix with one additional set of diagonals retained:
+    //   [[7, 1, 0],
+    //    [9, 4, 8],
+    //    [2, 6, 3]]
+    const lowerPositive = builder.tri(input, { upper: false, diagonal: 1 });
+
+    // lower triangular matrix with one additional set of diagonals excluded:
+    //   [[0, 0, 0],
+    //    [9, 0, 0],
+    //    [2, 6, 0]]
+    const lowerNegative = builder.tri(input, { upper: false, diagonal: -1 });
+  
+
+
+ ### {{MLGraphBuilder/where}} ### {#api-mlgraphbuilder-where} Select the values from the input or the other tensor depending on the corresponding Boolean values of the condition tensor. The condition tensor is often the output of one of the element-wise logical operations. From cfcbca0835031a9dcc7284d1a82db7361166658c Mon Sep 17 00:00:00 2001 From: Chai Chaoweeraprasit Date: Fri, 10 Nov 2023 22:14:58 -0800 Subject: [PATCH 03/19] tri -> triangular --- index.bs | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/index.bs b/index.bs index 3908421e..9cbf2f4a 100644 --- a/index.bs +++ b/index.bs @@ -5737,22 +5737,22 @@ partial interface MLGraphBuilder { -### {{MLGraphBuilder/tri}} ### {#api-mlgraphbuilder-tri} +### {{MLGraphBuilder/triangular}} ### {#api-mlgraphbuilder-triangular} Given a 2-D tensor (matrix), return a 2-D tensor containing either the upper or lower triangular part of the input tensor. -{{MLTriOptions}} has the following members: -
+{{MLTriangularOptions}} has the following members: +
: upper :: A {{boolean}} value. Indicate whether the output the upper or the lower part of the input matrix is retained. If not set, it is assumed to be true, indicating that the upper part is retained. @@ -5764,20 +5764,20 @@ partial interface MLGraphBuilder {
**Arguments:** - *input*: an {{MLOperand}}. The input 2-D tensor. - - *options*: an optional {{MLTriOptions}}. The optional parameters of the operation. + - *options*: an optional {{MLTriangularOptions}}. The optional parameters of the operation. **Returns:** an {{MLOperand}}. The output 2-D tensor representing a triangular matrix.
- The tri(|input|, |options|) method steps are: + The triangular(|input|, |options|) method steps are:
1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. 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 an [=implementation-defined=] platform operator for the tri operation, given |options|. + 1. Let |opImpl| be an [=implementation-defined=] platform operator for the triangular operation, given |options|. 1. Store a reference of |opImpl| in |output|.{{MLOperand/[[operator]]}}. 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent the output, given |output| and |opImpl|. 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. @@ -5790,7 +5790,7 @@ partial interface MLGraphBuilder {
- Examples of how tri works in different diagonal settings. + Examples of how triangular works in different diagonal settings.
     // input:
@@ -5804,37 +5804,37 @@ partial interface MLGraphBuilder {
     //   [[7, 1, 2], 
     //    [0, 4, 8],
     //    [0, 0, 3]]
-    const upper = builder.tri(input);
+    const upper = builder.triangular(input);
 
     // upper triangular matrix with one additional set of diagonals excluded:
     //   [[0, 1, 2], 
     //    [0, 0, 8],
     //    [0, 0, 0]]
-    const upperPositive = builder.tri(input, { diagonal: 1 });
+    const upperPositive = builder.triangular(input, { diagonal: 1 });
 
     // upper triangular matrix with one additional set of diagonals retained:
     //   [[7, 1, 2], 
     //    [9, 4, 8],
     //    [0, 6, 3]]
-    const upperNegative = builder.tri(input, { diagonal: -1 });
+    const upperNegative = builder.triangular(input, { diagonal: -1 });
 
     // lower triangular matrix:
     //   [[7, 0, 0],
     //    [9, 4, 0],
     //    [2, 6, 3]]
-    const lower = builder.tri(input, { upper: false });
+    const lower = builder.triangular(input, { upper: false });
 
     // lower triangular matrix with one additional set of diagonals retained:
     //   [[7, 1, 0],
     //    [9, 4, 8],
     //    [2, 6, 3]]
-    const lowerPositive = builder.tri(input, { upper: false, diagonal: 1 });
+    const lowerPositive = builder.triangular(input, { upper: false, diagonal: 1 });
 
     // lower triangular matrix with one additional set of diagonals excluded:
     //   [[0, 0, 0],
     //    [9, 0, 0],
     //    [2, 6, 0]]
-    const lowerNegative = builder.tri(input, { upper: false, diagonal: -1 });
+    const lowerNegative = builder.triangular(input, { upper: false, diagonal: -1 });
   
From 9ab86c2f9744e8de59541a08a01c08011ca3404a Mon Sep 17 00:00:00 2001 From: Chai Chaoweeraprasit Date: Fri, 10 Nov 2023 23:13:28 -0800 Subject: [PATCH 04/19] Fix Bikeshed link errors. --- index.bs | 92 ++++++++++++++++++++++++++++---------------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/index.bs b/index.bs index 9cbf2f4a..1e1e0a4d 100644 --- a/index.bs +++ b/index.bs @@ -1439,7 +1439,7 @@ Both {{MLGraphBuilder}}.{{MLGraphBuilder/build()}} and {{MLGraphBuilder}}.{{MLGr
-### {{MLGraphBuilder/batchNormalization}} ### {#api-mlgraphbuilder-batchnorm} +### batchNormalization ### {#api-mlgraphbuilder-batchnorm} Normalize the values of the input tensor using [[Batch-Normalization]]. For each input feature, the mean and variance values of that feature are computed across all the samples in the batch dimension while the model is trained. These mean and variance values are then subsequently given to this operation during model inference. + ## {{ML}} interface ## {#api-ml} + +{{MLArgMinMaxOptions}} has the following members: +
+ : axes + :: + A sequence of {{unsigned long}}. The dimensions to reduce. The values in the sequence must be in the range [0, N-1] where N is the [=rank=] of the input tensor. If not present, all dimensions are reduced. + + : keepDimensions + :: + A {{boolean}}. If true, retains reduced dimensions with [=list/size=] 1. The default value is false. +
+ +
+ **Arguments:** + - *input*: an {{MLOperand}}. The input N-D tensor. + - *options*: an optional {{MLArgMinMaxOptions}}. The optional parameters of the operation. + + **Returns:** an {{MLOperand}}. The N-D tensor of the reduced shape. The values must be of type "uint32" in the range [0, N-1] where N is the corresponding size of each of the input dimensions specified by options.axes. +
+ +
+ + To create argMin/argMax operation given |op|, |input| and |options|, run the following steps: + +
+ 1. [=Assert=]: |op| is one of "argMin", "argMax". + 1. [=Assert=]: the type of |input| is {{MLOperand}}. + 1. If |options|.{{MLArgMinMaxOptions/axes}} [=map/exists=], if any of its elements is not in [=the range=] 0 to the [=rank=] of |input|, exclusive, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |outputShape| be the result of invoking the underlying implementation for calculating reduction output dimensions, given |options|. + 1. Let |desc| be a new {{MLOperandDescriptor}}. + 1. Set |desc|.{{MLOperandDescriptor/dataType}} to "uint32". + 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to |outputShape|. + 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 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 an [=implementation-defined=] platform operator for the |op| argMin or argMax operation, given |options|. + 1. Store a reference of |opImpl| in |output|.{{MLOperand/[[operator]]}}. + 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent the output, given |output| and |opImpl|. + 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. + 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. + 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Return |output|. +
+
+ +
+ + The following argMin/argMax algorithms are supported. + +
+ The argMin(|input|, |options|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/argminmax-op | create argMin/argMax operation=] given "argMin", |input| and |options|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. +
+ +
+ The argMax(|input|, |options|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/argminmax-op | create argMin/argMax operation=] given "argMax", |input| and |options|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. +
+
+ ### batchNormalization ### {#api-mlgraphbuilder-batchnorm} Normalize the values of the input tensor using [[Batch-Normalization]]. For each input feature, the mean and variance values of that feature are computed across all the samples in the batch dimension while the model is trained. These mean and variance values are then subsequently given to this operation during model inference. @@ -2902,13 +2980,13 @@ partial interface MLGraphBuilder { { dimensions: [4,3] }, new Float32Array([0,1,2,10,11,12,20,21,22,30,31,32])); const indices1 = builder.constant( - { type: 'uint32', dimensions: [2] }, new Uint32Array([3,1])); + { dataType: 'uint32', dimensions: [2] }, new Uint32Array([3,1])); const indices2 = builder.constant( - { type: 'uint32', dimensions: [3] }, new Uint32Array([2,1,1])); + { dataType: 'uint32', dimensions: [3] }, new Uint32Array([2,1,1])); const indices3 = builder.constant( - { type: 'uint32', dimensions: [2,2] }, new Uint32Array([0,1,1,2])); + { dataType: 'uint32', dimensions: [2,2] }, new Uint32Array([0,1,1,2])); // axis = 0 (default) // indices of shape [2]: @@ -3166,7 +3244,7 @@ partial interface MLGraphBuilder { let hiddenState = options.initialHiddenState; if (!hiddenState) { - const desc = { type: 'float32', dimensions: [numDirections, 1, hiddenSize] }; + const desc = { dataType: 'float32', dimensions: [numDirections, 1, hiddenSize] }; const totalSize = numDirections * hiddenSize; hiddenState = builder.constant(desc, new Float32Array(totalSize).fill(0)); } @@ -4170,13 +4248,13 @@ partial interface MLGraphBuilder { let cellState = options.initialCellState; if (!hiddenState) { - const desc = { type: 'float32', dimensions: [numDirections, 1, hiddenSize] }; + const desc = { dataType: 'float32', dimensions: [numDirections, 1, hiddenSize] }; const totalSize = numDirections * hiddenSize; hiddenState = builder.constant(desc, new Float32Array(totalSize).fill(0)); } if (!cellState) { - const desc = { type: 'float32', dimensions: [numDirections, 1, hiddenSize] }; + const desc = { dataType: 'float32', dimensions: [numDirections, 1, hiddenSize] }; const totalSize = numDirections * hiddenSize; cellState = builder.constant(desc, new Float32Array(totalSize).fill(0)); } @@ -4617,7 +4695,7 @@ partial interface MLGraphBuilder {
     // input: [[1,2,3], [4,5,6]]
     const input = builder.constant(
-      { type: 'float32', dimensions: [2,3] }, new Float32Array([1,2,3,4,5,6]));
+      { dataType: 'float32', dimensions: [2,3] }, new Float32Array([1,2,3,4,5,6]));
 
     const beginningPadding = [1,2];
     const endingPadding = [1,2];
@@ -4654,7 +4732,7 @@ partial interface MLGraphBuilder {
 
 
 ### Pooling operations ### {#api-mlgraphbuilder-pool2d}
-Compute a reduction operation across all the elements within the moving window over the input tensor. See the description of each type of reduction in [[#api-mlgraphbuilder-reduce]].
+Compute a pooling operation across all the elements within the moving window over the input tensor.
 
@@ -6241,7 +6305,7 @@ Given the following build graph:
     const builder = new MLGraphBuilder(context);
 
     // Create MLOperandDescriptor object.
-    const desc = {type: 'float32', dimensions: TENSOR_DIMS};
+    const desc = {dataType: 'float32', dimensions: TENSOR_DIMS};
 
     // constant1 is a constant MLOperand with the value 0.5.
     const constantBuffer1 = new Float32Array(TENSOR_SIZE).fill(0.5);

From 06bdb0a85ac0179146397183adf45a74edb450c7 Mon Sep 17 00:00:00 2001
From: Chai Chaoweeraprasit 
Date: Tue, 5 Dec 2023 11:53:28 -0800
Subject: [PATCH 12/19] add 'be'

---
 index.bs | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/index.bs b/index.bs
index 3523c206..98f4960b 100644
--- a/index.bs
+++ b/index.bs
@@ -2924,7 +2924,7 @@ partial interface MLGraphBuilder {
   
   
1. [=Assert=]: the type of |input| and |indices| is {{MLOperand}}. - 1. Let |shapeInput| be |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} and |rankInput| the [=list/size=] of |shapeInput|. + 1. Let |shapeInput| be |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} and |rankInput| be the [=list/size=] of |shapeInput|. 1. Let |shapeIndices| be |indices|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. 1. Let |axis| be |options|.{{MLGatherOptions/axis}}. 1. Let |axisSize| be |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[|axis|] From b491f795d02f691b102af734ca6a226d2d824201 Mon Sep 17 00:00:00 2001 From: Chai Chaoweeraprasit Date: Tue, 5 Dec 2023 16:02:08 -0800 Subject: [PATCH 13/19] Add dfn for MLOperand.shape() and .dataType(). Fix argMin/Max return type. --- index.bs | 75 +++++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 58 insertions(+), 17 deletions(-) diff --git a/index.bs b/index.bs index 98f4960b..733b8746 100644 --- a/index.bs +++ b/index.bs @@ -1459,6 +1459,7 @@ Return the index location of the minium or maxmium values of all the input value dictionary MLArgMinMaxOptions { sequence axes = null; boolean keepDimensions = false; + boolean selectLastIndex = false; }; partial interface MLGraphBuilder { @@ -1476,6 +1477,10 @@ partial interface MLGraphBuilder { : keepDimensions :: A {{boolean}}. If true, retains reduced dimensions with [=list/size=] 1. The default value is false. + + : selectLastIndex + :: + A {{boolean}}. If true, select the last index instead of the first found along the axes. The default value is false.
@@ -1483,7 +1488,7 @@ partial interface MLGraphBuilder { - *input*: an {{MLOperand}}. The input N-D tensor. - *options*: an optional {{MLArgMinMaxOptions}}. The optional parameters of the operation. - **Returns:** an {{MLOperand}}. The N-D tensor of the reduced shape. The values must be of type "uint32" in the range [0, N-1] where N is the corresponding size of each of the input dimensions specified by options.axes. + **Returns:** an {{MLOperand}}. The N-D tensor of the reduced shape. The values must be of type "int64" in the range [0, N-1] where N is the corresponding size of each of the input dimensions specified by options.axes.
@@ -1496,7 +1501,7 @@ partial interface MLGraphBuilder { 1. If |options|.{{MLArgMinMaxOptions/axes}} [=map/exists=], if any of its elements is not in [=the range=] 0 to the [=rank=] of |input|, exclusive, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. Let |outputShape| be the result of invoking the underlying implementation for calculating reduction output dimensions, given |options|. 1. Let |desc| be a new {{MLOperandDescriptor}}. - 1. Set |desc|.{{MLOperandDescriptor/dataType}} to "uint32". + 1. Set |desc|.{{MLOperandDescriptor/dataType}} to "int64". 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to |outputShape|. 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. 1. Let |output| be the result of creating an MLOperand given [=this=] and |desc|. @@ -2505,8 +2510,7 @@ partial interface MLGraphBuilder { - *a*: an {{MLOperand}}. The first input tensor. - *b*: an {{MLOperand}}. The second input tensor when specified. - **Returns:** an {{MLOperand}}. The output tensor that contains the result of - element-wise comparison of the two input tensors. + **Returns:** an {{MLOperand}}. The output tensor that contains the result of element-wise comparison of the two input tensors.
**Operation types:** @@ -2529,7 +2533,10 @@ Although operations *greaterOrEqual* and *lesserOrEqual* can each be implemented
1. [=Assert=]: |op| is one of "equal", "greater", "greaterOrEqual", "lesser", "lesserOrEqual", "not". 1. [=Assert=]: the type of |a| and |b| if available is {{MLOperand}}. - 1. If either |a|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}} or |b|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}} (when available) isn't "uint8", then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |op| is "not". + 1. If |a|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}} isn't "uint8", then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |op| is anything else but "not". + 1. If |a|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}} is not equal to |b|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. Let |descriptor| be a new {{MLOperandDescriptor}}. 1. Set |descriptor|.{{MLOperandDescriptor/dataType}} to "uint8". 1. Let |descriptor|.{{MLOperandDescriptor/dimensions}} be the result of running the [=MLGraphBuilder/broadcast-shapes=] steps given |a|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} and |b|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. @@ -2874,7 +2881,7 @@ partial interface MLGraphBuilder { 1. If the sequence length of |newShape| is not equal to the [=rank=] of |inputDesc|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. Let |outputDesc| be a copy of |inputDesc|. 1. [=map/For each=] |index| in [=the range=] 0 to the [=rank=] of |input|, exclusive: - 1. Let |size| be the [=operand-shape=][|index|] of |input|. + 1. Let |size| be the |input|.{{MLOperand/shape()}}[|index|]. 1. If |size| is not equal to 1 and not equal to |newShape|[index], then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. If |size| is equal to 1, then let |outputDesc|.{{MLOperandDescriptor/dimensions}}[|index|] be |newShape|[|index|]. 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. @@ -6129,10 +6136,7 @@ For instance, an {{MLOperand}} may represent a constant feeding to an operation
@@ -6160,13 +6164,6 @@ interface MLOperand {
-
-To get the operand-shape of an {{MLOperand}} |operand|, run the following steps: -
- 1. Return |operand|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. -
-
-
To get the rank of an {{MLOperand}} |operand|, run the following steps:
@@ -6232,6 +6229,50 @@ The {{MLOperand}} objects are created by the methods of {{MLGraphBuilder}}, inte
+### dataType ### {#api-mloperand-datatype} +Return a data type of the {{MLOperand}}. + + + +
+ **Returns:** an {{MLOperandDataType}}. The data type of the operand. +
+ +
+ + The dataType() method steps are: + +
+ 1. Return [=this=].{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}}. +
+
+ +### shape ### {#api-mloperand-shape} +Return a shape of the {{MLOperand}}. + + + +
+ **Returns:** a sequence of {{unsigned long}}. The shape of the operand. +
+ +
+ + The shape() method steps are: + +
+ 1. Return [=this=].{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. +
+
+ ## {{MLOperandDescriptor}} dictionary ## {#api-mloperanddescriptor}