diff --git a/index.bs b/index.bs index dc91c019..4714113a 100644 --- a/index.bs +++ b/index.bs @@ -39,49 +39,15 @@ Status Text:

-urlPrefix: https://gpuweb.github.io/gpuweb/; spec: WEBGPU
-    type: interface
-        text: GPUDevice; url: gpu-device
-        text: GPUBuffer; url: buffer-interface
-        for: GPUBuffer; text: size; url: dom-gpubuffer-size
-        text: GPUTexture; url: texture-interface
-        text: GPUQueue; url: queues
-        text: GPUCommandBuffer; url: command-buffers
-        text: GPUCommandBufferDescriptor; url: dictdef-gpucommandbufferdescriptor
 urlPrefix: https://tc39.es/ecma262/; spec: ECMA-262
     type: dfn
         text: element size; url: table-the-typedarray-constructors
         text: element type; url: table-the-typedarray-constructors
         text: view constructor; url: table-the-typedarray-constructors
-        text: Construct; url: sec-construct
-urlPrefix: https://webidl.spec.whatwg.org/; spec: WEBIDL
-    type: interface
-        text: Promise; url: idl-promise
-        text: nullable; url: idl-nullable-type
-    type: dfn
-        text: underlying buffer; url: buffersource-underlying-buffer
-        text: buffer byte length; url: buffersource-byte-length
 urlPrefix: https://tc39.es/proposal-float16array/; spec: float16array
     type: interface
         text: Float16Array; url: sec-float16array
 
-
-{
-	"WEBGPU": {
-		"authors": [
-			"Dzmitry Malyshau",
-			"Kai Ninomiya"
-		],
-		"href": "https://gpuweb.github.io/gpuweb/",
-		"title": "WebGPU",
-		"status": "ED",
-		"publisher": "W3C",
-		"deliveredBy": [
-			"https://www.w3.org/2020/gpu/"
-		]
-	}
-}
-
+ + + +
+ + To check clamp options given |options|, run the following steps: + +
+ 1. If |options|.{{MLClampOptions/minValue}} is greater than |options|.{{MLClampOptions/maxValue}}, then return false. + 1. Return true. +
+
+ +#### The {{MLGraphBuilder/clamp(operand, options)}} method #### {#api-mlgraphbuilder-clamp-operand-options} +
+ **Arguments:** + - *operand*: 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. + **Returns:** + - an {{MLOperand}}. The output tensor of the same shape as *operand*. +
+ +
+ + + The clamp(|operand|, |options|) method steps are: + +
+ 1. [=Assert=]: the type of |operand| 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. 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 |output|.{{MLOperand/[[operand]]}} as output to |clampImpl|. + 1. Return |output|. +
+
+ +#### The {{MLGraphBuilder/clamp(options)}} method #### {#api-mlgraphbuilder-clamp-options} +
+ **Arguments:** + - *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. + **Returns:** + - an {{MLActivation}}. The operator representing the clamp operation.
+
+ + + The clamp(|options|) method steps are: + +
+ 1. If running the check clamp options steps given |options| returns false, then [=exception/throw=] a {{TypeError}}. + 1. Let |op| be the result of creating an MLActivation given [=this=], `"clamp"` and |options|. + 1. If that [=exception/throws=] an error, re-[=exception/throw=] the error. + 1. Return |op|. +
+
+ ### The concat() method ### {#api-mlgraphbuilder-concat} Concatenates the input tensors along a given axis. -
+
**Arguments:** - *inputs*: a sequence of {{MLOperand}}. All input tensors must have the same shape, except for the size of the dimension to concatenate on. - - *axis*: an {{unsigned long}} scalar. The axis that the inputs concatenate along. Its value must be in the range [0, N-1] where N is the rank of input tensors. + - *axis*: an {{unsigned long}} scalar. The axis that the inputs concatenate along. Its value must be in the range [0, N-1] where N is the [=rank=] of the input tensors. **Returns:** an {{MLOperand}}. The concatenated tensor of all the inputs along the *axis*. The output tensor has the same shape except on the dimension @@ -1409,10 +1975,50 @@ partial interface MLGraphBuilder { computed as the sum of all the input sizes of the same dimension.
-### The conv2d() method ### {#api-mlgraphbuilder-conv2d} -Compute a 2-D convolution given 4-D input and filter tensors - -
- **Arguments:** - - *input*: an {{MLOperand}}. The input 4-D tensor. The logical shape - is interpreted according to the value of *options.inputLayout*. - - *filter*: an {{MLOperand}}. The filter 4-D tensor. The logical shape is - interpreted according to the value of *options.filterLayout* and *options.groups*. - - *options*: an optional {{MLConv2dOptions}}. The optional parameters of the operation. - - *padding*: a sequence of {{unsigned long}} of length 4. The additional rows and columns added to the beginning and ending of each spatial dimension of *input*, [beginning_height, ending_height, beginning_width, ending_width]. If not present, the values are assumed to be [0,0,0,0]. - - *strides*: a sequence of {{unsigned long}} of length 2. The stride of the sliding window for each spatial dimension of *input*, [stride_height, stride_width]. If not present, the values are assumed to be [1,1]. - - *dilations*: a sequence of {{unsigned long}} of length 2. The dilation factor for each spatial dimension of *input*, [dilation_height, dilation_width]. If not present, the values are assumed to be [1,1]. - - *autoPad*: an {{MLAutoPad}}. The automatic input padding options. By default, this argument is set to *"explicit"*, which means that the values in the *options.padding* array should be used for input padding. When the option is set other than *"explicit"*, the values in the *options.padding* array are ignored. With the *"same-upper"* option, the padding values are automatically computed such that the additional ending padding of the spatial input dimensions would allow all of the input values in the corresponding dimension to be filtered. The *"same-lower"* option is similar but padding is applied to the beginning padding of the spatial input dimensions instead of the ending one. - - *groups*: an {{unsigned long}} scalar. The number of groups that input channels and output channels are divided into, default to 1. - - *inputLayout*: an {{MLInputOperandLayout}}. The default value is *"nchw"*. This option specifies the layout format of the input and output tensor as follow: - "nchw": - - input tensor: [batches, input_channels, height, width] - - output tensor: [batches, output_channels, height, width] +{{MLConv2dOptions}} has the following members: +
+ : padding + :: + A sequence of {{unsigned long}} of length 4: [beginningHeight, endingHeight, beginningWidth, endingWidth]. + Specifies the additional rows and columns added to the beginning and ending of each spatial dimension of the convolution input. + The default value is [0, 0, 0, 0]. - "nhwc": - - input tensor: [batches, height, width, input_channels] - - output tensor: [batches, height, width, output_channels] + : strides + :: + A sequence of {{unsigned long}} of length 2: [strideHeight, strideWidth]. + Specifies the stride of the sliding window for each spatial dimension of the convolution input. + The default value is [1, 1]. - - *filterLayout*: an {{MLConv2dFilterOperandLayout}}. The default value is *"oihw"*. This option specifies the layout format of the filter tensor as follow: + : dilations + :: + A sequence of {{unsigned long}} of length 2: [dilationHeight, dilationWidth]. Specifies the dilation factor for each spatial dimension applied on the convolution filter (kernel). + The default value is [1, 1]. - "oihw": - - [output_channels, input_channels/groups, height, width] + : autoPad + :: + An {{MLAutoPad}} [=string=]. + Specifies the automatic input padding options. + The default value is *"explicit"*, which means that the values in the {{MLConv2dOptions/padding}} array should be used for input padding. + When the option is set other than *"explicit"*, the values in the {{MLConv2dOptions/padding}} array are ignored. - "hwio": - - [height, width, input_channels/groups, output_channels] + With the *"same-upper"* option, the padding values are automatically computed such that the additional ending padding of the spatial input dimensions would allow all of the input values in the corresponding dimension to be filtered. - "ohwi": - - [output_channels, height, width, input_channels/groups] + The *"same-lower"* option is similar but padding is applied to the beginning padding of the spatial input dimensions instead of the ending one. - "ihwo": - - [input_channels/groups, height, width, output_channels] + : groups + :: + An {{unsigned long}} scalar. + Specifies the number of groups that input channels and output channels are divided into. + The default value is 1. - - *bias*: an {{MLOperand}}. The additional 1-D tensor with the shape of [output_channels] whose values are to be added to the convolution result. - - *activation*: an {{MLActivation}}. The optional activation function that immediately follows the convolution operation. + : inputLayout + :: + An {{MLInputOperandLayout}} [=string=]. + Specifies the layout format of the input and output tensor as follows: + - **"nchw"** + - input tensor: *[batches, inputChannels, height, width]* + - output tensor: *[batches, outputChannels, height, width]* + - **"nhwc"**: + - input tensor: *[batches, height, width, inputChannels]* + - output tensor: *[batches, height, width, outputChannels]* + The default value is *"nchw"*. + + : filterLayout + :: + An {{MLConv2dFilterOperandLayout}} [=string=]. + Specifies the layout format of the filter tensor as follow: + - **"oihw"**: *[outputChannels, inputChannels/groups, height, width]* + - **"hwio"**: *[height, width, inputChannels/groups, outputChannels]* + - **"ohwi"**: *[outputChannels, height, width, inputChannels/groups]* + - **"ihwo"**: *[inputChannels/groups, height, width, outputChannels]* + The default value is *"oihw"*. + + : bias + :: + An {{MLOperand}} object. + Specifies the additional 1-D tensor with the shape of *[outputChannels]* whose values are to be added to the convolution result. - **Returns:** an {{MLOperand}}. The output 4-D tensor that contains the convolution result. The output shape is interpreted according to the *options.inputLayout* value. More specifically, the spatial dimensions or the sizes of the last two dimensions of the output tensor for the *nchw* input layout can be calculated as follow: + : activation + :: + An {{MLActivation}} object. + Specifies the optional activation function that immediately follows the convolution operation. +
- *output size = 1 + (input size - (filter size - 1) ** *dilation - 1 + beginning padding + ending padding) / stride* +
+ **Arguments:** + - *input*: an {{MLOperand}}. The input 4-D tensor. The logical shape + is interpreted according to the value of *options*.{{MLConv2dOptions/inputLayout}}. + - *filter*: an {{MLOperand}}. The filter 4-D tensor. The logical shape is + interpreted according to the value of *options*.{{MLConv2dOptions/filterLayout}} and *options*.{{MLConv2dOptions/groups}}. + - *options*: an {{MLConv2dOptions}}. The optional parameters of the operation. -
- A *depthwise* conv2d operation is a variant of grouped convolution, used in models like the MobileNet, where the *options.groups* = input_channels = output_channels and the shape of filter tensor is [options.groups, 1, height, width] + **Returns:** an {{MLOperand}}. The output 4-D tensor that contains the convolution result. The output shape is interpreted according to the *options*.{{MLConv2dOptions/inputLayout}} value. More specifically, the spatial dimensions or the sizes of the last two dimensions of the output tensor for the *nchw* input layout can be calculated as follow: + + *outputSize = 1 + (inputSize - (filterSize - 1) ** *dilation - 1 + beginningPadding + endingPadding) / stride* +
+ +
+ A *depthwise* conv2d operation is a variant of grouped convolution, used in models like the MobileNet, where the *options.groups* = inputChannels = outputChannels and the shape of filter tensor is [options.groups, 1, height, width] for *"oihw"* layout, [height, width, 1, options.groups] for *"hwio"* layout, [options.groups, height, width, 1] for *"ohwi"* layout and [1, height, width, options.groups] for *"ihwo"* layout. -
+
+ + + The conv2d(|input|, |filter|, |options|) method steps are: + +
+ 1. [=Assert=]: the type of |input| and |filter| is {{MLOperand}}. + 1. Let |inputSize| be the [=list/size=] of |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. + 1. Let |filterSize| be the [=list/size=] of |filter|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. + 1. If |inputSize| is not 4, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |filterSize| is not 4, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}} is not the same as |filter|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}}, then [=exception/throw=] a {{TypeError}}. + 1. If |options|.{{MLConv2dOptions/padding}} does not [=map/exist=], set it to `« 0, 0, 0, 0 »`. + 1. Else if the [=list/size=] of |options|.{{MLConv2dOptions/padding}} is not 4, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLConv2dOptions/strides}} does not [=map/exist=], set it to `« 1, 1 »`. + 1. Else if the [=list/size=] of |options|.{{MLConv2dOptions/strides}} is not 2, then [=exception/throw=] a {{TypeError}}. + 1. If any element in |options|.{{MLConv2dOptions/strides}} is equal to 0, then [=exception/throw=] a {{TypeError}}. + 1. If |options|.{{MLConv2dOptions/dilations}} does not [=map/exist=], set it to `« 1, 1 »`. + 1. Else if the [=list/size=] of |options|.{{MLConv2dOptions/dilations}} is not 2, then [=exception/throw=] a {{TypeError}}. + 1. If |options|.{{MLConv2dOptions/autoPad}} does not [=map/exist=], set it to `"explicit"`. + 1. If |options|.{{MLConv2dOptions/groups}} is 0, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |inputSize| / |options|.{{MLConv2dOptions/groups}} is not equal to |filterSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Else if |inputSize| % |options|.{{MLConv2dOptions/groups}} is not 0, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLConv2dOptions/bias}} [=map/exists=]: + 1. [=Assert=]: the type of |options|.{{MLConv2dOptions/bias}} is {{MLOperand}}. + 1. If the [=list/size=] of |options|.{{MLConv2dOptions/bias}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} is not 1, then [=exception/throw=] a {{TypeError}}. + 1. If |options|.{{MLConv2dOptions/bias}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}} is not the same as |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}}, then [=exception/throw=] a {{TypeError}}. + 1. If |options|.{{MLConv2dOptions/activation}} [=map/exists=]: + 1. [=Assert=]: the type of |options|.{{MLConv2dOptions/activation}} is {{MLActivation}}. + 1. Let |outputShape| be the result of invoking the underlying implementation for calculating output dimensions, given |options|. + 1. If |outputShape| is not the same as the shape of |options|.{{MLConv2dOptions/bias}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |desc| a new {{MLOperandDescriptor}}. + 1. Set |desc|.{{MLOperandDescriptor/type}} to |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}}. + 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. Create an [=implementation-defined=] platform operator |conv2dImpl| for this method, given |options| and |filter|. + 1. If |options|.{{MLConv2dOptions/activation}} [=map/exists=],register it as activation to |conv2dImpl|. + 1. Store a reference of |conv2dImpl| in |output|.{{MLOperand/[[operator]]}}. + 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent the output, given |output| and |conv2dImpl|. + 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. + 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |conv2dImpl|. + 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |conv2dImpl|. + 1. Return |output|. +
+
+ ### The convTranspose2d() method ### {#api-mlgraphbuilder-convtranspose2d} Compute a 2-D transposed convolution given 4-D input and filter tensors -
- **Arguments:** - - *input*: an {{MLOperand}}. The input 4-D tensor. The logical shape - is interpreted according to the value of *options.inputLayout*. - - *filter*: an {{MLOperand}}. The filter 4-D tensor. The logical shape is - interpreted according to the value of *options.filterLayout* and *options.groups*. - - *options*: an optional {{MLConvTranspose2dOptions}}. The optional parameters of the operation. - - *padding*: a sequence of {{unsigned long}} of length 4. The additional rows and columns added to the beginning and ending of each spatial dimension of *input*, [beginning_height, ending_height, beginning_width, ending_width]. If not present, the values are assumed to be [0,0,0,0]. - - *strides*: a sequence of {{unsigned long}} of length 2. The stride of the sliding window for each spatial dimension of *input*, [stride_height, stride_width]. If not present, the values are assumed to be [1,1]. - - *dilations*: a sequence of {{unsigned long}} of length 2. The dilation factor for each spatial dimension of *input*, [dilation_height, dilation_width]. If not present, the values are assumed to be [1,1]. - - *outputPadding*: a sequence of {{unsigned long}} of length 2. The padding values applied to each spatial dimension of the output tensor. This explicit padding values are needed to disambiguate the output tensor shape for transposed convolution when the value of the *options.strides* is greater than 1. Note that these values are only used to disambiguate output shape when needed; it does not necessarily cause any padding value to be written to the output tensor. If not specified, the values are assumed to be [0,0]. - - *outputSizes*: a sequence of {{unsigned long}} of length 2. The sizes of the last two dimensions of the output tensor. When the output sizes are explicitly specified, the output padding values in *options.outputPadding* are ignored. If not specified, the output sizes are automatically computed. - - *autoPad*: an {{MLAutoPad}}. The automatic input padding options. By default, this argument is set to *"explicit"*, which means that the values in the *options.padding* array should be used for input padding. When the option is set other than *"explicit"*, the values in the *options.padding* array are ignored. With the *"same-upper"* option, the padding values are automatically computed such that the additional ending padding of the spatial input dimensions would allow all of the input values in the corresponding dimension to be filtered. The *"same-lower"* option is similar but padding is applied to the beginning padding of the spatial input dimensions instead of the ending one. - - *groups*: an {{unsigned long}} scalar. The number of groups that input channels and output channels are divided into, default to 1. - - *inputLayout*: an {{MLInputOperandLayout}}. The default value is *"nchw"*. This option specifies the layout format of the input and output tensor as follow: - "nchw": - - input tensor: [batches, input_channels, height, width] - - output tensor: [batches, output_channels, height, width] +{{MLConvTranspose2dOptions}} has the following members: +
+ : padding + :: + A sequence of {{unsigned long}} of length 4: [beginningHeight, endingHeight, beginningWidth, endingWidth]. + Specifies the additional rows and columns added to the beginning and ending of each spatial dimension of the convolution input. + The default value is [0, 0, 0, 0]. + + : strides + :: + A sequence of {{unsigned long}} of length 2: [strideHeight, strideWidth]. + Specifies the stride of the sliding window for each spatial dimension of the convolution input. + The default value is [1, 1]. + + : dilations + :: + A sequence of {{unsigned long}} of length 2: [dilationHeight, dilationWidth]. Specifies the dilation factor for each spatial dimension applied on the convolution filter (kernel). + The default value is [1, 1]. + + : outputPadding + :: + A sequence of {{unsigned long}} of length 2. + Specifies the padding values applied to each spatial dimension of the output tensor. The explicit padding values are needed to disambiguate the output tensor shape for transposed convolution when the value of the *options*.{{MLConvTranspose2dOptions/strides}} is greater than 1. + + Note that these values are only used to disambiguate output shape when needed; it does not necessarily cause any padding value to be written to the output tensor. + + The default values is [0, 0]. + + : outputSizes + :: + A sequence of {{unsigned long}} of length 2. + Specifies the sizes of the last two dimensions of the output tensor. When the output sizes are explicitly specified, the output padding values in {{MLConvTranspose2dOptions/outputPadding}} are ignored. + + If not specified, the output sizes are automatically computed. - "nhwc": - - input tensor: [batches, height, width, input_channels] - - output tensor: [batches, height, width, output_channels] + : autoPad + :: + An {{MLAutoPad}} [=string=]. + Specifies the automatic input padding options. + The default value is *"explicit"*, which means that the values in the {{MLConvTranspose2dOptions/padding}} array should be used for input padding. - - *filterLayout*: an {{MLConvTranspose2dFilterOperandLayout}}. The default value is *"iohw"*. This option specifies the layout format of the filter tensor as follow: + When the option is set other than *"explicit"*, the values in the {{MLConvTranspose2dOptions/padding}} array are ignored. - "iohw": - - [input_channels, output_channels/groups, height, width] + With the *"same-upper"* option, the padding values are automatically computed such that the additional ending padding of the spatial input dimensions would allow all of the input values in the corresponding dimension to be filtered. - "hwoi": - - [height, width, output_channels/groups, input_channels] + The *"same-lower"* option is similar but padding is applied to the beginning padding of the spatial input dimensions instead of the ending one. - "ohwi": - - [output_channels/groups, height, width, input_channels] + : groups + :: + An {{unsigned long}} scalar. + Specifies the number of groups that input channels and output channels are divided into. + The default value is 1. - - *bias*: an {{MLOperand}}. The additional 1-D tensor with the shape of [output_channels] whose values are to be added to the transposed convolution result. - - *activation*: an {{MLActivation}}. The optional activation function that immediately follows the transposed convolution operation. + : inputLayout + :: + An {{MLInputOperandLayout}} [=string=]. + Specifies the layout format of the input and output tensor as follows: + - **"nchw"** + - input tensor: *[batches, inputChannels, height, width]* + - output tensor: *[batches, outputChannels, height, width]* + - **"nhwc"**: + - input tensor: *[batches, height, width, inputChannels]* + - output tensor: *[batches, height, width, outputChannels]* + The default value is *"nchw"*. + + : filterLayout + :: + An {{MLConvTranspose2dFilterOperandLayout}} [=string=]. + Specifies the layout format of the filter tensor as follow: + - **"iohw"**: [inputChannels, outputChannels/groups, height, width] + - **"hwoi"**: [height, width, outputChannels/groups, inputChannels] + - **"ohwi"**: [outputChannels/groups, height, width, inputChannels] + The default value is *"iohw"*. + + : bias + :: + An {{MLOperand}} object. + Specifies the additional 1-D tensor with the shape of *[outputChannels]* whose values are to be added to the convolution result. - **Returns:** an {{MLOperand}}. The output 4-D tensor that contains the transposed convolution result. The output shape is interpreted according to the *options.inputLayout* value. More specifically, unless the *options.outputSizes* values are explicitly specified, the *options.outputPadding* may be needed to compute the spatial dimension values of the output tensor as follow: + : activation + :: + An {{MLActivation}} object. + Specifies the optional activation function that immediately follows the convolution operation. +
- *output size = (input size - 1) ** *stride + (filter size - 1) ** *dilation + 1 - beginning padding - ending padding + output padding* +
+ **Arguments:** + - *input*: an {{MLOperand}}. The input 4-D tensor. The logical shape + is interpreted according to the value of *options*.{{MLConvTranspose2dOptions/inputLayout}}. + - *filter*: an {{MLOperand}}. The filter 4-D tensor. The logical shape is + interpreted according to the value of *options*.{{MLConvTranspose2dOptions/filterLayout}} and {{MLConvTranspose2dOptions/groups}}. + - *options*: an optional {{MLConvTranspose2dOptions}}. + + **Returns:** an {{MLOperand}}. The output 4-D tensor that contains the transposed convolution result. The output shape is interpreted according to the *options*.{{MLConvTranspose2dOptions/inputLayout}} value. More specifically, unless the *options*.{{MLConvTranspose2dOptions/outputSizes}} values are explicitly specified, the *options*.{{MLConvTranspose2dOptions/outputPadding}} may be needed to compute the spatial dimension values of the output tensor as follow: + + *outputSize = (inputSize - 1) ** *stride + (filterSize - 1) ** *dilation + 1 - beginningPadding - endingPadding + outputPadding*
+
+ + + The convTranspose2d(|input|, |filter|, |options|) method steps are: + +
+ 1. [=Assert=]: the type of |input| and |filter| is {{MLOperand}}. + 1. Let |inputSize| be the [=list/size=] of |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. + 1. Let |filterSize| be the [=list/size=] of |filter|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. + 1. If |inputSize| is not 4, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |filterSize| is not 4, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}} is not the same as {{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}}, then [=exception/throw=] a {{TypeError}}. + 1. If |options|.{{MLConvTranspose2dOptions/padding}} does not [=map/exist=], set it to `« 0, 0, 0, 0 »`. + 1. Else if the [=list/size=] of |options|.{{MLConvTranspose2dOptions/padding}} is not 4, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLConvTranspose2dOptions/strides}} does not [=map/exist=], set it to `« 1, 1 »`. + 1. Else if the [=list/size=] of |options|.{{MLConvTranspose2dOptions/strides}} is not 2, then [=exception/throw=] a {{TypeError}}. + 1. If any element in |options|.{{MLConv2dOptions/strides}} is equal to 0, then [=exception/throw=] a {{TypeError}}. + 1. If |options|.{{MLConvTranspose2dOptions/dilations}} does not [=map/exist=], set it to `« 1, 1 »`. + 1. Else if the [=list/size=] of |options|.{{MLConvTranspose2dOptions/dilations}} is not 2, then [=exception/throw=] a {{TypeError}}. + 1. If |options|.{{MLConvTranspose2dOptions/outputPadding}} does not [=map/exist=], set it to `« 0, 0 »`. + 1. Else if the [=list/size=] of |options|.{{MLConvTranspose2dOptions/outputPadding}} is not 2, then [=exception/throw=] a {{TypeError}}. + 1. If |options|.{{MLConvTranspose2dOptions/outputSizes}} [=map/exists=]: + 1. If the [=list/size=] of |options|.{{MLConvTranspose2dOptions/outputSizes}} is not 2, then [=exception/throw=] a {{TypeError}}. + 1. If the elements of |options|.{{MLConvTranspose2dOptions/outputSizes}} are not smaller than the elements at the same dimension (index) for |options|.{{MLConvTranspose2dOptions/strides}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |inputSize| / |options|.{{MLConvTranspose2dOptions/groups}} is not equal to |filterSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Else if |inputSize| % |options|.{{MLConvTranspose2dOptions/groups}} is not 0, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLConvTranspose2dOptions/bias}} [=map/exists=]: + 1. [=Assert=]: the type of |options|.{{MLConvTranspose2dOptions/bias}} is {{MLOperand}}. + 1. If the [=list/size=] of |options|.{{MLConvTranspose2dOptions/bias}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} is not 1, then [=exception/throw=] a {{TypeError}}. + 1. If |options|.{{MLConvTranspose2dOptions/bias}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}} is not the same as |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}}, then [=exception/throw=] a {{TypeError}}. + 1. If |options|.{{MLConvTranspose2dOptions/activation}} [=map/exists=]: + 1. [=Assert=]: the type of |options|.{{MLConvTranspose2dOptions/activation}} is {{MLActivation}}. + 1. Let |outputShape| be the result of invoking the underlying implementation for calculating output dimensions, given |options|. + 1. If |outputShape| is not the same as the shape of |options|.{{MLConvTranspose2dOptions/bias}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |desc| a new {{MLOperandDescriptor}}. + 1. Set |desc|.{{MLOperandDescriptor/type}} to |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}}. + 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. Create an [=implementation-defined=] platform operator |convTranspose2dImpl| for this method, given |options| and |filter|. + 1. If |options|.{{MLConvTranspose2dOptions/activation}} [=map/exists=],register it as activation to |convTranspose2dImpl|. + 1. Store a reference of |convTranspose2dImpl| in |output|.{{MLOperand/[[operator]]}}. + 1. Create an [=implementation-defined=] platform operand |outputImpl| to represent the output, given |output| and |convTranspose2dImpl|. + 1. Store a reference to |outputImpl| in |output|.{{MLOperand/[[operand]]}}. + 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |convTranspose2dImpl|. + 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |convTranspose2dImpl|. + 1. Return |output|. +
+
+ ### Element-wise binary operations ### {#api-mlgraphbuilder-binary} -Compute the element-wise binary addition, subtraction, multiplication, division, -maximum and minimum of the two input tensors. +Compute the element-wise binary addition, subtraction, multiplication, division, power, maximum and minimum of the two input tensors. + +The element-wise binary operations will be broadcasted according to +[[!numpy-broadcasting-rule]]. The [=rank=] of the output tensor is the maximum +[=rank=] of the input tensors. For each dimension of the output tensor, its size +is the maximum size along that dimension of the input tensors. + -
+ +
**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 binary operation of the two input tensors. - - The element-wise binary operation will be broadcasted according to - [[!numpy-broadcasting-rule]]. The rank of the output tensor is the maximum - rank of the input tensors. For each dimension of the output tensor, its size - is the maximum size along that dimension of the input tensors. - +
+
**Operation types:** - *add*: Add the values of the two input tensors, element-wise. - *sub*: Subtract the values of the second input tensor from the values of the first input tensor, element-wise. @@ -1599,29 +2401,129 @@ partial interface MLGraphBuilder { - *pow*: Compute the values of the values of the first input tensor to the power of the values of the second input tensor, element-wise.
+
+ + + To create element-wise binary operation given |op|, |a| and |b|, run the following steps: + +
+ 1. [=Assert=]: |op| is one of "add", "sub", "mul", "div", "max", "min", "pow". + 1. [=Assert=]: the type of |a| and |b| is {{MLOperand}}. + 1. If |a|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}} is not equal to |b|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |descriptor| be a new {{MLOperandDescriptor}}. + 1. Set |descriptor|.{{MLOperandDescriptor/type}} to |a|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}}. + 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|. +
+
+ +
+ + + To broadcast-shapes given |shape1| and |shape2|, run the following steps: + +
+ 1. [=Assert=]: The type of |shape1| and |shape2| is `sequence of unsigned long`. + 1. Let |output| be the result of invoking the [=implementation-defined=] shape broadcast on |shape1| and |shape2|. + 1. If that fails, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Return |output|. +
+ The most common implementation is that two shapes are compatible, when each of their corresponding dimensions are equal, or one of them is 1. The output shape consists of the maximum of the corresponding dimensions. +
+
+
+ +
+ + The element-wise binary operation algorithms invoke the [=MLGraphBuilder/element-wise-binary-op | create element-wise binary operation=] steps as follows. + +
+
+ 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|. +
+ +
+ 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|. +
+ +
+ 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|. +
+ +
+ 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|. +
+ +
+ 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|. +
+ +
+ 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|. +
+ +
+ 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|. +
+
+
+ ### Element-wise unary operations ### {#api-mlgraphbuilder-unary} Compute the element-wise unary operation for input tensor. -
+ +
**Arguments:** - - *x*: an {{MLOperand}}. The input tensor. + - *input*: an {{MLOperand}}. The input tensor. **Returns:** an {{MLOperand}}. The output tensor that contains the result of 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. @@ -1634,33 +2536,119 @@ partial interface MLGraphBuilder { - *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=]: 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|. + 1. Make a request to the underlying platform to: + 1. Let |opImpl| be an [=implementation-defined=] platform operator for the unary operation |op|. + 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 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|. +
+ +
+ 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|. +
+ +
+ 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|. +
+ +
+ 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|. +
+ +
+ 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|. +
+ +
+ 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|. +
+ +
+ 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|. +
+ +
+ 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|. +
+ +
+ 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|. +
+
+
+ ### The elu() method ### {#api-mlgraphbuilder-elu} -Calculate the exponential linear unit function on the input tensor element-wise. The calculation follows the expression `max(0, x) + alpha * (exp(min(0, x)) - 1)`. +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:** - - *x*: an {{MLOperand}}. The input tensor. - - *options*: an optional {{MLEluOptions}}. The optional parameters of the operation. - - *alpha*: a {{float}} scalar multiplier, default to 1. - - **Returns:** - - an {{MLOperand}}. The output tensor of the same shape as *x*. - - an {{MLActivation}}. The activation function representing the elu operation. -
+
+
+ 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. +
     return builder.add(
               builder.max(builder.constant(0), x),
@@ -1670,11 +2658,63 @@ partial interface MLGraphBuilder {
                   builder.exp(builder.min(builder.constant(0), x)),
                   builder.constant(1))));
     
