From 74aef99ecea497ce634773df0c9eb0a607d3ab5f Mon Sep 17 00:00:00 2001 From: Joshua Bell Date: Fri, 26 Jan 2024 14:48:52 -0800 Subject: [PATCH] New content: Add definition for shape broadcasting This change introduces a new section for Algorithms, following APIs, to collect algorithms referenced throughout the specification. A section for Broadcasting is introduced, which defines broadcasting shapes and gives an explicit algorithm matching WebNN implementations of NumPy's General Broadcasting Rules. Definitions for "broadcastable" and "unidirectionally broadcastable" are introduced. The previous definition of "broadcast-shapes" is removed in favor of these new algorithms. For #324, #378, #462, and potentially #523. --- index.bs | 84 +++++++++++++++++++++++++++++++++++++------------------- 1 file changed, 56 insertions(+), 28 deletions(-) diff --git a/index.bs b/index.bs index a859f42c..1b5d24ab 100644 --- a/index.bs +++ b/index.bs @@ -2439,8 +2439,8 @@ partial interface MLGraphBuilder { 1. If |a|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}} is not equal to |b|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. Let |descriptor| be a new {{MLOperandDescriptor}}. 1. Set |descriptor|.{{MLOperandDescriptor/dataType}} to |a|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}}. - 1. Set |descriptor|.{{MLOperandDescriptor/dimensions}} to 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. Set |descriptor|.{{MLOperandDescriptor/dimensions}} to the result of [=bidirectionally broadcasting the shapes=] |a|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} and |b|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. + 1. If that returns failure, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |descriptor|. 1. Make a request to the underlying platform to: @@ -2454,21 +2454,6 @@ partial interface MLGraphBuilder { -
- - 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. @@ -2576,8 +2561,8 @@ Although operations *greaterOrEqual* and *lesserOrEqual* can each be implemented 1. If |a|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}} is not equal to |b|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. Let |descriptor| be a new {{MLOperandDescriptor}}. 1. Set |descriptor|.{{MLOperandDescriptor/dataType}} to {{MLOperandDataType/"uint8"}}. - 1. Set |descriptor|.{{MLOperandDescriptor/dimensions}} to 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. Set |descriptor|.{{MLOperandDescriptor/dimensions}} to the result of [=bidirectionally broadcasting the shapes=] |a|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}} and |b|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}. + 1. If that returns failure, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. If any of the following sub-steps fail, [=exception/throw=] an "{{OperationError}}" {{DOMException}}. 1. Let |output| be the result of [=creating an MLOperand=] given [=this=] and |descriptor|. 1. Make a request to the underlying platform to: @@ -2918,6 +2903,7 @@ partial interface MLGraphBuilder { 1. If the sequence length of |newShape| is not equal to the [=rank=] of |inputDesc|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. Let |outputDesc| be a copy of |inputDesc|. 1. [=map/For each=] |index| in [=the range=] 0 to the [=rank=] of |input|, exclusive: + Issue: Can this be replaced with [=unidirectionally broadcasting the shapes=] |inputDesc| and |newShape|. 1. Let |size| be the |input|.{{MLOperand/shape()}}[|index|]. 1. If |size| is not equal to 1 and not equal to |newShape|[index], then [=exception/throw=] a "{{DataError}}" {{DOMException}}. 1. If |size| is equal to 1, then let |outputDesc|.{{MLOperandDescriptor/dimensions}}[|index|] be |newShape|[|index|]. @@ -3066,7 +3052,7 @@ partial interface MLGraphBuilder { ### gemm ### {#api-mlgraphbuilder-gemm} -Calculate the [general matrix multiplication of the Basic Linear Algebra Subprograms](https://en.wikipedia.org/wiki/Basic_Linear_Algebra_Subprograms#Level_3). The calculation follows the expression `alpha * A * B + beta * C`, where `A` is a 2-D tensor with shape [M, K] or [K, M], `B` is a 2-D tensor with shape [K, N] or [N, K], and `C` is broadcastable to the shape [M, N]. `A` and `B` may optionally be transposed prior to the calculation. +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 [=unidirectionally broadcastable=] to the shape [M, N]. `A` and `B` may optionally be transposed prior to the calculation.