Skip to content

Commit a2f7e0a

Browse files
inexorabletashfdwr
andauthored
Wording change: Tighten up output shape calculation algorithms (#523)
* Wording change: Tighten up output shape calculation algorithms For gemm() - make lists that are mutated be explicit clones using Infra terminology, and simplify the wording reversing the lists. For matmul() - make lists that are mutated be explicit clones using Infra terminology, use append/prepend definitions from Infra, convert a variable change from "let" to "set" and drop use of "array". For #395 * Rewrite to match Chromium impl * Update index.bs Co-authored-by: Dwayne Robinson <[email protected]> --------- Co-authored-by: Dwayne Robinson <[email protected]>
1 parent 8503e24 commit a2f7e0a

File tree

1 file changed

+23
-20
lines changed

1 file changed

+23
-20
lines changed

index.bs

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -2892,11 +2892,13 @@ partial interface MLGraphBuilder {
28922892
The <dfn method for=MLGraphBuilder>gemm(|a|, |b|, |options|)</dfn> method steps are:
28932893
</summary>
28942894
<div class=algorithm-steps>
2895-
1. Let |shapeA| be |a|'s [=MLOperand/shape=] and |sizeA| be |a|'s [=MLOperand/rank=].
2896-
1. Let |shapeB| be |b|'s [=MLOperand/shape=] and |sizeB| be |b|'s [=MLOperand/rank=].
2895+
1. Let |shapeA| be a [=list/clone=] of |a|'s [=MLOperand/shape=].
2896+
1. Let |sizeA| be the [=list/size=] of |shapeA|.
2897+
1. Let |shapeB| be a [=list/clone=] of |b|'s [=MLOperand/shape=].
2898+
1. Let |sizeB| be the [=list/size=] of |shapeB|.
28972899
1. If |sizeA| is not 2 or |sizeB| is not 2, then [=exception/throw=] a "{{DataError}}" {{DOMException}}.
2898-
1. If |options|.{{MLGemmOptions/aTranspose}} is true, then let |shapeA| be the reverse array of |shapeA|.
2899-
1. If |options|.{{MLGemmOptions/bTranspose}} is true, then let |shapeB| be the reverse array of |shapeB|.
2900+
1. If |options|.{{MLGemmOptions/aTranspose}} is true, then reverse the order of the items in |shapeA|.
2901+
1. If |options|.{{MLGemmOptions/bTranspose}} is true, then reverse the order of the items in |shapeB|.
29002902
1. If |shapeA|[1] is not equal to |shapeB|[0], then [=exception/throw=] a "{{DataError}}" {{DOMException}}.
29012903
1. If |options|.{{MLGemmOptions/c}} [=map/exists=] and is not [=unidirectionally broadcastable=] to the shape [|shapeA|[0], |shapeB|[1]], then [=exception/throw=] a "{{DataError}}" {{DOMException}}.
29022904
<div class="note">
@@ -4324,8 +4326,8 @@ partial interface MLGraphBuilder {
43244326

43254327
<div>
43264328
**Arguments:**
4327-
- *a*: an {{MLOperand}}. The first N-dimensional input tensor.
4328-
- *b*: an {{MLOperand}}. The second N-dimensional input tensor.
4329+
- *a*: an {{MLOperand}}. The first input tensor which is at least 2-D.
4330+
- *b*: an {{MLOperand}}. The second input tensor which is at least 2-D.
43294331

43304332
**Returns:** an {{MLOperand}}. The output tensor that contains the matrix
43314333
product of two input tensors.
@@ -4335,27 +4337,28 @@ partial interface MLGraphBuilder {
43354337
- If both *a* and *b* are 2-dimensional, they are multiplied like conventional
43364338
matrices and produce a 2-dimensional tensor as the output.
43374339
- 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.
4338-
- If *a* is 1-dimensional, it is converted to a 2-dimensional tensor by prepending a 1 to its dimensions.
4339-
- If *b* is 1-dimensional, it is converted to a 2-dimensional tensor by by appending a 1 to its dimensions.
4340-
- If both *a* and *b* are 1-dimensional, the operation is a vector dot-product, which produces a scalar output.
43414340
</div>
43424341

43434342
<details open algorithm>
43444343
<summary>
43454344
To <dfn dfn-for=MLGraphBuilder>calculate matmul output sizes</dfn>, given |a| and |b| run the following steps:
43464345
</summary>
43474346
<div class=algorithm-steps>
4348-
1. Let |shapeA| be |a|'s [=MLOperand/shape=] and |sizeA| be |a|'s [=MLOperand/rank=].
4349-
1. Let |shapeB| be |b|'s [=MLOperand/shape=] and |sizeB| be |b|'s [=MLOperand/rank=].
4350-
1. If |sizeA| and |sizeB| is 1, return the [=/list=] « 1 ».
4351-
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.
4352-
1. If |shapeA|[0] is not equal to |shapeB|[|sizeB| - 2], then [=exception/throw=] an "{{OperationError}}" {{DOMException}}.
4353-
1. If |sizeB| is 1 and |sizeA| is not, then append 1 to |shapeB| to become [ |shapeB| | 1 ] and let |sizeB| be 2.
4354-
1. If |shapeA|[|sizeA| - 1] is not equal to |shapeB|[0], then [=exception/throw=] an "{{OperationError}}" {{DOMException}}.
4355-
1. Let |shape| be an array whose size |size| is the maximum of |sizeA| and |sizeB|.
4356-
1. [=list/For each=] |index| in [=the range=] 0 to |size|, exclusive:
4357-
1. Set |shape|[|index|] to the maximum of |shapeA|[|index|] and |shapeB|[|index|].
4358-
1. Return |shape|.
4347+
1. Let |shapeA| be a [=list/clone=] of |a|'s [=MLOperand/shape=]
4348+
1. Let |sizeA| be the [=list/size=] of |shapeA|.
4349+
1. Let |shapeB| be a [=list/clone=] of |b|'s [=MLOperand/shape=]
4350+
1. Let |sizeB| be the [=list/size=] of |shapeB|.
4351+
1. If either |sizeA| or |sizeB| is less than 2, then [=exception/throw=] a "{{DataError}}" {{DOMException}}.
4352+
1. Let |colsA| be |shapeA|[|sizeA| - 1].
4353+
1. Let |rowsA| be |shapeA|[|sizeA| - 2].
4354+
1. Let |colsB| be |shapeB|[|sizeB| - 1].
4355+
1. Let |rowsB| be |shapeB|[|sizeB| - 2].
4356+
1. If |colsA| is not equal to |rowsB|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}.
4357+
1. Let |batchShapeA| be a [=list/clone=] of |shapeA| with the spatial dimensions (last 2 items) [=list/removed=].
4358+
1. Let |batchShapeB| be a [=list/clone=] of |shapeB| with the spatial dimensions (last 2 items) [=list/removed=].
4359+
1. Let |outputShape| be the result of [=bidirectionally broadcasting the shapes=] |batchShapeA| and |batchShapeB|. If that returns failure, then [=exception/throw=] a "{{DataError}}" {{DOMException}}.
4360+
1. [=list/Append=] « |rowsA|, |colsB| » to |outputShape|.
4361+
1. Return |outputShape|.
43594362
</div>
43604363
</details>
43614364

0 commit comments

Comments
 (0)