-
+ +
+ +#### The {{MLGraphBuilder/elu(input, options)}} method #### {#api-mlgraphbuilder-elu-input-options} +
+ **Arguments:** + - *input*: an {{MLOperand}}. The input tensor. + - *options*: an optional {{MLEluOptions}}. The optional parameters of the operation. + - *alpha*: a {{float}} scalar multiplier, default to 1. + + **Returns:** + - an {{MLOperand}}. The output tensor of the same shape as *input*.
+
+ + + The elu(|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 ELU 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 {{MLGraphBuilder/elu(options)}} method #### {#api-mlgraphbuilder-elu-options} +
+ **Arguments:** + - *options*: an optional {{MLEluOptions}}. The optional parameters of the operation. + - *alpha*: a {{float}} scalar multiplier, default to 1. + + **Returns:** + - an {{MLActivation}}. The activation function representing the elu operation. +
+ +
+ + + The elu(|options|) method steps are: + +
+ 1. Let |op| be the result of creating an MLActivation given [=this=], `"elu"` and |options|. + 1. Return |op|. +
+
+ ### The gemm() method ### {#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. + -
+ +{{MLGemmOptions}} has the following members: +
+ : c + :: + An {{MLOperand}}. Specifies the third input tensor. It is either a scalar, or of the shape that is unidirectionally broadcastable to the shape [M, N] according to [[!numpy-broadcasting-rule]]. When it is not specified, the computation is done as if *c* is a scalar 0.0. + + : alpha + :: + A {{float}} scalar multiplier for the first input. + + : beta + :: + A {{float}} scalar multiplier for the third input {{MLGemmOptions/c}}. + + : aTranspose + :: + A {{boolean}} indicating if the first input should be transposed prior to calculating the output. + + : bTranspose + :: + A {{boolean}} indicating if the second input should be transposed prior to calculating the output. +
+ +
**Arguments:** - *a*: an {{MLOperand}}. The first input 2-D tensor with shape [M, K] if *aTranspose* is false, or [K, M] if *aTranspose* is true. - *b*: an {{MLOperand}}. The second input 2-D tensor with shape [K, N] if *bTranspose* is false, or [N, K] if *bTranspose* is true. - *options*: an optional {{MLGemmOptions}}. The optional parameters of the operation. - - *c*: an {{MLOperand}}. The third input tensor. It is either a scalar, or of the shape that is unidirectionally broadcastable to the shape [M, N] according to [[!numpy-broadcasting-rule]]. When it is not specified, the computation is done as if *c* is a scalar 0.0. - - *alpha*: a {{float}} scalar multiplier for the first input, default to 1.0. - - *beta*: a {{float}} scalar multiplier for the third input, default to 1.0. - - *aTranspose*: a {{boolean}} indicating if the first input should be transposed prior to calculating the output, default to false. - - *bTranspose*: a {{boolean}} indicating if the second input should be transposed prior to calculating the output, default to false. **Returns:** an {{MLOperand}}. The output 2-D tensor of shape [M, N] that contains the calculated product of all the inputs. +
-
+
+ + + The gemm(|a|, |b|, |options|) method steps are: + +
+ 1. [=Assert=]: the type of |a| and |b| is {{MLOperand}}. + 1. Let |shapeA| be |a|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} and |sizeA| the [=list/size=] of |shapeA|. + 1. Let |shapeB| be |b|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} and |sizeB| the [=list/size=] of |shapeB|. + 1. If |sizeA| is not 2 or |sizeB| is not 2, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLGemmOptions/aTranspose}} is true, then let |shapeA| be the reverse array of |shapeA|. + 1. If |options|.{{MLGemmOptions/bTranspose}} is true, then let |shapeB| be the reverse array of |shapeB|. + 1. If |shapeA|[1] is not equal to |shapeB|[0], then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLGemmOptions/c}} [=map/exists=] and is not unidirectionally broadcastable to the shape [|shapeA|[0], |shapeB|[1]] according to the [[!numpy-broadcasting-rule]], then [=exception/throw=] a "{{DataError}}" {{DOMException}}. +
+ Type compatibility between |a|, |b| and |options|.{{MLGemmOptions/c}} can be also checked. +
+ 1. Let |desc| a new {{MLOperandDescriptor}}. + 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to [|shapeA|[0], |shapeB|[1]]. + 1. Set |desc|.{{MLOperandDescriptor/type}} to |a|.{{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 [=this=] and |desc|. + 1. Make a request to the underlying platform to: + 1. Let |opImpl| be an [=implementation-defined=] platform operator for the GEMM 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 |a|.{{MLOperand/[[operand]]}} and |b|.{{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. -
+  
+
     if (options.aTranspose)
       a = builder.transpose(a);
 
@@ -1712,8 +2808,8 @@ partial interface MLGraphBuilder {
 
     let ab = builder.matmul(builder.mul(builder.constant(options.alpha), a), b);
     return (c ? builder.add(ab, builder.mul(builder.constant(options.beta), c)) : ab);
-    
-
+ +
### The gru() method ### {#api-mlgraphbuilder-gru} @@ -1747,28 +2843,91 @@ partial interface MLGraphBuilder { optional MLGruOptions options = {}); }; -
+ +{{MLGruOptions}} has the following members: +
+ : bias + :: + An {{MLOperand}}. Specifies the 2-D input bias tensor of shape [numDirections, 3 * hiddenSize]. The ordering of the bias vectors in the second dimension of the tensor shape is specified according to the {{MLGruOptions/layout}} argument. + + : recurrentBias + :: + An {{MLOperand}}. Specifies the 2-D recurrent bias tensor of shape [numDirections, 3 * hiddenSize]. The ordering of the bias vectors in the second dimension of the tensor shape is specified according to the {{MLGruOptions/layout}} argument. + + : initialHiddenState + :: + An {{MLOperand}}. The 3-D initial hidden state tensor of shape [numDirections, batchSize, hiddenSize]. + When not specified, implementations SHOULD use a tensor filled with zero. + + : resetAfter + :: + A {{boolean}} indicating whether to apply the reset gate after or before matrix multiplication. The default value is true. + + : returnSequence + :: + A {{boolean}} indicating whether to also return the entire sequence with every output from each time step in it in addition to the output of the last time step. + The default value is false. + + : direction + :: + An {{MLRecurrentNetworkDirection}}. Specifies the processing direction of the input sequence. When set to `"both"`, the size of the first dimension of the weight and the bias tensor shapes must be 2, and the input is processed in both directions. + + : layout + :: + An {{MLGruWeightLayout}}. The ordering of the weight and bias vectors for the internal gates of GRU, specifically the `update (z)`, `reset (r)`, and `new (n)` gate, as indicated in the second dimension of the weight and bias tensor shape. When not specified, the default layout is `"zrn"`.bias + + : activations + :: + A sequence of {{MLActivation}}. Specifies a pair of activation functions with the first function used for the update and reset gate, and the second used for the new gate. When not specified, implementations SHOULD use the the pair of sigmoid (`"sigmoid"`) and the hyperbolic tangent (`"tanh"`) functions, respectively. +
+ +
**Arguments:** - - *input*: an {{MLOperand}}. The input 3-D tensor of shape [steps, batch_size, input_size]. - - *weight*: an {{MLOperand}}. The 3-D input weight tensor of shape [num_directions, 3 * hidden_size, input_size]. The ordering of the weight vectors in the second dimension of the tensor shape is specified according to the *options.layout* argument. - - *recurrentWeight*: an {{MLOperand}}. The 3-D recurrent weight tensor of shape [num_directions, 3 * hidden_size, hidden_size]. The ordering of the weight vectors in the second dimension of the tensor shape is specified according to the *options.layout* argument. + - *input*: an {{MLOperand}}. The input 3-D tensor of shape [steps, batchSize, inputSize]. + - *weight*: an {{MLOperand}}. The 3-D input weight tensor of shape [numDirections, 3 * hiddenSize, inputSize]. The ordering of the weight vectors in the second dimension of the tensor shape is specified according to the |options|.{{MLGruOptions/layout}} argument. + - *recurrentWeight*: an {{MLOperand}}. The 3-D recurrent weight tensor of shape [numDirections, 3 * hiddenSize, hiddenSize]. The ordering of the weight vectors in the second dimension of the tensor shape is specified according to the |options|.{{MLGruOptions/layout}} argument. - *steps*: an {{unsigned long}} scalar. The number of time steps in the recurrent network. The value must be greater than 0. - *hiddenSize*: an {{unsigned long}} scalar. The value of the third dimension of the cell output tensor shape. It indicates the number of features in the hidden state. - *options*: an optional {{MLGruOptions}}. The optional parameters of the operation. - - *bias*: an {{MLOperand}}. The 2-D input bias tensor of shape [num_directions, 3 * hidden_size]. The ordering of the bias vectors in the second dimension of the tensor shape is specified according to the *options.layout* argument. - - *recurrentBias*: an {{MLOperand}}. The 2-D recurrent bias tensor of shape [num_directions, 3 * hidden_size]. The ordering of the bias vectors in the second dimension of the tensor shape is specified according to the *options.layout* argument. - - *initialHiddenState*: an {{MLOperand}}. The 3-D initial hidden state tensor of shape [num_directions, batch_size, hidden_size]. When not specified, it's assumed to be a tensor filled with zero. - - *resetAfter*: a {{boolean}} indicating whether to apply the reset gate after or before matrix multiplication. Default to true. - - *returnSequence*: a {{boolean}} indicating whether to also return the entire sequence with every output from each time step in it in addition to the output of the last time step. Default to false. - - *direction*: an {{MLRecurrentNetworkDirection}}. The processing direction of the input sequence. When set to *"both"*, the size of the first dimension of the weight and the bias tensor shapes must be 2, and the input is processed in both directions. - - *layout*: an {{MLGruWeightLayout}}. The ordering of the weight and bias vectors for the internal gates of GRU, specifically the *update (z)*, *reset (r)*, and *new (n)* gate, as indicated in the second dimension of the weight and bias tensor shape. When not specified, the default layout is *"zrn"*. - - *activations*: a sequence of {{MLActivation}}. A pair of activation functions with the first function used for the update and reset gate, and the second used for the new gate. When not specified, it's assumed to be the sigmoid (*"sigmoid"*) and the hyperbolic tangent (*"tanh"*) function respectively. - **Returns:** a sequence of {{MLOperand}}. The first element of the sequence is a 3-D tensor of shape [num_directions, batch_size, hidden_size], the cell output from the last time step of the network. Additionally, if *options.returnSequence* is set to true, the second element is the 4-D output tensor of shape [steps, num_directions, batch_size, hidden_size] containing every cell outputs from each time step in the temporal sequence. + **Returns:** a sequence of {{MLOperand}}. The first element of the sequence is a 3-D tensor of shape [numDirections, batchSize, hiddenSize], the cell output from the last time step of the network. Additionally, if |options|.{{MLGruOptions/returnSequence}} is set to true, the second element is the 4-D output tensor of shape [steps, numDirections, batchSize, hiddenSize] containing every cell outputs from each time step in the temporal sequence. +
-
+
+ + + The gru(|input|, |weight|, |recurrentWeight|, |steps|, |hiddenSize|, |options|) method steps are: + +
+ 1. [=Assert=]: the type of |input|, |weight| and |recurrentWeight| is {{MLOperand}}. + 1. If the [=rank=] of |input| or |weight| or |recurrentWeight| is not 3, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLGruOptions/bias}} [=map/exists=]. + 1. [=Assert=]: its type is {{MLOperand}}. + 1. If |options|.{{MLGruOptions/bias}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[1] is not equal to 3 * |hiddenSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLGruOptions/recurrentBias}} [=map/exists=]. + 1. [=Assert=]: its type is {{MLOperand}}. + 1. If |options|.{{MLGruOptions/recurrentBias}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[1] is not equal to 3 * |hiddenSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLGruOptions/initialHiddenState}} [=map/exists=]. + 1. [=Assert=]: its type is {{MLOperand}}. + 1. If its rank is not 3, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLGruOptions/activations}} [=map/exists=] and its [=list/size=] is not 2, then [=exception/throw=] a {{TypeError}}. + 1. If |steps| is not equal to |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0], then [=exception/throw=] a {{TypeError}}. + 1. Let |output| be an empty sequence of {{MLOperand}} objects. + 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. Make a request to the underlying platform to: + 1. Let |opImpl| be an [=implementation-defined=] platform operator for `"gru"`, given |weight|, |recurrentWeight|, |steps|, |hiddenSize| and |options| as parameters. + 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. + 1. Connect |output| as output to |opImpl|. + 1. Return |output|. +
+
+ +
+
+ The behavior of this operation can be generically emulated from the usage of other operations as follows. However, user agents typically have a more efficient implementation for it, therefore its usage is encouraged from the performance standpoint. -
+  
+
     const numDirections = (options.direction == "both" ? 2 : 1);
     let hiddenState = options.initialHiddenState;
 
@@ -1785,11 +2944,11 @@ partial interface MLGraphBuilder {
     let currentRecurrentBias = [];
 
     for (let dir = 0; dir < numDirections; ++dir) {
-      currentWeight.push(builder.squeeze(builder.slice(weight, [dir, 0, 0], [1, 3 * hidden_size, input_size]), { axes: [0] }));
-      currentRecurrentWeight.push(builder.squeeze(builder.slice(recurrentWeight, [dir, 0, 0], [1, 3 * hidden_size, hidden_size]), { axes: [0] }));
-      currentBias.push(options.bias ? (builder.squeeze(builder.slice(options.bias, [dir, 0], [1, 3 * hidden_size]), { axes: [0] })) : null);
+      currentWeight.push(builder.squeeze(builder.slice(weight, [dir, 0, 0], [1, 3 * hiddenSize, inputSize]), { axes: [0] }));
+      currentRecurrentWeight.push(builder.squeeze(builder.slice(recurrentWeight, [dir, 0, 0], [1, 3 * hiddenSize, hiddenSize]), { axes: [0] }));
+      currentBias.push(options.bias ? (builder.squeeze(builder.slice(options.bias, [dir, 0], [1, 3 * hiddenSize]), { axes: [0] })) : null);
       currentRecurrentBias.push(options.recurrentBias ?
-        (builder.squeeze(builder.slice(options.recurrentBias, [dir, 0], [1, 3 * hidden_size]), { axes: [0] })) : null);
+        (builder.squeeze(builder.slice(options.recurrentBias, [dir, 0], [1, 3 * hiddenSize]), { axes: [0] })) : null);
     }
 
     for (let step = 0; step < steps; ++step) {
@@ -1797,12 +2956,12 @@ partial interface MLGraphBuilder {
       let currentOutput = null;
 
       for (let dir = 0; dir < numDirections; ++dir) {
-        currentHidden.push(builder.squeeze(builder.slice(hiddenState, [dir, 0, 0], [1, batch_size, hidden_size]), { axes: [0] }));
+        currentHidden.push(builder.squeeze(builder.slice(hiddenState, [dir, 0, 0], [1, batchSize, hiddenSize]), { axes: [0] }));
       }
 
       for (let dir = 0; dir < numDirections; ++dir) {
         let slice = (dir == 1 || options.direction == "backward" ? steps - step - 1 : step);
-        let currentInput = builder.squeeze(builder.slice(input, [slice, 0, 0], [1, batch_size, input_size]), { axes: [0] });
+        let currentInput = builder.squeeze(builder.slice(input, [slice, 0, 0], [1, batchSize, inputSize]), { axes: [0] });
 
         let result = builder.reshape(
           builder.gruCell(
@@ -1824,12 +2983,13 @@ partial interface MLGraphBuilder {
     }
 
     return (sequence ? [hiddenState, sequence] : [hiddenState]);
-    
-
+ +
### The gruCell() method ### {#api-mlgraphbuilder-grucell} A single time step of the Gated Recurrent Unit [[GRU]] recurrent network using an update gate and a reset gate to compute the hidden state that rolls into the output across the temporal sequence of a recurrent network. + -
+ +{{MLGruCellOptions}} has the following members: +
+ : bias + :: + An {{MLOperand}}. Specifies the 1-D input bias tensor of shape [3 * hiddenSize]. The ordering of the bias vectors in the second dimension of the tensor shape is specified according to the {{MLGruOptions/layout}} argument. + + : recurrentBias + :: + An {{MLOperand}}. Specifies the 1-D recurrent bias tensor of shape [3 * hiddenSize]. The ordering of the bias vectors in the second dimension of the tensor shape is specified according to the {{MLGruOptions/layout}} argument. + + : resetAfter + :: + A {{boolean}} indicating whether to apply the reset gate after or before matrix multiplication. The default value is true. + + : layout + :: + An {{MLGruWeightLayout}}. The ordering of the weight and bias vectors for the internal gates of GRU, specifically the `update (z)`, `reset (r)`, and `new (n)` gate, as indicated in the second dimension of the weight and bias tensor shape. When not specified, the default layout is `"zrn"`. + + : activations + :: + A sequence of {{MLActivation}}. Specifies a pair of activation functions with the first function used for the update and reset gate, and the second used for the new gate. When not specified, implementations SHOULD use the the pair of sigmoid (`"sigmoid"`) and the hyperbolic tangent (`"tanh"`) functions, respectively. +
+ +
**Arguments:** - - *input*: an {{MLOperand}}. The input 2-D tensor of shape [batch_size, input_size]. - - *weight*: an {{MLOperand}}. The 2-D input weight tensor of shape [3 * hidden_size, input_size]. The ordering of the weight vectors in the first dimension of the tensor shape is specified according to the *options.layout* argument. - - *recurrentWeight*: an {{MLOperand}}. The 2-D recurrent weight tensor of shape [3 * hidden_size, hidden_size]. The ordering of the weight vectors in the first dimension of the tensor shape is specified according to the *options.layout* argument. - - *hiddenState*: an {{MLOperand}}. The 2-D input hidden state tensor of shape [batch_size, hidden_size]. + - *input*: an {{MLOperand}}. The input 2-D tensor of shape [batchSize, inputSize]. + - *weight*: an {{MLOperand}}. The 2-D input weight tensor of shape [3 * hiddenSize, inputSize]. The ordering of the weight vectors in the first dimension of the tensor shape is specified according to the *options.layout* argument. + - *recurrentWeight*: an {{MLOperand}}. The 2-D recurrent weight tensor of shape [3 * hiddenSize, hiddenSize]. The ordering of the weight vectors in the first dimension of the tensor shape is specified according to the *options.layout* argument. + - *hiddenState*: an {{MLOperand}}. The 2-D input hidden state tensor of shape [batchSize, hiddenSize]. - *hiddenSize*: an {{unsigned long}} scalar. The value of the second dimension of the output tensor shape. It indicates the number of features in the hidden state. - *options*: an optional {{MLGruCellOptions}}. The optional parameters of the operation. - - *bias*: an {{MLOperand}}. The 1-D input bias tensor of shape [3 * hidden_size]. The ordering of the bias vectors in the first dimension of the tensor shape is specified according to the *options.layout* argument. - - *recurrentBias*: an {{MLOperand}}. The 1-D recurrent bias tensor of shape [3 * hidden_size]. The ordering of the bias vectors in the first dimension of the tensor shape is specified according to the *options.layout* argument. - - *resetAfter*: a {{boolean}} indicating whether to apply the reset gate after or before matrix multiplication. Default to true. - - *layout*: an {{MLGruWeightLayout}}. The ordering of the weight and bias vectors for the internal gates of GRU, specifically the *update (z)*, *reset (r)*, and *new (n)* gate, as indicated in the first dimension of the weight and bias tensor shapes. When not specified, the default layout is *"zrn"*. - - *activations*: a sequence of {{MLActivation}}. A pair of activation functions with the first function used for the *update (z)* and *reset (r)* gate, and the second used for the *new (n)* gate. When not specified, it's default to the sigmoid (*"sigmoid"*) and the hyperbolic tangent (*"tanh"*) function respectively. - **Returns:** an {{MLOperand}}. The 2-D tensor of shape [batch_size, hidden_size], the cell output hidden state of a single time step of the recurrent network. + **Returns:** an {{MLOperand}}. The 2-D tensor of shape [batchSize, hiddenSize], the cell output hidden state of a single time step of the recurrent network. +
-
+
+ + + The gruCell(|input|, |weight|, |recurrentWeight|, |hiddenState|, |hiddenSize|, |options|) method steps are: + +
+ 1. [=Assert=]: the type of |input|, |weight| and |recurrentWeight| is {{MLOperand}}. + 1. If the [=rank=] of |input| or |weight| or |recurrentWeight| or |hiddenState| is not 2, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |weight|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0] is not equal to 3 * |hiddenSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |recurrentWeight|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0] is not equal to 3 * |hiddenSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLGruOptions/bias}} [=map/exists=]: + 1. [=Assert=]: its type is {{MLOperand}}. + 1. If its rank is not equal to 3 * |hiddenSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLGruOptions/recurrentBias}} [=map/exists=]: + 1. [=Assert=]: its type is {{MLOperand}}. + 1. If its rank is not equal to 3 * |hiddenSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLGruOptions/activations}} [=map/exists=] and its [=list/size=] is not 2, then [=exception/throw=] a {{TypeError}}. + 1. Let |desc| a new {{MLOperandDescriptor}}. + 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to [ |input|.{{MLOperandDescriptor/dimensions}}[0], |hiddenSize| ]. + 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 [=this=] and |desc|. + 1. Make a request to the underlying platform to: + 1. Let |opImpl| be an [=implementation-defined=] platform operator for `"gruCell"`, given |weight|, |recurrentWeight|, |hiddenState|, |hiddenSize| and |options| as parameters. + 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 can be generically emulated via other operations as shown below, when the weight layout is the default *"zrn"* layout, and the activation functions of the update/reset gate and new gate are of the operator types *sigmoid* and *tanh* respectively. -
+  
+
     const one = builder.constant(1);
     const zero = builder.constant(0);
 
@@ -1877,11 +3093,11 @@ partial interface MLGraphBuilder {
         builder.add(
           builder.matmul(
             input,
-            builder.transpose(builder.slice(weight, [0, 0], [hiddenSize, input_size]))
+            builder.transpose(builder.slice(weight, [0, 0], [hiddenSize, inputSize]))
             ),
           builder.matmul(
             hiddenState,
-            builder.transpose(builder.slice(recurrentWeight, [0, 0], [hiddenSize, hidden_size]))
+            builder.transpose(builder.slice(recurrentWeight, [0, 0], [hiddenSize, hiddenSize]))
             )
           )
         )
@@ -1897,11 +3113,11 @@ partial interface MLGraphBuilder {
         builder.add(
           builder.matmul(
             input,
-            builder.transpose(builder.slice(weight, [hiddenSize, 0], [hiddenSize, input_size]))
+            builder.transpose(builder.slice(weight, [hiddenSize, 0], [hiddenSize, inputSize]))
             ),
           builder.matmul(
             hiddenState,
-            builder.transpose(builder.slice(recurrentWeight, [hiddenSize, 0], [hiddenSize, hidden_size]))
+            builder.transpose(builder.slice(recurrentWeight, [hiddenSize, 0], [hiddenSize, hiddenSize]))
             )
           )
         )
@@ -1916,7 +3132,7 @@ partial interface MLGraphBuilder {
           builder.add(
             builder.matmul(
               input,
-              builder.transpose(builder.slice(weight, [2 * hiddenSize, 0], [hiddenSize, input_size]))
+              builder.transpose(builder.slice(weight, [2 * hiddenSize, 0], [hiddenSize, inputSize]))
               ),
             builder.mul(
               r,
@@ -1924,7 +3140,7 @@ partial interface MLGraphBuilder {
                 (options.recurrentBias ? builder.slice(options.recurrentBias, [2 * hiddenSize], [hiddenSize]) : zero),
                 builder.matmul(
                   hiddenState,
-                  builder.transpose(builder.slice(recurrentWeight, [2 * hiddenSize, 0], [hiddenSize, hidden_size]))
+                  builder.transpose(builder.slice(recurrentWeight, [2 * hiddenSize, 0], [hiddenSize, hiddenSize]))
                   )
                 )
               )
@@ -1942,11 +3158,11 @@ partial interface MLGraphBuilder {
           builder.add(
             builder.matmul(
               input,
-              builder.transpose(builder.slice(weight, [2 * hiddenSize, 0], [hiddenSize, input_size]))
+              builder.transpose(builder.slice(weight, [2 * hiddenSize, 0], [hiddenSize, inputSize]))
               ),
             builder.matmul(
               builder.mul(r, hiddenState),
-              builder.transpose(builder.slice(recurrentWeight, [2 * hiddenSize, 0], [hiddenSize, hidden_size]))
+              builder.transpose(builder.slice(recurrentWeight, [2 * hiddenSize, 0], [hiddenSize, hiddenSize]))
               )
             )
           )
@@ -1955,12 +3171,12 @@ partial interface MLGraphBuilder {
 
     // compute the new hidden state
     return builder.add(builder.mul(z, hiddenState), builder.mul(n, builder.sub(one, z)));
-    
-
+ +
### The hardSigmoid() method ### {#api-mlgraphbuilder-hard-sigmoid} -Calculate the non-smooth function used in place of a sigmoid function on the input tensor. +Calculate the non-smooth hard sigmoid function on the input tensor, used instead of the sigmoid function for faster computation. -
- **Arguments:** - - *x*: an {{MLOperand}}. The input tensor. - - *options*: an optional {{MLHardSigmoidOptions}}. The optional parameters of the operation. - - *alpha*: a {{float}} scalar multiplier, default to 0.2. - - *beta*: a {{float}} scalar addition, default to 0.5. - **Returns:** - - an {{MLOperand}}. The output tensor of the same shape as *x*. - - an {{MLActivation}}. The activation function representing the hard sigmoid operation. - -
+
+
+ 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. +
     return builder.max(
                builder.min(
@@ -1997,31 +3206,90 @@ partial interface MLGraphBuilder {
                    builder.constant(1)),
                builder.constant(0));
     
-
+ +
+ +{{MLHardSigmoidOptions}} has the following members: +
+ : alpha + :: + A {{float}} scalar multiplier. + The default value is 0.2. + : beta + :: + A {{float}} scalar addition. + The default value is 0.5. +
+ +#### The {{MLGraphBuilder/hardSigmoid(input, options)}} method #### {#api-mlgraphbuilder-hardsigmoid-input-options} +
+ **Arguments:** + - *input*: an {{MLOperand}}. The input tensor. + - *options*: an optional {{MLHardSigmoidOptions}}. The optional parameters of the operation. + + **Returns:** + - an {{MLOperand}}. The output tensor of the same shape as *input*. +
+ +
+ + + The hardSigmoid(|input|, |options|) method steps are: + +
+ 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|. + 1. Make a request to the underlying platform to: + 1. Let |opImpl| be an [=implementation-defined=] platform operator for the hard sigmoid 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 {{MLGraphBuilder/hardSigmoid(options)}} method #### {#api-mlgraphbuilder-hardsigmoid-options} +
+ **Arguments:** + - *options*: an optional {{MLHardSigmoidOptions}}. The optional parameters of the operation. + + **Returns:** + - an {{MLActivation}}. The activation function representing the hard sigmoid operation.
+
+ + + The hardSigmoid(|options|) method steps are: + +
+ 1. Let |op| be the result of creating an MLActivation given [=this=], `"hardSigmoid"` and |options|. + 1. If that [=exception/throws=] an error, re-[=exception/throw=] the error. + 1. Return |op|. +
+
+ ### The hardSwish() method ### {#api-mlgraphbuilder-hard-swish} Computes the nonlinear function `y = x * max(0, min(6, (x + 3))) / 6` that is introduced by [[MobileNetV3]] on the input tensor element-wise. -
- **Arguments:** - - *x*: an {{MLOperand}}. The input tensor. - - **Returns:** - - an {{MLOperand}}. The output tensor of the same shape as *x*. - - an {{MLActivation}}. The activation function representing the hard-swish operation. -
+
+
+ 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. -
+  
+
     return builder.div(
                builder.mul(
                    x,
@@ -2031,12 +3299,61 @@ partial interface MLGraphBuilder {
                            builder.constant(6),
                            builder.add(x, builder.constant(3))))),
                builder.constant(6));
-    
-
+ +
+#### The {{MLGraphBuilder/hardSwish(input)}} method #### {#api-mlgraphbuilder-hardswish-input} +
+ **Arguments:** + - *input*: an {{MLOperand}}. The input tensor. + + **Returns:** + - an {{MLOperand}}. The output tensor of the same shape as *input*. +
+ +
+ + + The hardSwish(|input|) 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 hard-swish operation. + 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 {{MLGraphBuilder/hardSwish()}} method #### {#api-mlgraphbuilder-hardswish} +
+ **Arguments:** + - None. + + **Returns:** + - an {{MLActivation}}. The activation function representing the hard-swish operation. +
+ +
+ + The hardSwish() method steps are: + +
+ 1. Let |op| be the result of creating an MLActivation given [=this=] and `"hardSwish"`. + 1. If that [=exception/throws=] an error, re-[=exception/throw=] the error. + 1. Return |op|. +
+
+ ### The instanceNormalization() method ### {#api-mlgraphbuilder-instancenorm} Normalize the input features using [[Instance-Normalization]]. Unlike [[#api-mlgraphbuilder-batchnorm]] where the mean and variance values used in the calculation are previously computed across the batch dimension during the model training phase, the mean and variance values used in the calculation of an instance normalization are computed internally on the fly per input feature. + -
+ +The {{MLInstanceNormalizationOptions}} members are: +
+ : scale + :: + An {{MLOperand}}. Specifies the 1-D tensor of the scaling values whose [=list/size=] is equal to the number of channels, i.e. the size of the feature dimension of the input. For example, for an |input| tensor with `nchw` layout, the [=list/size=] is the value of |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[1]. + + : bias + :: + An {{MLOperand}}. Specifies the 1-D tensor of the bias values whose [=list/size=] is equal to the size of the feature dimension of the input. For example, for an |input| tensor with `nchw` layout, the len[=list/size=]gth is the value of |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[1]. + + : epsilon + :: + A {{float}} scalar. Specifies a small value to prevent computational error due to divide-by-zero. + + : layout + :: + An {{MLInputOperandLayout}}. Specifies the layout format of the input. + +
+ +
**Arguments:** - *input*: an {{MLOperand}}. The input 4-D tensor. - *options*: an optional {{MLInstanceNormalizationOptions}}. The optional parameters of the operation. - - *scale*: an {{MLOperand}}. The 1-D tensor of the scaling values whose length is equal to the size of the feature dimension of the input e.g. for the input tensor with *nchw* layout, the feature dimension is 1. - - *bias*: an {{MLOperand}}. The 1-D tensor of the bias values whose length is equal to the size of the feature dimension of the input e.g. for the input tensor with *nchw* layout, the feature dimension is 1. - - *epsilon*: a {{float}} scalar. A small value to prevent computational error due to divide-by-zero. The default value is 0.00001 when not specified. - - *layout*: an {{MLInputOperandLayout}}. This option specifies the layout format of the input. The default value is *"nchw"*. - **Returns:** an {{MLOperand}}. The instance-normalized 4-D tensor of the same shape as the input tensor. + **Returns:** an {{MLOperand}}. The instance-normalized 4-D tensor of the same shape as *input*. +
-
+
+ + + The instanceNormalization(|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|.{{MLInstanceNormalizationOptions/scale}} is {{MLOperand}}. + 1. If the [=rank=] of |options|.{{MLInstanceNormalizationOptions/scale}} is not equal to the [=list/size=] of the channel dimension of |input|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. [=Assert=]: the type of |options|.{{MLInstanceNormalizationOptions/bias}} is {{MLOperand}}. + 1. If the [=rank=] of |options|.{{MLInstanceNormalizationOptions/bias}} is not equal to the [=list/size=] of the channel dimension of |input|, 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 input tensor is 4-D of the *"nchw"* layout 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 mean reductions happen over the spatial dimensions of the input
     // e.g. axis 2 and 3 of the input tensor.
     const reduceOptions = { axes: [2,3], keepDimensions: true };
@@ -2092,46 +3455,100 @@ partial interface MLGraphBuilder {
         ),
       builder.reshape(options.bias, shape)
       );
-    
-
+ +
### The leakyRelu() method ### {#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:** - - *x*: an {{MLOperand}}. The input tensor. - - *options*: an optional {{MLLeakyReluOptions}}. The optional parameters of the operation. - - *alpha*: a {{float}} scalar multiplier, default to 0.01. - - **Returns:** - - an {{MLOperand}}. The output tensor of the same shape as *x*. - - an {{MLActivation}}. The activation function representing the leaky relu operation. -
+
+
+ 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. +
     return builder.add(builder.max(builder.constant(0), x),
               builder.mul(builder.constant(options.alpha), builder.min(builder.constant(0), x)));
     
-
+
+{{MLLeakyReluOptions}} has the following members: +
+ : alpha + :: + A {{float}} scalar multiplier. + The default value is 0.01. +
+ +#### The {{MLGraphBuilder/leakyRelu(input, options)}} method #### {#api-mlgraphbuilder-leaky-relu-input-options} +
+ **Arguments:** + - *input*: an {{MLOperand}}. The input tensor. + - *options*: an optional {{MLLeakyReluOptions}}. The optional parameters of the operation. + + **Returns:** + - an {{MLOperand}}. The output tensor of the same shape as *input*. +
+ +
+ + + The leakyRelu(|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 Leaky RELU 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 {{MLGraphBuilder/leakyRelu(options)}} method #### {#api-mlgraphbuilder-leaky-relu-options} +
+ **Arguments:** + - *options*: an optional {{MLLeakyReluOptions}}. The optional parameters of the operation. + + **Returns:** + - an {{MLActivation}}. The activation function representing the leaky relu operation. +
+ +
+ + + The leakyRelu(|options|) method steps are: + +
+ 1. Let |op| be the result of creating an MLActivation given [=this=], `"leakyRelu"` and |options|. + 1. If that [=exception/throws=] an error, re-[=exception/throw=] the error. + 1. Return |op|. +
+
+ ### The linear() method ### {#api-mlgraphbuilder-linear} Calculate a linear function `y = alpha * x + beta` on the input tensor. + -
- **Arguments:** - - *x*: an {{MLOperand}}. The input tensor. - - *options*: an optional {{MLLinearOptions}}. The optional parameters of the operation. - - *alpha*: a {{float}} scalar multiplier, default to 1. - - *beta*: a {{float}} scalar addition, default to 0. - - **Returns:** - - an {{MLOperand}}. The output tensor of the same shape as *x*. - - an {{MLActivation}}. The activation function representing the linear operation. -
+
+
+ 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. +
     return builder.add(
               builder.mul(x, builder.constant(options.alpha)),
               builder.constant(options.beta));
     
-
+ +
+ +{{MLLinearOptions}} has the following members: +
+ : alpha + :: + A {{float}} scalar multiplier. + The default value is 1. + : beta + :: + A {{float}} scalar addition. + The default value is 0. +
+ +#### The {{MLGraphBuilder/linear(input, options)}} method #### {#api-mlgraphbuilder-linear-input-options} +
+ **Arguments:** + - *input*: an {{MLOperand}}. The input tensor. + - *options*: an optional {{MLLinearOptions}}. The optional parameters of the operation. + + **Returns:** + - an {{MLOperand}}. The output tensor of the same shape as *input*. +
+ +
+ + + The linear(|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 linear 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 {{MLGraphBuilder/linear(options)}} method #### {#api-mlgraphbuilder-linear-options} +
+ **Arguments:** + - *options*: an optional {{MLLinearOptions}}. The optional parameters of the operation. + + **Returns:** + - an {{MLActivation}}. The activation function representing the linear operation.
+
+ + + The linear(|options|) method steps are: + +
+ 1. Let |op| be the result of creating an MLActivation given [=this=], `"linear"` and |options|. + 1. If that [=exception/throws=] an error, re-[=exception/throw=] the error. + 1. Return |op|. +
+
+ ### The lstm() method ### {#api-mlgraphbuilder-lstm} Long Short-Term Memory [[LSTM]] recurrent network uses an input, output, forget, and cell gate to compute the output state that rolls into the output across the temporal sequence of the network. + -
+ +{{MLLstmOptions}} has the following members: +
+ : bias + :: + An {{MLOperand}}. Specifies the 2-D input bias tensor of shape [numDirections, 4 * hiddenSize]. The ordering of the bias vectors in the second dimension of the tensor shape is specified according to {{MLLstmOptions/layout}}. + + : recurrentBias + :: + An {{MLOperand}}. Specifies the 2-D recurrent bias tensor of shape [numDirections, 4 * hiddenSize]. The ordering of the bias vectors in the first dimension of the tensor shape is specified according to {{MLLstmOptions/layout}}. + + : peepholeWeight + :: + An {{MLOperand}}. Specifies the 2-D weight tensor for peepholes of shape [numDirections, 3 * hiddenSize]. The pack ordering of the weight vectors is for the `input (i)`, `output (o)`, and `forget (f)` gate, respectively. + + : initialHiddenState + :: + An {{MLOperand}}. Specifies the 3-D initial hidden state tensor of shape [numDirections, batchSize, hiddenSize]. When not specified, implementations SHOULD use a tensor filled with zero. + + : initialCellState + :: + An {{MLOperand}}. Specifies the 3-D initial hidden state tensor of shape [numDirections, batchSize, hiddenSize]. When not specified, implementations SHOULD use a tensor filled with zero. + + : returnSequence + :: + A {{boolean}} indicating whether to also return the entire sequence with every output from each time step in it in addition to the output of the last time step. + + : direction + :: + An {{MLRecurrentNetworkDirection}}. Specifies the processing direction of the input sequence. When set to `"both"`, the size of the first dimension of the weight and the bias tensor shapes must be 2, and the input is processed in both directions. + + : layout + :: + An {{MLLstmWeightLayout}}. The ordering of the weight and bias vectors for the internal gates of LSTM, specifically the `input (i)`, `output (o)`, `forget (f)`, and `cell (g)` gate, as indicated in the first dimension of the weight and bias tensor shapes. When not specified, the default layout is `"iofg"`. + + : activations + :: + A sequence of {{MLActivation}}. A sequence of three activation functions, the first one is used for the `input (i)`, `forget (f)`, and `output (o)` gate, the second one is used for the `cell (g)` gate, and the last used for filtering the output cell state before combining it with the result of the output gate to form the output hidden state. When not specified, implementations SHOULD use the sequence of the sigmoid function (`"sigmoid"`) followed by two hyperbolic tangent functions (`"tanh"`) respectively. +
+ +
**Arguments:** - - *input*: an {{MLOperand}}. The input 3-D tensor of shape [steps, batch_size, input_size]. - - *weight*: an {{MLOperand}}. The 3-D input weight tensor of shape [num_directions, 4 * hidden_size, input_size]. The ordering of the weight vectors in the second dimension of the tensor shape is specified according to the *options.layout* argument. - - *recurrentWeight*: an {{MLOperand}}. The 3-D recurrent weight tensor of shape [num_directions, 4 * hidden_size, hidden_size]. The ordering of the weight vectors in the second dimension of the tensor shape is specified according to the *options.layout* argument. + - *input*: an {{MLOperand}}. The input 3-D tensor of shape [steps, batchSize, inputSize]. + - *weight*: an {{MLOperand}}. The 3-D input weight tensor of shape [numDirections, 4 * hiddenSize, inputSize]. The ordering of the weight vectors in the second dimension of the tensor shape is specified according to the |options|.{{MLLstmOptions/layout}}. + - *recurrentWeight*: an {{MLOperand}}. The 3-D recurrent weight tensor of shape [numDirections, 4 * hiddenSize, hiddenSize]. The ordering of the weight vectors in the second dimension of the tensor shape is specified according to the |options|.{{MLLstmOptions/layout}} argument. - *steps*: an {{unsigned long}} scalar. The number of time steps in the recurrent network. The value must be greater than 0. - *hiddenSize*: an {{unsigned long}} scalar. The value of the third dimension of the cell output tensor shape. It indicates the number of features in the hidden state. - - *options*: an optional {{MLGruOptions}}. The optional parameters of the operation. - - *bias*: an {{MLOperand}}. The 2-D input bias tensor of shape [num_directions, 4 * hidden_size]. The ordering of the bias vectors in the second dimension of the tensor shape is specified according to the *options.layout* argument. - - *recurrentBias*: an {{MLOperand}}. The 2-D recurrent bias tensor of shape [num_directions, 4 * hidden_size]. The ordering of the bias vectors in the second dimension of the tensor shape is specified according to the *options.layout* argument. - - *peepholeWeight*: an {{MLOperand}}. The 2-D weight tensor for peepholes of shape [num_directions, 3 * hidden_size]. The pack ordering of the weight vectors is for the *input (i)*, *output (o)*, and *forget (f)* gate respectively. - - *initialHiddenState*: an {{MLOperand}}. The 3-D initial hidden state tensor of shape [num_directions, batch_size, hidden_size]. When not specified, it's assumed to be a tensor filled with zero. - - *initialCellState*: an {{MLOperand}}. The 3-D initial hidden state tensor of shape [num_directions, batch_size, hidden_size]. When not specified, it's assumed to be a tensor filled with zero. - - *returnSequence*: a {{boolean}} indicating whether to also return the entire sequence with every output from each time step in it in addition to the output of the last time step. Default to false. - - *direction*: an {{MLRecurrentNetworkDirection}}. The processing direction of the input sequence. When set to *"both"*, the size of the first dimension of the weight and the bias tensor shapes must be 2, and the input is processed in both directions. - - *layout*: an {{MLLstmWeightLayout}}. The ordering of the weight and bias vectors for the internal gates of LSTM, specifically the *input (i)*, *output (o)*, *forget (f)*, and *cell (g)* gate, as indicated in the second dimension of the weight and bias tensor shapes. When not specified, the default layout is *"iofg"*. - - *activations*: a sequence of {{MLActivation}}. A sequence of three activation functions, the first one is used for the *input (i)*, *forget (f)*, and *output (o)* gate, the second one is used for the *cell (g)* gate, and the last used for filtering the output cell state before combining it with the result of the output gate to form the output hidden state. When not specified, they are assumed to be of the sigmoid function (*"sigmoid"*) followed by two hyperbolic tangent functions (*"tanh"*) respectively. - - **Returns:** a sequence of {{MLOperand}}. The first element of the sequence is a 3-D tensor of shape [num_directions, batch_size, hidden_size], the output hidden state from the last time step of the network. The second element is a 3-D tensor of shape [num_directions, batch_size, hidden_size], the output cell state from the last time step of the network. Additionally, if *options.returnSequence* is set to true, the third element is the 4-D output tensor of shape [steps, num_directions, batch_size, hidden_size] containing every output from each time step in the temporal sequence. + - *options*: an optional {{MLLstmOptions}}. The optional parameters of the operation. -
+ **Returns:** a sequence of {{MLOperand}}. The first element of the sequence is a 3-D tensor of shape [numDirections, batchSize, hiddenSize], the output hidden state from the last time step of the network. The second element is a 3-D tensor of shape [numDirections, batchSize, hiddenSize], the output cell state from the last time step of the network. Additionally, if |options|.{{MLLstmOptions/returnSequence}} is set to true, the third element is the 4-D output tensor of shape [steps, numDirections, batchSize, hiddenSize] containing every output from each time step in the temporal sequence. +
+ +
+ + + The lstm(|input|, |weight|, |recurrentWeight|, |steps|, |hiddenSize|, |options|) method steps are: + +
+ 1. Let |numDirections| be 1 if |options|.{{MLLstmOptions/direction}} is `"forward"`, or otherwise let it be 2. + 1. [=Assert=]: the type of |input|, |weight| and |recurrentWeight| is {{MLOperand}}. +
+ The shape of |input|, |weight| or |recurrentWeight| could be also checked here. +
+ 1. If |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0] is not equal to |steps|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |batchSize| be |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[1]. + 1. If |options|.{{MLLstmOptions/bias}} [=map/exists=]: + 1. [=Assert=]: its type is {{MLOperand}}. + 1. If its rank is not 2, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmOptions/bias}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0] is not |numDirections|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmOptions/bias}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[1] is not 4 * |hiddenSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmOptions/recurrentBias}} [=map/exists=]: + 1. [=Assert=]: its type is {{MLOperand}}. + 1. If its rank is not 2, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmOptions/recurrentBias}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0] is not |numDirections|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmOptions/recurrentBias}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[1] is not 4 * |hiddenSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmOptions/peepholeWeight}} [=map/exists=]: + 1. [=Assert=]: its type is {{MLOperand}}. + 1. If its rank is not 2, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmOptions/peepholeWeight}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0] is not |numDirections|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmOptions/peepholeWeight}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[1] is not 4 * |hiddenSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmOptions/initialHiddenState}} [=map/exists=]: + 1. [=Assert=]: its type is {{MLOperand}}. + 1. If its rank is not 3, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmOptions/initialHiddenState}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0] is not |numDirections|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmOptions/initialHiddenState}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[1] is not equal to |batchSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmOptions/initialHiddenState}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[2] is not |hiddenSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmOptions/initialCellState}} [=map/exists=]: + 1. [=Assert=]: its type is {{MLOperand}}. + 1. If its rank is not 3, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmOptions/initialCellState}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0] is not |numDirections|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmOptions/initialCellState}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[1] is not equal to |batchSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmOptions/initialCellState}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[2] is not |hiddenSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmOptions/activations}} [=map/exists=]: + 1. If its [=list/size=] is not 3, then [=exception/throw=] a {{TypeError}}. + 1. [=Assert=]: the type of its elements is {{MLActivation}}. + 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. Let |desc| a new {{MLOperandDescriptor}}. + 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to [ |numDirections|, |batchSize|, |hiddenSize| ]. + 1. Set |desc|.{{MLOperandDescriptor/type}} to |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/type}}. + 1. Let |output0| be the result of creating an MLOperand given [=this=] and |desc|. + 1. Let |output1| be the result of creating an MLOperand given [=this=] and |desc|. + 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to [ |steps|, |numDirections|, |batchSize|, |hiddenSize| ]. + 1. If |options|.{{MLLstmOptions/returnSequence}} is set to true: + 1. Let |output2| be the result of creating an MLOperand given [=this=] and |desc|. + 1. Let |output| be the array [ |output0|, |output1|, |output2| ]. + 1. Otherwise, Let |output| be the array [ |output0|, |output1| ]. + 1. Make a request to the underlying platform to: + 1. Let |opImpl| be an [=implementation-defined=] platform operator for the LSTM operation, given |weight|, |recurrentWeight|, |steps|, |hiddenSize| and |options|. + 1. Store a reference of |opImpl| in |output0|.{{MLOperand/[[operator]]}}, |output1|.{{MLOperand/[[operator]]}} and |output2|.{{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 |output0|.{{MLOperand/[[operand]]}}, |output1|.{{MLOperand/[[operand]]}} and |output2|.{{MLOperand/[[operand]]}}. + 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. + 1. Connect |output| 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. -
+  
+
     const numDirections = (options.direction == "both" ? 2 : 1);
     let hiddenState = options.initialHiddenState;
     let cellState = options.initialCellState;
@@ -2240,13 +3813,13 @@ partial interface MLGraphBuilder {
     let currentPeepholeWeight = [];
 
     for (let dir = 0; dir < numDirections; ++dir) {
-      currentWeight.push(builder.squeeze(builder.slice(weight, [dir, 0, 0], [1, 4 * hidden_size, input_size]), { axes: [0] }));
-      currentRecurrentWeight.push(builder.squeeze(builder.slice(recurrentWeight, [dir, 0, 0], [1, 4 * hidden_size, hidden_size]), { axes: [0] }));
-      currentBias.push(options.bias ? (builder.squeeze(builder.slice(options.bias, [dir, 0], [1, 4 * hidden_size]), { axes: [0] })) : null);
+      currentWeight.push(builder.squeeze(builder.slice(weight, [dir, 0, 0], [1, 4 * hiddenSize, inputSize]), { axes: [0] }));
+      currentRecurrentWeight.push(builder.squeeze(builder.slice(recurrentWeight, [dir, 0, 0], [1, 4 * hiddenSize, hiddenSize]), { axes: [0] }));
+      currentBias.push(options.bias ? (builder.squeeze(builder.slice(options.bias, [dir, 0], [1, 4 * hiddenSize]), { axes: [0] })) : null);
       currentRecurrentBias.push(options.recurrentBias ?
-        (builder.squeeze(builder.slice(options.recurrentBias, [dir, 0], [1, 4 * hidden_size]), { axes: [0] })) : null);
+        (builder.squeeze(builder.slice(options.recurrentBias, [dir, 0], [1, 4 * hiddenSize]), { axes: [0] })) : null);
       currentPeepholeWeight.push(options.peepholeWeight ?
-        (builder.squeeze(builder.slice(options.peepholeWeight, [dir, 0], [1, 3 * hidden_size]), { axes: [0] })) : null);
+        (builder.squeeze(builder.slice(options.peepholeWeight, [dir, 0], [1, 3 * hiddenSize]), { axes: [0] })) : null);
     }
 
     for (let step = 0; step < steps; ++step) {
@@ -2256,13 +3829,13 @@ partial interface MLGraphBuilder {
       let nextCell = null;
 
       for (let dir = 0; dir < numDirections; ++dir) {
-        currentHidden.push(builder.squeeze(builder.slice(hiddenState, [dir, 0, 0], [1, batch_size, hidden_size]), { axes: [0] }));
-        currentCell.push(builder.squeeze(builder.slice(cellState, [dir, 0, 0], [1, batch_size, hidden_size]), { axes: [0] }));
+        currentHidden.push(builder.squeeze(builder.slice(hiddenState, [dir, 0, 0], [1, batchSize, hiddenSize]), { axes: [0] }));
+        currentCell.push(builder.squeeze(builder.slice(cellState, [dir, 0, 0], [1, batchSize, hiddenSize]), { axes: [0] }));
       }
 
       for (let dir = 0; dir < numDirections; ++dir) {
         let slice = (dir == 1 || options.direction == "backward" ? steps - step - 1 : step);
-        let currentInput = builder.squeeze(builder.slice(input, [slice, 0, 0], [1, batch_size, input_size]), { axes: [0] });
+        let currentInput = builder.squeeze(builder.slice(input, [slice, 0, 0], [1, batchSize, inputSize]), { axes: [0] });
 
         let results = builder.lstmCell(
           currentInput, currentWeight[dir], currentRecurrentWeight[dir],
@@ -2286,9 +3859,9 @@ partial interface MLGraphBuilder {
       }
     }
 
-    return (sequence ? [hiddenState, cellState, sequence] : [hiddenState, cellState]);
-    
-
+ return (sequence ? [hiddenState, cellState, sequence] : [hiddenState, cellState]); + +
### The lstmCell() method ### {#api-mlgraphbuilder-lstmcell} @@ -2309,26 +3882,91 @@ partial interface MLGraphBuilder { optional MLLstmCellOptions options = {}); }; -
+ +{{MLLstmCellOptions}} has the following members: +
+ : bias + :: + An {{MLOperand}}. The 1-D input bias tensor of shape [4 * hiddenSize]. The ordering of the bias vectors in the first dimension of the tensor shape is specified according to the {{MLLstmCellOptions/layout}} argument. + + : recurrentBias + :: + An {{MLOperand}}. The 1-D recurrent bias tensor of shape [4 * hiddenSize]. The ordering of the bias vectors in the first dimension of the tensor shape is specified according to the {{MLLstmCellOptions/layout}} argument. + + : peepholeWeight + :: + An {{MLOperand}}. The 1-D weight tensor for peepholes of shape [3 * hiddenSize]. The pack ordering of the weight vectors is for the `input (i)`, `output (o)`, and `forget (f)` gate, respectively. + + : layout + :: + An {{MLLstmWeightLayout}}. The ordering of the weight and bias vectors for the internal gates of LSTM, specifically the `input (i)`, `output (o)`, `forget (f)`, and `cell (g)` gate, as indicated in the first dimension of the weight and bias tensor shapes. When not specified, the default layout is `"iofg"`. + + : activations + :: + A sequence of {{MLActivation}}. A sequence of three activation functions, the first one is used for the `input (i)`, `forget (f)`, and `output (o)` gate, the second one is used for the `cell (g)` gate, and the last used for filtering the output cell state before combining it with the result of the output gate to form the output hidden state. When not specified, they are assumed to be of the sigmoid function (`"sigmoid"`) followed by two hyperbolic tangent functions (`"tanh"`) respectively. +
+ +
**Arguments:** - - *input*: an {{MLOperand}}. The input 2-D tensor of shape [batch_size, input_size]. - - *weight*: an {{MLOperand}}. The 2-D input weight tensor of shape [4 * hidden_size, input_size]. The ordering of the weight vectors in the first dimension of the tensor shape is specified according to the *options.layout* argument. - - *recurrentWeight*: an {{MLOperand}}. The 2-D recurrent weight tensor of shape [4 * hidden_size, hidden_size]. The ordering of the weight vectors in the first dimension of the tensor shape is specified according to the *options.layout* argument. - - *hiddenState*: an {{MLOperand}}. The 2-D input hidden state tensor of shape [batch_size, hidden_size]. - - *cellState*: an {{MLOperand}}. The 2-D input cell state tensor of shape [batch_size, hidden_size]. + - *input*: an {{MLOperand}}. The input 2-D tensor of shape [batchSize, inputSize]. + - *weight*: an {{MLOperand}}. The 2-D input weight tensor of shape [4 * hiddenSize, inputSize]. The ordering of the weight vectors in the first dimension of the tensor shape is specified according to the *options.layout* argument. + - *recurrentWeight*: an {{MLOperand}}. The 2-D recurrent weight tensor of shape [4 * hiddenSize, hiddenSize]. The ordering of the weight vectors in the first dimension of the tensor shape is specified according to the *options.layout* argument. + - *hiddenState*: an {{MLOperand}}. The 2-D input hidden state tensor of shape [batchSize, hiddenSize]. + - *cellState*: an {{MLOperand}}. The 2-D input cell state tensor of shape [batchSize, hiddenSize]. - *hiddenSize*: an {{unsigned long}} scalar. The value of the second dimension of the output tensor shape. It indicates the number of features in the hidden state. - *options*: an optional {{MLLstmCellOptions}}. The optional parameters of the operation. - - *bias*: an {{MLOperand}}. The 1-D input bias tensor of shape [4 * hidden_size]. The ordering of the bias vectors in the first dimension of the tensor shape is specified according to the *options.layout* argument. - - *recurrentBias*: an {{MLOperand}}. The 1-D recurrent bias tensor of shape [4 * hidden_size]. The ordering of the bias vectors in the first dimension of the tensor shape is specified according to the *options.layout* argument. - - *peepholeWeight*: an {{MLOperand}}. The 1-D weight tensor for peepholes of shape [3 * hidden_size]. The pack ordering of the weight vectors is for the *input (i)*, *output (o)*, and *forget (f)* gate respectively. - - *layout*: an {{MLLstmWeightLayout}}. The ordering of the weight and bias vectors for the internal gates of LSTM, specifically the *input (i)*, *output (o)*, *forget (f)*, and *cell (g)* gate, as indicated in the first dimension of the weight and bias tensor shapes. When not specified, the default layout is *"iofg"*. - - *activations*: a sequence of {{MLActivation}}. A sequence of three activation functions, the first one is used for the *input (i)*, *forget (f)*, and *output (o)* gate, the second one is used for the *cell (g)* gate, and the last used for filtering the output cell state before combining it with the result of the output gate to form the output hidden state. When not specified, they are assumed to be of the sigmoid function (*"sigmoid"*) followed by two hyperbolic tangent functions (*"tanh"*) respectively. - **Returns:** a sequence of {{MLOperand}}. The first element of the sequence is the output hidden state of the current time step of the recurrent network. The following element is the output cell state. Both elements are 2-D tensors of shape [batch_size, hidden_size]. + **Returns:** a sequence of {{MLOperand}}. The first element of the sequence is the output hidden state of the current time step of the recurrent network. The following element is the output cell state. Both elements are 2-D tensors of shape [batchSize, hiddenSize]. +
+ +
+ + + The lstmCell(|input|, |weight|, |recurrentWeight|, |hiddenState|, |cellState|, |hiddenSize|, |options|) method steps are: + +
+ 1. [=Assert=]: the type of |input|, |weight|, |recurrentWeight|, |hiddenState| and |cellState| is {{MLOperand}}. + 1. If the [=rank=] of |input|, |weight|, |recurrentWeight|, |hiddenState| or |cellState| is not 2, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |batchSize| be |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0]. + 1. If |options|.{{MLLstmCellOptions/bias}} [=map/exists=]: + 1. [=Assert=]: its type is {{MLOperand}}. + 1. If its rank is not 1, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmCellOptions/bias}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0] is not 4 * |hiddenSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmCellOptions/recurrentBias}} [=map/exists=]: + 1. [=Assert=]: its type is {{MLOperand}}. + 1. If its rank is not 1, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmCellOptions/recurrentBias}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0] is not 4 * |hiddenSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmCellOptions/peepholeWeight}} [=map/exists=]: + 1. [=Assert=]: its type is {{MLOperand}}. + 1. If its rank is not 1, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmCellOptions/peepholeWeight}}.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[0] is not 3 * |hiddenSize|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLLstmCellOptions/activations}} [=map/exists=]: + 1. If its [=list/size=] is not 3, then [=exception/throw=] a {{TypeError}}. + 1. [=Assert=]: the type of its elements is {{MLActivation}}. + 1. Let |desc| a new {{MLOperandDescriptor}}. + 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to [ |batchSize|, |hiddenSize| ]. + 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 |output0| be the result of creating an MLOperand given [=this=] and |desc|. + 1. Let |output1| be the result of creating an MLOperand given [=this=] and |desc|. + 1. Let |output| be the array [ |output0|, |output1| ]. + 1. Make a request to the underlying platform to: + 1. Let |opImpl| be an [=implementation-defined=] platform operator for the LSTM cell operation, given |weight|, |recurrentWeight|, |hiddenState|, |cellState|, |hiddenSize| and |options|. + 1. Store a reference of |opImpl| in |output0|.{{MLOperand/[[operator]]}} and |output1|.{{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 |output0|.{{MLOperand/[[operand]]}} and |output1|.{{MLOperand/[[operand]]}}. + 1. Connect |input|.{{MLOperand/[[operand]]}} as input to |opImpl|. + 1. Connect |output| as output to |opImpl|. + 1. Return |output|. +
+
-
+
+
+ The behavior of this operation can be generically emulated via other operations as shown below, when the weight layout is the default *"iofg"* layout, and the activation functions of the input/forget/output gate and the cell gate/the cell state's filter for the output hidden state are of the operator types *sigmoid* and *tanh* respectively. -
+  
+
     const zero = builder.constant(0);
 
     // input gate (i)
@@ -2346,11 +3984,11 @@ partial interface MLGraphBuilder {
           builder.add(
             builder.matmul(
               input,
-              builder.transpose(builder.slice(weight, [0, 0], [hiddenSize, input_size]))
+              builder.transpose(builder.slice(weight, [0, 0], [hiddenSize, inputSize]))
             ),
             builder.matmul(
               hiddenState,
-              builder.transpose(builder.slice(recurrentWeight, [0, 0], [hiddenSize, hidden_size]))
+              builder.transpose(builder.slice(recurrentWeight, [0, 0], [hiddenSize, hiddenSize]))
             )
           )
         )
@@ -2372,11 +4010,11 @@ partial interface MLGraphBuilder {
           builder.add(
             builder.matmul(
               input,
-              builder.transpose(builder.slice(weight, [2 * hiddenSize, 0], [hiddenSize, input_size]))
+              builder.transpose(builder.slice(weight, [2 * hiddenSize, 0], [hiddenSize, inputSize]))
             ),
             builder.matmul(
               hiddenState,
-              builder.transpose(builder.slice(recurrentWeight, [2 * hiddenSize, 0], [hiddenSize, hidden_size]))
+              builder.transpose(builder.slice(recurrentWeight, [2 * hiddenSize, 0], [hiddenSize, hiddenSize]))
             )
           )
         )
@@ -2393,11 +4031,11 @@ partial interface MLGraphBuilder {
         builder.add(
           builder.matmul(
             input,
-            builder.transpose(builder.slice(weight, [3 * hiddenSize, 0], [hiddenSize, input_size]))
+            builder.transpose(builder.slice(weight, [3 * hiddenSize, 0], [hiddenSize, inputSize]))
           ),
           builder.matmul(
             hiddenState,
-            builder.transpose(builder.slice(recurrentWeight, [3 * hiddenSize, 0], [hiddenSize, hidden_size]))
+            builder.transpose(builder.slice(recurrentWeight, [3 * hiddenSize, 0], [hiddenSize, hiddenSize]))
           )
         )
       )
@@ -2418,11 +4056,11 @@ partial interface MLGraphBuilder {
           builder.add(
             builder.matmul(
               input,
-              builder.transpose(builder.slice(weight, [hiddenSize, 0], [hiddenSize, input_size]))
+              builder.transpose(builder.slice(weight, [hiddenSize, 0], [hiddenSize, inputSize]))
             ),
             builder.matmul(
               hiddenState,
-              builder.transpose(builder.slice(recurrentWeight, [hiddenSize, 0], [hiddenSize, hidden_size]))
+              builder.transpose(builder.slice(recurrentWeight, [hiddenSize, 0], [hiddenSize, hiddenSize]))
             )
           )
         )
@@ -2436,8 +4074,8 @@ partial interface MLGraphBuilder {
     let ht = builder.mul(o, builder.tanh(ct));
 
     return [ht, ct];
-    
-
+ +
### The matmul() method ### {#api-mlgraphbuilder-matmul} @@ -2447,31 +4085,67 @@ partial interface MLGraphBuilder { MLOperand matmul(MLOperand a, MLOperand b); }; -
+ +
**Arguments:** - - *a*: an {{MLOperand}}. The first input N-D tensor. - - *b*: an {{MLOperand}}. The second input N-D tensor. + - *a*: an {{MLOperand}}. The first N-dimensional input tensor. + - *b*: an {{MLOperand}}. The second N-dimensional input tensor. - **Returns:** an {{MLOperand}}. The output N-D tensor that contains the matrix + **Returns:** an {{MLOperand}}. The output tensor that contains the matrix product of two input tensors. - - Compute the matrix product of two input tensors. It behaves as following: - - If both *a* and *b* are 2-D, they are multiplied like conventional - matrices and produce a 2-D tensor as the output. - - If either *a* or *b* is N-D, N > 2, it is treated as a stack of - matrices with dimensions corresponding to the last two indices. The - matrix multiplication will be broadcasted accordingly by following - [[!numpy-broadcasting-rule]]. The output is a N-D tensor whose rank - is the maximum rank of the input tensors. For each dimension, except - the last two, of the output tensor, its size is the maximum size - along that dimension of the input tensors. - - If *a* is 1-D, it is converted to a 2-D tensor by prepending a 1 to - its dimensions. - - If *b* is 1-D, it is converted to a 2-D tensor by by appending a 1 to - its dimensions. - - If both *a* and *b* are 1-D, the operation is a vector dot-product, - which produces a scalar output.
+
+ Computes the matrix product of two input tensors as follows: + - If both *a* and *b* are 2-dimensional, they are multiplied like conventional + matrices and produce a 2-dimensional tensor as the output. + - If either *a* or *b* is `N`-dimensional where `N > 2`, it is treated as a stack of matrices with dimensions corresponding to the last two indices. The matrix multiplication will be broadcasted accordingly by following the [[!numpy-broadcasting-rule]]. The output is a `N`-dimensional tensor whose rank is the maximum [=rank=] of the input tensors. For each dimension, except the last two, of the output tensor, its size is the maximum size along that dimension of the input tensors. + - If *a* is 1-dimensional, it is converted to a 2-dimensional tensor by prepending a 1 to its dimensions. + - If *b* is 1-dimensional, it is converted to a 2-dimensional tensor by by appending a 1 to its dimensions. + - If both *a* and *b* are 1-dimensional, the operation is a vector dot-product, which produces a scalar output. +
+ +
+ + To calculate matmul output sizes, given |a| and |b| run the following steps: + +
+ 1. Let |shapeA| be |a|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} and |sizeA| the [=list/size=] of |shapeA|. + 1. Let |shapeB| be |b|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} and |sizeB| the [=list/size=] of |shapeB|. + 1. If |sizeA| and |sizeB| is 1, return `« 1 »`. + 1. If |sizeA| is 1 and |sizeB| is not, then insert 1 in the front of |shapeA| to become [ 1 | |shapeA| ] and let |sizeA| be 2. + 1. If |shapeA|[0] is not equal to |shapeB|[|sizeB| - 2], then [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. If |sizeB| is 1 and |sizeA| is not, then append 1 to |shapeB| to become [ |shapeB| | 1 ] and let |sizeB| be 2. + 1. If |shapeA|[|sizeA| - 1] is not equal to |shapeB|[0], then [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. Let |shape| be an array whose size |size| is the maximum of |sizeA| and |sizeB|. + 1. [=map/For each=] |index| in [=the range=] 0 to |size|, exclusive: + 1. Set |shape|[|index|] to the maximum of |shapeA|[|index|] and |shapeB|[|index|]. + 1. Return |shape|. +
+
+ +
+ + + The matmul(|a|, |b|) method steps are: + +
+ 1. [=Assert=]: the type of |a| and |b| is {{MLOperand}}. + 1. Let |desc| a new {{MLOperandDescriptor}}. + 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to the result of invoking the calculate matmul output sizes steps given |a| and |b|. + 1. If that throws an error, re-[=exception/throw=] the error. + 1. Set |desc|.{{MLOperandDescriptor/type}} to |a|.{{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 [=this=] and |desc|. + 1. Make a request to the underlying platform to: + 1. Let |opImpl| be an [=implementation-defined=] platform operator for the matrix multiplication operation. + 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 pad() method ### {#api-mlgraphbuilder-pad} Inflate the tensor with constant or mirrored values on the edges. @@ -2495,21 +4169,76 @@ partial interface MLGraphBuilder { optional MLPadOptions options = {}); }; -
+ +{{MLPadOptions}} has the following members: +
+ : mode + :: + An {{MLPaddingMode}} [=string=]. + Specifies the different ways to pad the tensor. + The default value is `"constant"`. + + : value + :: + A {{float}}. + Specifies the padding value when {{MLPadOptions/mode}} is set to `"constant"`. + The default value is 0. +
+ +
**Arguments:** - *input*: an {{MLOperand}}. The input tensor. - - *beginningPadding*: a sequence of {{unsigned long}}. The sequence of unsigned integer values indicating the number of padding values to add at the beginning of each input dimension, of length *N* where *N* is the rank of the input tensor. For each dimension *d* of *input*, *beginningPadding[d]* indicates how many values to add before the content in that dimension. - - *endingPadding*: a sequence of {{unsigned long}}. The sequence of unsigned integer values indicating the number of padding values to add at the ending of each input dimension, of length *N* where *N* is the rank of the input tensor. For each dimension *d* of *input*, *endingPadding[d]* indicates how many values to add after the content in that dimension. + - *beginningPadding*: a sequence of {{unsigned long}}. The sequence of unsigned integer values indicating the number of padding values to add at the beginning of each input dimension, of length *N* where *N* is the [=rank=] of the input tensor. For each dimension *d* of *input*, *beginningPadding[d]* indicates how many values to add before the content in that dimension. + - *endingPadding*: a sequence of {{unsigned long}}. The sequence of unsigned integer values indicating the number of padding values to add at the ending of each input dimension, of length *N* where *N* is the [=rank=] of the input tensor. For each dimension *d* of *input*, *endingPadding[d]* indicates how many values to add after the content in that dimension. - *options*: an optional {{MLPadOptions}}. The optional parameters of the operation. - - *mode*: an {{MLPaddingMode}}. The different ways to pad the tensor. When not set, it's assumed to be "constant". - - *value*: a {{float}}. The pad value when the *options.mode* is set to *"constant"*. When not set, it's assumed to be 0. **Returns:** an {{MLOperand}}. The padded output tensor. Each dimension of the output tensor can be calculated as follow: *output size = beginning padding + input size + ending padding* +
-
-
+
+ + To calculate padding output sizes, given |input|, |beginningPadding| and |endingPadding|, run the following steps: + +
+ 1. Let |shape| be a copy of |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. + 1. For |index| in [=the range=] 0 to the [=rank=] of |shape|, exclusive: + 1. Add to |shape|[|index|] the value of |beginningPadding|[|index|]. + 1. Add to |shape|[|index|] the value of |endingPadding|[|index|]. + 1. Return |shape|. +
+
+ +
+ + + The pad(|input|, |beginningPadding|, |endingPadding|, |options|) method steps are: + +
+ 1. [=Assert=]: the type of |input| is {{MLOperand}}. + 1. If the [=list/size=] of |beginningPadding| and |endingPadding| is not equal to the [=rank=] of |input|, then then [=exception/throw=] a "{{TypeError}}". + 1. Let |desc| be a copy of |input|.{{MLOperand/[[descriptor]]}}. + 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to the result of invoking the calculate padding output sizes steps given |input|, |beginningPadding| and |endingPadding|. + 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 padding operation, given |beginningPadding|, |endingPadding| 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]]}} as input to |opImpl|. + 1. Connect |output|.{{MLOperand/[[operand]]}} as output to |opImpl|. + 1. Return |output|. +
+
+ +
+
+ + Examples for constant, edge, reflection and symmetric padding: + +
     // input: [[1,2,3], [4,5,6]]
     const input = builder.constant(
       { type: 'float32', dimensions: [2,3] }, new Float32Array([1,2,3,4,5,6]));
@@ -2544,8 +4273,8 @@ partial interface MLGraphBuilder {
     //     [5,4,4,5,6,6,5],
     //     [5,4,4,5,6,6,5]]
     builder.pad(input, beginningPadding, endingPadding, { mode: "symmetric" });
-    
-
+
+
### Pooling operations ### {#api-mlgraphbuilder-pool2d} @@ -2573,34 +4302,12 @@ partial interface MLGraphBuilder { MLOperand maxPool2d(MLOperand input, optional MLPool2dOptions options = {}); }; -
+ +
**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. - - *windowDimensions*: a sequence of {{unsigned long}} of length 2. The dimensions of the sliding window, - [window_height, window_width]. If not present, the window dimensions are assumed to be the height - and width dimensions of the input shape. - - *padding*: a sequence of {{unsigned long}} of length 4. The additional rows and columns added to the beginning and ending of each spatial dimension of *input*, [beginning_height, ending_height, beginning_width, ending_width]. If not present, the values are assumed to be [0,0,0,0]. - - *strides*: a sequence of {{unsigned long}} of length 2. The stride of the - sliding window for each spatial dimension of *input*, - [stride_height, stride_width]. If not present, the values are assumed to be [1,1]. - - *dilations*: a sequence of {{unsigned long}} of length 2. The dilation factor - for each spatial dimension of *input*, [dilation_height, dilation_width]. - If not present, the values are assumed to be [1,1]. - - *autoPad*: an {{MLAutoPad}}. The automatic input padding options. By default, this argument is set to *"explicit"*, which means that the values in the *options.padding* array should be used for input padding. When the option is set other than *"explicit"*, the values in the *options.padding* array are ignored. With the *"same-upper"* option, the padding values are automatically computed such that the additional ending padding of the spatial input dimensions would allow all of the input values in the corresponding dimension to be filtered. The *"same-lower"* option is similar but padding is applied to the beginning padding of the spatial input dimensions instead of the ending one. - - *layout*: an {{MLInputOperandLayout}}. The default value is *"nchw"*. This option specifies the - layout format of the input and output tensor as follow: - - "nchw": - - input tensor: [batches, channels, height, width] - - output tensor: [batches, channels, height, width] - - "nhwc": - - input tensor: [batches, height, width, channels] - - output tensor: [batches, height, width, channels] - - *roundingType*: an {{MLRoundingType}}. The option specifies the rounding function used to compute the output shape. - - *outputSizes*: a sequence of {{unsigned long}} of length 2. The sizes of the two spacial dimensions of the output tensor. When the output sizes are explicitly specified, the options.roundingType is ignored. If not specified, the output sizes are automatically computed. **Returns:** an {{MLOperand}}. The output 4-D tensor that contains the result of the reduction. The logical shape is interpreted according to the @@ -2611,46 +4318,200 @@ partial interface MLGraphBuilder { 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 + :: + A sequence of {{unsigned long}} of length 2: [windowHeight, windowWidth]. + Specifies the dimensions of the sliding window. + The default value for the window dimensions are the height and width dimensions of the input shape. + + : padding + :: + A sequence of {{unsigned long}} of length 4: [beginningHeight, endingHeight, beginningWidth, endingWidth]. + Specifies the additional rows and columns added to the beginning and ending of each spatial dimension of the convolution input. + The default value is [0,0,0,0]. + + : strides + :: + A sequence of {{unsigned long}} of length 2: [strideHeight, strideWidth]. + Specifies the stride of the sliding window for each spatial dimension of the convolution input. + The default value is [1,1]. + + : dilations + :: + A sequence of {{unsigned long}} of length 2: [dilationHeight, dilationWidth]. Specifies the dilation factor for each spatial dimension applied on the convolution filter (kernel). + The default value is [1,1]. + + : autoPad + :: + An {{MLAutoPad}} [=string=]. + Specifies the automatic input padding options. + The default value is *"explicit"*, which means that the values in the {{MLPool2dOptions/padding}} array should be used for input padding. + When the option is set other than *"explicit"*, the values in the {{MLPool2dOptions/padding}} array are ignored. + + With the *"same-upper"* option, the padding values are automatically computed such that the additional ending padding of the spatial input dimensions would allow all of the input values in the corresponding dimension to be filtered. + + The *"same-lower"* option is similar but padding is applied to the beginning padding of the spatial input dimensions instead of the ending one. + + : layout + :: + An {{MLInputOperandLayout}} [=string=]. + Specifies the layout format of the input and output tensor as follows: + - **"nchw"** + - input tensor: *[batches, inputChannels, height, width]* + - output tensor: *[batches, outputChannels, height, width]* + - **"nhwc"**: + - input tensor: *[batches, height, width, inputChannels]* + - output tensor: *[batches, height, width, outputChannels]* + The default value is *"nchw"*. + + : roundingType + :: + An {{MLRoundingType}} [=string=]. + Specifies the rounding function used to compute the output shape. + + : outputSizes + :: + A sequence of {{unsigned long}} of length 2. + 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. + +
+ +
+ + + To create pooling operation given |op|, |input| and |options|, run the following steps: + +
+ 1. [=Assert=]: |op| is one of "averagePool2d", "l2Pool2d", "maxPool2d". + 1. [=Assert=]: the type of |input| is {{MLOperand}}. + 1. If the [=list/size=] of |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} is not 4, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLPool2dOptions/windowDimensions}} [=map/exists=] and its [=list/size=] is not 2, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Otherwise, set |options|.{{MLPool2dOptions/windowDimensions}} to the height and width dimensions of the shape of |input|. + 1. If |options|.{{MLPool2dOptions/outputSizes}} [=map/exists=], or if |options|.{{MLPool2dOptions/padding}} does not [=map/exist=], set |options|.{{MLPool2dOptions/padding}} to `« 0, 0, 0, 0 »`. + 1. If the len[=list/size=]gth of |options|.{{MLPool2dOptions/padding}} is not 4, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLPool2dOptions/strides}} does not [=map/exist=], set |options|.{{MLPool2dOptions/strides}} to `« 1, 1 »`. + 1. If the [=list/size=] of |options|.{{MLPool2dOptions/strides}} is not 2, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If any value in |options|.{{MLPool2dOptions/strides}} is not greater than 0, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLPool2dOptions/outputSizes}} [=map/exists=]: + 1. If the [=list/size=] of |options|.{{MLPool2dOptions/outputSizes}} is not 2, then [=exception/throw=] a {{TypeError}}. + 1. If the elements of |options|.{{MLPool2dOptions/outputSizes}} are not smaller than the elements at the same dimension (index) for |options|.{{MLPool2dOptions/strides}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLPool2dOptions/dilations}} does not [=map/exist=], set |options|.{{MLPool2dOptions/dilations}} to `« 1, 1 »`. + 1. If the [=list/size=] of |options|.{{MLPool2dOptions/dilations}} is not 2, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If any value in |options|.{{MLPool2dOptions/dilations}} is not greater than 0, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If |options|.{{MLPool2dOptions/autoPad}} is not `"explicit"`, set |options|.{{MLPool2dOptions/padding}} to `« 0, 0, 0, 0 »`. + 1. Let |desc| be a copy of |input|.{{MLOperand/[[descriptor]]}}. + 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. Make a request to the underlying platform to: + 1. Calculate the output dimensions given |input| and |options|. Let |desc|.{{MLOperandDescriptor/dimensions}} be the result of that. + 1. Let |output| be the result of creating an MLOperand given [=this=] and |desc|. + 1. Let |opImpl| be an [=implementation-defined=] platform operator for the |op| pooling 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 pooling algorithms are supported. + +
+ The averagePool2d(|input|, |options|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/pooling-op | create pooling operation=] given `"averagePool2d"`, |input| and |options|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. +
+ +
+ The l2Pool2d(|input|, |options|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/pooling-op | create pooling operation=] given `"l2Pool2d"`, |input| and |options|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. +
+ +
+ The maxPool2d(|input|, |options|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/pooling-op | create pooling operation=] given `"maxPool2d"`, |input| and |options|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. +
+
+ ### The prelu() method ### {#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)`. +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)`. -
+ +
**Arguments:** - - *x*: an {{MLOperand}}. The input tensor. - - *slope*: an {{MLOperand}}. The slope tensor. Its shape is either the same as, or unidirectionally broadcastable to the shape of input tensor *x* according to [[!numpy-broadcasting-rule]]. + - *input*: an {{MLOperand}}. The input tensor. + - *slope*: an {{MLOperand}}. The slope tensor. Its shape is either the same as, or unidirectionally broadcastable to the shape of input tensor *input* according to [[!numpy-broadcasting-rule]]. **Returns:** - - an {{MLOperand}}. The output tensor of the same shape as *x*. + - an {{MLOperand}}. The output tensor of the same shape as *input*. +
-
+
+ + + The prelu(|input|, |slope|) method steps are: + +
+ 1. [=Assert=]: the type of |input| and |slope| is {{MLOperand}}. + 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 |slope|.{{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 PreLU operation, given |slope|. + 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 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. +
     return builder.add(builder.max(builder.constant(0), x),
                        builder.mul(slope, builder.min(builder.constant(0), x)));
     
-
+
- ### Reduction operations ### {#api-mlgraphbuilder-reduce} -Reduce the input along the dimensions given in *axes*. +Reduce the input tensor along all dimensions, or along the axes specified in the {{MLReduceOptions/axes}} array parameter. For each specified axis, the dimension with that index is reduced, i.e. the resulting tensor will not contain it, unless the {{MLReduceOptions/keepDimensions}} option is specified. The values of the resulting tensor are calculated using the specified reduction function that takes as parameters all the values across the reduced dimension. -
+ +
**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 input tensor. + - *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 size of 1. + - *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. @@ -2694,34 +4558,177 @@ partial interface MLGraphBuilder { - *SumSquare*: Compute the sum of the square of all the input values along the axes.
-### The relu() method ### {#api-mlgraphbuilder-relu} +
+ + + 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=]: 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}}. + 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 |op| reduce 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 reduce algorithms are supported. + +
+ 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|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. +
+ +
+ The reduceL2(|input|, |options|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/reduce-op | create reduce operation=] given "reduceL2", |input| and |options|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. +
+ +
+ The reduceLogSum(|input|, |options|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/reduce-op | create reduce operation=] given "reduceLogSum", |input| and |options|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. +
+ +
+ The reduceLogSumExp(|input|, |options|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/reduce-op | create reduce operation=] given "reduceLogSumExp", |input| and |options|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. +
+ +
+ The reduceMax(|input|, |options|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/reduce-op | create reduce operation=] given "reduceMax", |input| and |options|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. +
+ +
+ The reduceMean(|input|, |options|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/reduce-op | create reduce operation=] given "reduceMean", |input| and |options|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. +
+ +
+ The reduceMin(|input|, |options|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/reduce-op | create reduce operation=] given "reduceMin", |input| and |options|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. +
+ +
+ The reduceProduct(|input|, |options|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/reduce-op | create reduce operation=] given "reduceProduct", |input| and |options|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. +
+ +
+ The reduceSum(|input|, |options|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/reduce-op | create reduce operation=] given "reduceSum", |input| and |options|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. +
+ +
+ The reduceSumSquare(|input|, |options|) method steps are: + 1. Let |output| be the result of running the [=MLGraphBuilder/reduce-op | create reduce operation=] given "reduceSumSquare", |input| and |options|. + 1. If that [=exception/throws=] an error, then re-[=exception/throw=] the error. + 1. Return |output|. +
+
+ +### The relu() method ### {#api-mlgraphbuilder-relu-method} Compute the rectified linear function of the input tensor. + -
- **Arguments:** - - *x*: an {{MLOperand}}. The input tensor. - - **Returns:** - - an {{MLOperand}}. The output tensor of the same shape as *x*. - - an {{MLActivation}}. The activation function representing the relu operation. -
+
+
+ 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. +
     return builder.max(builder.constant(0), x);
     
-
+ +
+ +#### The {{MLGraphBuilder/relu(input)}} method #### {#api-mlgraphbuilder-relu-input} +
+ **Arguments:** + - *input*: an {{MLOperand}}. The input tensor. + + **Returns:** + - an {{MLOperand}}. The output tensor of the same shape as *input*. +
+ +
+ + + The relu(|input|) method steps are: + +
+ 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|. + 1. Make a request to the underlying platform to: + 1. Let |opImpl| be an [=implementation-defined=] platform operator for the ReLU operation. + 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 {{MLGraphBuilder/relu()}} method #### {#api-mlgraphbuilder-relu} +
+ **Arguments:** + - None. + + **Returns:** + - an {{MLActivation}}. The activation function representing the relu operation.
-### The resample2d() method ### {#api-mlgraphbuilder-resample2d} +
+ + The relu() method steps are: + +
+ 1. Let |op| be the result of creating an MLActivation given [=this=] and `"relu"`. + 1. If that [=exception/throws=] an error, re-[=exception/throw=] the error. + 1. Return |op|. +
+
+ +### The resample2d() method ### {#api-mlgraphbuilder-resample2d-method} Resample the tensor values from the source to the destination spatial dimensions according to the scaling factors. -
+
**Arguments:** - *input*: an {{MLOperand}}. The input 4-D tensor. - *options*: an optional {{MLResample2dOptions}}. The optional parameters of the operation. - - *mode*: an {{MLInterpolationMode}}. The interpolation algorithm used to fill the output tensor values. - If not set, it is assumed to be the *Nearest Neighbor* interpolation. - - *scales*: a sequence of {{float}} of length 2. Each value represents the scaling factor used to scale in each spatial dimensions of input, [scale_height, scale_width]. If not set, the values are assumed to be [1.0, 1.0]. - - *sizes*: a sequence of {{unsigned long}} of length 2. The target sizes for each spatial dimensions of input, [size_height, size_width]. When the target sizes are specified, the *options.scales* argument is ignored as the scaling factor values are derived from the target sizes of each spatial dimension of input. - - *axes*: a sequence of {{unsigned long}} of length 2. The two consecutive dimensions of the input tensor to which the interpolation algorithm applies. The valid values in the sequence are [0, 1], [1, 2] or [2, 3]. When not specified, the sequence is assumed to be [2, 3]. **Returns:** an {{MLOperand}}. The output 4-D tensor.
-### The reshape() method ### {#api-mlgraphbuilder-reshape} +{{MLResample2dOptions}} has the following members: +
+ : mode + :: + An {{MLInterpolationMode}} [=string=]. + Specifies the interpolation algorithm used to fill the output tensor values. + The default value is `"nearest-neighbor"`, standing for *Nearest Neighbor* interpolation. + + : scales + :: + A sequence of {{float}} of length 2. + Specifies the scaling factor in each spatial dimensions of the input: [scaleHeight, scaleWidth]. + The default value is [1.0, 1.0]. + + : sizes + :: + A sequence of {{unsigned long}} of length 2. + Specifies the target sizes for each spatial dimensions of the input: [sizeHeight, sizeWidth]. When the target sizes are specified, the {{MLResample2dOptions/scales}} argument is ignored, since the scaling factor values are derived from the target sizes of each spatial dimension of the input. + + : axes + :: + A sequence of {{unsigned long}} of length 2. + Specifies the two consecutive dimensions of the input tensor to which the interpolation algorithm applies. The valid values in the sequence are [0, 1], [1, 2] or [2, 3]. + The default value is [2, 3]. +
+ +
+ + + To check resample options given |options|, run the following steps: + +
+ 1. If |options|.{{MLResample2dOptions/scales}} does not [=map/exist=], set it to to `« 1.0, 1.0 »`. + 1. Otherwise, if any of its values is not greater than 0, or if its [=list/size=] is not 2, return false. + 1. If |options|.{{MLResample2dOptions/sizes}} [=map/exists=], and if its size is not 2, or if any of its values is not greater than 0, return false. + 1. If |options|.{{MLResample2dOptions/axes}} does not [=map/exists=], set it to `« 2, 3 »`. + 1. Otherwise, if its value is not one of `« 0, 1», « 1, 2», « 2, 3 »`, return false. + 1. Return true. +
+
+ +
+ + + To resample output sizes given |input| and |options|, run the following steps: + +
+ 1. Let |desc| be an {{MLOperandDescriptor}} initialized to |input|.{{MLOperand/[[descriptor]]}}. + 1. For |index| in [=the range=] 0 to the [=list/size=] of |options|.{{MLResample2dOptions/axes}}, exclusive: + 1. If |options|.{{MLResample2dOptions/sizes}} [=map/exists=], set |desc|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[|options|.{{MLResample2dOptions/axes}}[|index|]] to |options|.{{MLResample2dOptions/sizes}}[|index|] and return |desc|. + 1. Otherwise, set |desc|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[|options|.{{MLResample2dOptions/axes}}[|index|]] to |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[|index|] multiplied by |options|.{{MLResample2dOptions/scales}}. + 1. Return |desc|. +
+
+ +
+ + + The resample2d(|input|, |options|) method steps are: + +
+ 1. If the [=list/size=] of |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} is not 4, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If running the check resample options steps given |options| returns false, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |desc| be the result of running the resample output sizes steps given |options|. + 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 |desc|. + 1. Make a request to the underlying platform to: + 1. Let |opImpl| be an [=implementation-defined=] platform operator for the resample 2D 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 reshape() method ### {#api-mlgraphbuilder-reshape-method} Alter the shape of a tensor to a new shape. Reshape does not copy or change the content of the tensor. It just changes the tensor's logical dimensions for the subsequent operations. -
+
**Arguments:** - *input*: an {{MLOperand}}. The input tensor. - - *newShape*: a sequence of {{nullable}} {{unsigned long}}. The shape of the output tensor. + - *newShape*: a sequence of [=nullable type|nullable=] {{unsigned long}}. The shape of the output tensor. The number of elements implied by *newShape* must be the same as the number of elements in the input tensor. Only one component of *newShape* can be the special value of `null`. The size of the dimension @@ -2775,27 +4855,55 @@ partial interface MLGraphBuilder { tensor is specified by the *newShape* argument.
-### The sigmoid() method ### {#api-mlgraphbuilder-sigmoid} +
+ + + The reshape(|input|, |newShape|) method steps are: + +
+ 1. [=Assert=]: the type of |input| is {{MLOperand}}. + 1. Let |outputShape| be an empty array of {{unsigned long}}. + 1. If |newShape| is a scalar [=number=], set |outputShape| to `« 1 »`. + 1. Otherwise, if |newShape| is an array of {{unsigned long}}: + 1. If the [=list/size=] of |newShape| is 0, set |outputShape| to `« 1 »` (reshaping to scalar). + 1. If |newShape| contains more than one `null` value, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If any value in |newShape| is 0, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |inputElementCount| be the product of all elements in |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. + 1. If |newShape| contains a `null` value, set that value to |inputElementCount| divided by the product of all other values in |newShape|. + 1. If that value is too large for {{unsigned long}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. If product of all values in |newShape| is not equal to |inputElementCount|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. + 1. Let |desc| be a copy of |input|.{{MLOperand/[[descriptor]]}}. + 1. Set |desc|.{{MLOperandDescriptor/dimensions}} to |newShape|. + 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. 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 reshape operation. + 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 sigmoid() method ### {#api-mlgraphbuilder-sigmoid-method} Compute the sigmoid function of the input tensor. The calculation follows the expression `1 / (exp(-x) + 1)`. -
- **Arguments:** - - *x*: an {{MLOperand}}. The input tensor. - - **Returns:** - - an {{MLOperand}}. The output tensor of the same shape as *x*. - - an {{MLActivation}}. The activation function representing the sigmoid operation. -
+
+
+ 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. +
     return builder.div(
               builder.constant(1),
@@ -2803,9 +4911,58 @@ partial interface MLGraphBuilder {
                 builder.exp(builder.neg(x)),
                 builder.constant(1)));
     
-
+ +
+ +#### The {{MLGraphBuilder/sigmoid(input)}} method #### {#api-mlgraphbuilder-sigmoid-input} +
+ **Arguments:** + - *input*: an {{MLOperand}}. The input tensor. + + **Returns:** + - an {{MLOperand}}. The output tensor of the same shape as *input*. +
+ +
+ + + The sigmoid(|input|) method steps are: + +
+ 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|. + 1. Make a request to the underlying platform to: + 1. Let |opImpl| be an [=implementation-defined=] platform operator for the sigmoid operation. + 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 {{MLGraphBuilder/sigmoid()}} method #### {#api-mlgraphbuilder-sigmoid} +
+ **Arguments:** + - None. + + **Returns:** + - an {{MLActivation}}. The activation function representing the sigmoid operation.
+
+ + The sigmoid() method steps are: + +
+ 1. Let |op| be the result of creating an MLActivation given [=this=] and `"sigmoid"`. + 1. If that [=exception/throws=] an error, re-[=exception/throw=] the error. + 1. Return |op|. +
+
+ ### The slice() method ### {#api-mlgraphbuilder-slice} Produce a slice of the input tensor. -
+
**Arguments:** - *input*: an {{MLOperand}}. The input tensor. - - *starts*: a sequence of {{unsigned long}}. The sequence of unsigned integer values indicating the starting index to slice of each input dimension, of length N where N is the rank of the input tensor. For each dimension *d* of *input*, *starts[d]* indicates the starting index to slice in that dimension. The starting index must be in the range [0, input size - 1] in that dimension. - - *sizes*: a sequence of {{unsigned long}}. The sequence of unsigned integer values indicating the number of elements to slice of each input dimension, of length N where N is the rank of the input tensor. For each dimension *d* of *input*, *sizes[d]* indicates the number of elements to slice in that dimension. The size must not be 0 and must satisfy the constraint *starting index + size <= input size* in that dimension. + - *starts*: a sequence of {{unsigned long}}. The sequence of unsigned integer values indicating the starting index to slice of each input dimension, of length N where N is the [=rank=] of the input tensor. For each dimension *d* of *input*, *starts[d]* indicates the starting index to slice in that dimension. The starting index must be in the range [0, input size - 1] in that dimension. + - *sizes*: a sequence of {{unsigned long}}. The sequence of unsigned integer values indicating the number of elements to slice of each input dimension, of length N where N is the [=rank=] of the input tensor. For each dimension *d* of *input*, *sizes[d]* indicates the number of elements to slice in that dimension. The size must not be 0 and must satisfy the constraint *starting index + size <= input size* in that dimension. **Returns:** an {{MLOperand}}. The output tensor of the same rank as the input tensor with tensor values stripped to the specified starting and ending indices in each dimension.
-### The softmax() method ### {#api-mlgraphbuilder-softmax} +
+ + + The slice(|input|, |starts|, |sizes|) method steps are: + +
+ 1. [=Assert=]: the type of |input| is {{MLOperand}}. + 1. If |sizes|.size is 0, then [=exception/throw=] a {{TypeError}}. + 1. If the [=list/size=] of |starts| and |sizes| is not equal to the rank of |input|, 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 slice operation, given |starts| and |sizes|. + 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 softmax() method ### {#api-mlgraphbuilder-softmax-method} Compute the [softmax](https://en.wikipedia.org/wiki/Softmax_function) values of the 2-D input tensor along axis 1. -
- **Arguments:** - - *x*: an {{MLOperand}}. The input 2-D tensor. - - **Returns:** - - an {{MLOperand}}. The output 2-D tensor that contains the softmax results, of the same shape as the input tensor. - - an {{MLActivation}}. The activation function representing the softmax operation. -
+
+
+ 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. -
+  
+
     // This sample deploys a well-known implementation trick [1] to compute the
     // exponentials of the distances to the max value, instead of the exponentials
     // of the input values itself, in order to increase the numerical stability of
@@ -2853,11 +5028,61 @@ partial interface MLGraphBuilder {
     const max_x = builder.reduceMax(x, { axes: [1], keepDimensions: true });
     const exp_x = builder.exp(builder.sub(x, max_x));
     return builder.div(exp_x, builder.reduceSum(exp_x, { axes: [1], keepDimensions: true }));
-    
-
+ + +
+ +#### The {{MLGraphBuilder/softmax(input)}} method #### {#api-mlgraphbuilder-softmax-input} +
+ **Arguments:** + - *input*: an {{MLOperand}}. The input 2-D tensor. + + **Returns:** + - an {{MLOperand}}. The output 2-D tensor that contains the softmax results, of the same shape as *input*. +
+ +
+ + + The softmax(|input|) method steps are: + +
+ 1. [=Assert=]: the type of |input| is {{MLOperand}}. + 1. If the [=list/size=] of |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} is not 2, 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 softmax operation. + 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 {{MLGraphBuilder/softmax()}} method #### {#api-mlgraphbuilder-softmax} +
+ **Arguments:** + - None. + + **Returns:** + - an {{MLActivation}}. The activation function representing the softmax operation.
-### The softplus() method ### {#api-mlgraphbuilder-softplus} +
+ + The softmax() method steps are: + +
+ 1. Let |op| be the result of creating an MLActivation given and `"softmax"`. + 1. If that [=exception/throws=] an error, re-[=exception/throw=] the error. + 1. Return |op|. +
+
+ +### The softplus() method ### {#api-mlgraphbuilder-softplus-method} Compute the softplus function of the input tensor. The calculation follows the expression `ln(1 + exp(steepness * x)) / steepness`. -
- **Arguments:** - - *x*: an {{MLOperand}}. The input tensor. - - **Returns:** - - an {{MLOperand}}. The output tensor of the same shape as *x*. - - an {{MLActivation}}. The activation function representing the softplus operation. -
+
+
+ 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. +
     return builder.div(
               builder.log(
@@ -2890,36 +5111,139 @@ partial interface MLGraphBuilder {
                   builder.constant(1))),
               builder.constant(options.steepness));
     
-
+ +
+ +{{MLSoftplusOptions}} has the following members: +
+ : steepness + :: + A {{float}} scalar parameter. + The default value is 1. +
+ +#### The {{MLGraphBuilder/softplus(input, options)}} method #### {#api-mlgraphbuilder-softplus-input-options} +
+ **Arguments:** + - *input*: an {{MLOperand}}. The input tensor. + - *options*: an optional {{MLSoftplusOptions}}. The optional parameters of the operation. + + **Returns:** + - an {{MLOperand}}. The output tensor of the same shape as *input*. +
+ +
+ + + The softplus(|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 softplus 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 {{MLGraphBuilder/softplus(options)}} method #### {#api-mlgraphbuilder-softplus-options} +
+ **Arguments:** + - *options*: an optional {{MLSoftplusOptions}}. The optional parameters of the operation. + + **Returns:** + - an {{MLActivation}}. The activation function representing the softplus operation.
-### The softsign() method ### {#api-mlgraphbuilder-softsign} +
+ + + The softplus(|options|) method steps are: + +
+ 1. Let |op| be the result of creating an MLActivation given [=this=], `"softplus"` and |options|. + 1. If that [=exception/throws=] an error, re-[=exception/throw=] the error. + 1. Return |op|. +
+
+ +### The softsign() method ### {#api-mlgraphbuilder-softsign-method} Compute the softsign function of the input tensor. The calculation follows the expression `x / (1 + |x|)`. -
- **Arguments:** - - *x*: an {{MLOperand}}. The input tensor. - - **Returns:** - - an {{MLOperand}}. The output tensor of the same shape as *x*. - - an {{MLActivation}}. The activation function representing the softsign operation. -
+
+
+ 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. +
     return builder.div(x, builder.add(builder.constant(1), builder.abs(x)));
     
-
+ +
+ +#### The {{MLGraphBuilder/softsign(input)}} method #### {#api-mlgraphbuilder-softsign-input} +
+ **Arguments:** + - *input*: an {{MLOperand}}. The input tensor. + + **Returns:** + - an {{MLOperand}}. The output tensor of the same shape as *input*. +
+ +
+ + + The softsign(|input|) method steps are: + +
+ 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|. + 1. Make a request to the underlying platform to: + 1. Let |opImpl| be an [=implementation-defined=] platform operator for the softsign operation. + 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 {{MLGraphBuilder/softsign()}} method #### {#api-mlgraphbuilder-softsign} +
+ **Arguments:** + - None. + + **Returns:** + - an {{MLActivation}}. The activation function representing the softsign operation.
+
+ + The softsign() method steps are: + +
+ 1. Let |op| be the result of creating an MLActivation given [=this=] and `"softsign"`. + 1. If that [=exception/throws=] an error, re-[=exception/throw=] the error. + 1. Return |op|. +
+
+ ### The split() method ### {#api-mlgraphbuilder-split} Split the input tensor into a number of sub tensors along the given axis. -
+ +
**Arguments:** - *input*: an {{MLOperand}}. The input tensor. - *splits*: an {{unsigned long}} or a sequence of {{unsigned long}}. If an {{unsigned long}}, it specifies the number of output tensors along the axis. The number must evenly divide the dimension size of *input* along *options.axis*. If a sequence of {{unsigned long}}, it specifies the sizes of each output tensor along the *options.axis*. The sum of sizes must equal to the dimension size of *input* along *options.axis*. - *options*: an optional {{MLSplitOptions}}. The optional parameters of the operation. - - *axis*: an {{unsigned long}} scalar. The dimension along which to split. Its value must be in the range [0, N-1] where N is the rank of input tensor. Default to 0. - **Returns:** a sequence of {{MLOperand}}. The splitted output tensors. If *splits* is an {{unsigned long}}, the length of the output sequence equals to *splits*. The shape of each output tensor is the same as *input* except the dimension size of *axis* equals to the quotient of dividing the dimension size of *input* along *axis* by *splits*. If *splits* is a sequence of {{unsigned long}}, the length of the output sequence equals to the length of *splits*. The shape of the i-th output tensor is the same as as *input* except along *axis* where the dimension size is *splits[i]*. + **Returns:** a sequence of {{MLOperand}}. The splitted output tensors. If *splits* is an {{unsigned long}}, the [=list/size=] of the output sequence equals to *splits*. The shape of each output tensor is the same as *input* except the dimension size of *axis* equals to the quotient of dividing the dimension size of *input* along *axis* by *splits*. If *splits* is a sequence of {{unsigned long}}, the [=list/size=] of the output sequence equals to the [=list/size=] of *splits*. The shape of the i-th output tensor is the same as as *input* except along *axis* where the dimension size is *splits[i]*. +
-
+{{MLSplitOptions}} has the following members: +
+ : axis + :: + An {{unsigned long}} scalar. The dimension along which to split. Its value must be in the range [0, N-1] where N is the [=rank=] of the input tensor. + The default value is 0. +
+ +
+ + + The split(|input|, |splits|, |options|) method steps are: + +
+ 1. [=Assert=]: the type of |input| is {{MLOperand}}. + 1. If |splits| is an {{unsigned long}}, and |input|.{{MLOperandDescriptor/dimensions}}[|options|.{{MLSplitOptions/axis}}] % |splits| is not 0, then [=exception/throw=] a {{TypeError}}. + 1. If |splits| is a sequence of {{unsigned long}}, and the sum of its elements is not equal to |input|.{{MLOperandDescriptor/dimensions}}[|options|.{{MLSplitOptions/axis}}], 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 split operation, given |splits| 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]]}} as input 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. -
+  
+
     // This sample shows the case that the splits parameter is an array.
     const outputs = [];
     let starts = Array(input_rank).fill(0);
@@ -2960,12 +5318,12 @@ partial interface MLGraphBuilder {
       start += size;
     }
     return outputs;
-    
-
+ +
### The squeeze() method ### {#api-mlgraphbuilder-squeeze} -Reduce the rank of a tensor by eliminating dimensions with size 1 of the tensor shape. Squeeze only affects the tensor's logical dimensions. It does not copy or change the content in the tensor. +Reduce the [=rank=] of a tensor by eliminating dimensions with size 1 of the tensor shape. Squeeze only affects the tensor's logical dimensions. It does not copy or change the content in the tensor. -
+ +
**Arguments:** - *input*: an {{MLOperand}}. The input tensor. - *options*: an optional {{MLSqueezeOptions}}. The optional parameters of the operation. - - *axes*: a sequence of {{unsigned long}}. 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 input tensor. When not specified, every shape dimensions of size 1 in the tensor are eliminated. **Returns:** an {{MLOperand}}. The output tensor of the same or reduced rank with the shape dimensions of size 1 eliminated.
-### The tanh() method ### {#api-mlgraphbuilder-tanh} +{{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} Compute the hyperbolic tangent function of the input tensor. The calculation follows the expression `(exp(2 * x) - 1) / (exp(2 * x) + 1)`. -
- **Arguments:** - - *x*: an {{MLOperand}}. The input tensor. - **Returns:** - - an {{MLOperand}}. The output tensor of the same shape as *x*. - - an {{MLActivation}}. The activation function representing the tanh operation. - -
+
+
+ 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. +
     return builder.div(
               builder.sub(builder.exp(builder.mul(builder.constant(2), x)), builder.constant(1)),
               builder.add(builder.exp(builder.mul(builder.constant(2), x)), builder.constant(1)));
     
-
+ +
+ +#### The {{MLGraphBuilder/tanh(input)}} method #### {#api-mlgraphbuilder-tanh-input} +
+ **Arguments:** + - *input*: an {{MLOperand}}. The input tensor. + + **Returns:** + - an {{MLOperand}}. The output tensor of the same shape as *input*. +
+ +
+ + + The tanh(|input|) method steps are: + +
+ 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|. + 1. Make a request to the underlying platform to: + 1. Let |opImpl| be an [=implementation-defined=] platform operator for the hyperbolic tangent operation. + 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 {{MLGraphBuilder/tanh()}} method #### {#api-mlgraphbuilder-tanh} +
+ **Arguments:** + - None. + + **Returns:** + - an {{MLActivation}}. The activation function representing the tanh operation.
+
+ + The tanh() method steps are: + +
+ 1. Let |op| be the result of creating an MLActivation given [=this=] and `"tanh"`. + 1. If that [=exception/throws=] an error, re-[=exception/throw=] the error. + 1. Return |op|. +
+
+ ### The transpose() method ### {#api-mlgraphbuilder-transpose} Permute the dimensions of the input tensor according to the *permutation* argument. -
+ +
**Arguments:** - *input*: an {{MLOperand}}. The input N-D tensor. - *options*: an optional {{MLTransposeOptions}}. The optional parameters of the operation. - - *permutation*: a sequence of {{unsigned long}} values. The values used to permute the output shape. When it's not specified, it's set to [N-1, ..., 0], where N is the rank of the input tensor, e.g. [2,1,0] for a 3-D tensor. 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. **Returns:** an {{MLOperand}}. The permuted or transposed N-D tensor.
+{{MLTransposeOptions}} has the following members: +
+ : permutation + :: + A sequence of {{unsigned long}} values. + Specifies the values used to permute the output shape. + The default value is [N-1, ..., 0], where N is the [=rank=] of the input tensor, e.g. [2,1,0] for a 3-D tensor. + 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. +
+ +
+ + The transpose(|input|, |options|) method steps are: + +
+ 1. [=Assert=]: the type of |input| is {{MLOperand}}. + 1. If |options|.{{MLTransposeOptions/permutation}} does not [=map/exist=], let |options|.{{MLTransposeOptions/permutation}} be the reversed sequence of all indices for |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. + 1. Otherwise if |options|.{{MLTransposeOptions/permutation}} [=map/exists=]: + 1. If the [=rank=] of |options|.{{MLTransposeOptions/permutation}} is not the same as the [=rank=] of |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}, then [=exception/throw=] a {{TypeError}}. + 1. If the values in |options|.{{MLTransposeOptions/permutation}} are not in [=the range=] 0 and the [=rank=] of |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} exclusive, then [=exception/throw=] a {{TypeError}}. + 1. If the values in |options|.{{MLTransposeOptions/permutation}} contain duplicate value, then [=exception/throw=] a {{TypeError}}. + 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. + 1. 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 transpose 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 {#examples} ===================== @@ -3044,49 +5517,54 @@ const context = await navigator.ml.createContext({powerPreference: 'low-power'})
-The following code builds a graph as: +Given the following build graph:
-constant1 ---+
-             +--- Add ---> intermediateOutput1 ---+
-input1    ---+                                    |
-                                                  +--- Mul---> output
-constant2 ---+                                    |
-             +--- Add ---> intermediateOutput2 ---+
-input2    ---+
+    constant1 ---+
+                +--- Add ---> intermediateOutput1 ---+
+    input1    ---+                                    |
+                                                    +--- Mul---> output
+    constant2 ---+                                    |
+                +--- Add ---> intermediateOutput2 ---+
+    input2    ---+
 
-
-// Use tensors in 4 dimensions.
-const TENSOR_DIMS = [1, 2, 2, 2];
-const TENSOR_SIZE = 8;
+
+ + The following code implements the graph: + +
+    // Use tensors in 4 dimensions.
+    const TENSOR_DIMS = [1, 2, 2, 2];
+    const TENSOR_SIZE = 8;
 
-const builder = new MLGraphBuilder(context);
+    const builder = new MLGraphBuilder(context);
 
-// Create MLOperandDescriptor object.
-const desc = {type: 'float32', dimensions: TENSOR_DIMS};
+    // Create MLOperandDescriptor object.
+    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);
-const constant1 = builder.constant(desc, constantBuffer1);
+    // constant1 is a constant MLOperand with the value 0.5.
+    const constantBuffer1 = new Float32Array(TENSOR_SIZE).fill(0.5);
+    const constant1 = builder.constant(desc, constantBuffer1);
 
-// input1 is one of the input MLOperands. Its value will be set before execution.
-const input1 = builder.input('input1', desc);
+    // input1 is one of the input MLOperands. Its value will be set before execution.
+    const input1 = builder.input('input1', desc);
 
-// constant2 is another constant MLOperand with the value 0.5.
-const constantBuffer2 = new Float32Array(TENSOR_SIZE).fill(0.5);
-const constant2 = builder.constant(desc, constantBuffer2);
+    // constant2 is another constant MLOperand with the value 0.5.
+    const constantBuffer2 = new Float32Array(TENSOR_SIZE).fill(0.5);
+    const constant2 = builder.constant(desc, constantBuffer2);
 
-// input2 is another input MLOperand. Its value will be set before execution.
-const input2 = builder.input('input2', desc);
+    // input2 is another input MLOperand. Its value will be set before execution.
+    const input2 = builder.input('input2', desc);
 
-// intermediateOutput1 is the output of the first Add operation.
-const intermediateOutput1 = builder.add(constant1, input1);
+    // intermediateOutput1 is the output of the first Add operation.
+    const intermediateOutput1 = builder.add(constant1, input1);
 
-// intermediateOutput2 is the output of the second Add operation.
-const intermediateOutput2 = builder.add(constant2, input2);
+    // intermediateOutput2 is the output of the second Add operation.
+    const intermediateOutput2 = builder.add(constant2, input2);
 
-// output is the output MLOperand of the Mul operation.
-const output = builder.mul(intermediateOutput1, intermediateOutput2);
-
+ // output is the output MLOperand of the Mul operation. + const output = builder.mul(intermediateOutput1, intermediateOutput2); +
+
@@ -3098,24 +5576,28 @@ const graph = await builder.build({'output': output});
-The following code executes the compiled graph. -
-// Setup the input buffers with value 1.
-const inputBuffer1 = new Float32Array(TENSOR_SIZE).fill(1);
-const inputBuffer2 = new Float32Array(TENSOR_SIZE).fill(1);
-const outputBuffer = new Float32Array(TENSOR_SIZE);
-
-// Execute the compiled graph with the specified inputs.
-const inputs = {
-  'input1': inputBuffer1,
-  'input2': inputBuffer2,
-};
-const outputs = {'output': outputBuffer};
-const result = await context.compute(graph, inputs, outputs);
-
-console.log('Output value: ' + result.outputs.output);
-// Output value: 2.25,2.25,2.25,2.25,2.25,2.25,2.25,2.25
-
+
+ + The following code executes the compiled graph. + +
+    // Setup the input buffers with value 1.
+    const inputBuffer1 = new Float32Array(TENSOR_SIZE).fill(1);
+    const inputBuffer2 = new Float32Array(TENSOR_SIZE).fill(1);
+    const outputBuffer = new Float32Array(TENSOR_SIZE);
+
+    // Execute the compiled graph with the specified inputs.
+    const inputs = {
+    'input1': inputBuffer1,
+    'input2': inputBuffer2,
+    };
+    const outputs = {'output': outputBuffer};
+    const result = await context.compute(graph, inputs, outputs);
+
+    console.log('Output value: ' + result.outputs.output);
+    // Output value: 2.25,2.25,2.25,2.25,2.25,2.25,2.25,2.25
+  
+
# Appendices # {#appendices} @@ -3163,6 +5645,8 @@ Benjamin Poulain for their contributions to the API specification. Thanks to Sangwhan Moon and the W3C Technical Architecture Group for review of this specification for web architecture fit, design consistency and developer ergonomics. +Thanks to Zoltan Kis for adding algorithms and making navigating this specification a delightful experience. Thanks to Joshua Bell for aligning the specification with modern editorial conventions. Thanks to Ningxin Hu, Lisha Guo, Shiyi Zou, Mingming Xu, Junwei Fu, Bruce Dai and Bin Miao for careful review and comments. + Thanks to W3C Privacy Interest Group for privacy and security review and feedback. Thanks to Alex Gough and the Chrome Security team for security review and questions.