Skip to content

Commit

Permalink
Bug fix: Correct linking for list/range iterations (webmachinelearnin…
Browse files Browse the repository at this point in the history
…g#527)

Some uses of "for each" in algorithms were linking to the map
iteration definition in Infra. Fix this to point at the list iteration
definition. Today I learned: this applies to iteration over ranges
too!

Also updated coding conventions to cover these cases.
  • Loading branch information
inexorabletash committed Jan 30, 2024
1 parent b421b69 commit 4a7622a
Show file tree
Hide file tree
Showing 2 changed files with 9 additions and 7 deletions.
2 changes: 2 additions & 0 deletions SpecCodingConventions.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ Example:
* Use the most specific types possible (e.g. MLOperand, not generic object).
* Use `[=this=]` to refer to the current object.
* Use `[=map/For each=] |key| → |value| of |map|` when iterating over a map, but use more specific terms for the key and value (e.g. _For each name → input of inputs:_)
* Use `[=list/For each=] |item| of |list|` when iterating over a list, but use more specific terms for the item (e.g. _For each dimension of dimensions:_)
* Use `[=list/For each=] |index| in [=the range=] X to Y, inclusive` when iterating over a numeric range; a range is implicitly an ordered set which is a type of list. Specify _inclusive_ or _exclusive_ regarding the upper bound, for clarity.
* Use "let" to introduce a variable and "set" to update a variable or assign to a property.
* Use « » notation for literal lists, which helps make it clear that they are not JavaScript arrays.

Expand Down
14 changes: 7 additions & 7 deletions index.bs
Original file line number Diff line number Diff line change
Expand Up @@ -1878,11 +1878,11 @@ partial interface MLGraphBuilder {
1. Let |desc| be |inputs|[0].{{MLOperand/[[descriptor]]}}.
1. If |axis| is greater than or equal to the [=rank=] of |desc|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}.
1. Set |desc|.{{MLOperandDescriptor/dimensions}}[|axis|] to 0.
1. [=map/For each=] |index| in [=the range=] 0 to the [=rank=] of |inputs|, exclusive:
1. [=list/For each=] |index| in [=the range=] 0 to the [=rank=] of |inputs|, exclusive:
1. Let |input| be |inputs|[|index|].
1. If [=validating MLOperand=] given |input| and [=this=] returns false, then [=exception/throw=] a "{{DataError}}" {{DOMException}}.
1. If |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}} is not equal to |inputs|[0].{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dataType}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}.
1. [=map/For each=] |dim| in [=the range=] 0 to the [=rank=] of |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}, exclusive:
1. [=list/For each=] |dim| in [=the range=] 0 to the [=rank=] of |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}, exclusive:
<div class="note">
If the shape of each corresponding dimension and type of the operands, except for those of the dimension given by |axis|, is not the same, fail.
</div>
Expand Down Expand Up @@ -2007,7 +2007,7 @@ Data truncation will occur when the values in the range exceed the range of the
1. Make a request to the underlying platform to:
1. Create an [=implementation-defined=] platform memory buffer the size of |size| multiplied by sizeof(|descriptor|.{{MLOperandDescriptor/dataType}}).
2. Store the beginning address to that memory buffer as a pointer |buffer| of the corresponding data type.
1. [=map/For each=] |index| in [=the range=] 0 to |size|, exclusive:
1. [=list/For each=] |index| in [=the range=] 0 to |size|, exclusive:
1. Set |buffer|[|index|] to |start| + (|index| * |step|).
1. Make a request to the underlying platform to:
1. Create an [=implementation-defined=] platform operand |constantImpl| to represent a constant operand, given |descriptor|.
Expand Down Expand Up @@ -2878,7 +2878,7 @@ partial interface MLGraphBuilder {
1. Let |inputDesc| be |input|.{{MLOperand/[[descriptor]]}}.
1. If the sequence length of |newShape| is not equal to the [=rank=] of |inputDesc|, then [=exception/throw=] a "{{DataError}}" {{DOMException}}.
1. Let |outputDesc| be a copy of |inputDesc|.
1. [=map/For each=] |index| in [=the range=] 0 to the [=rank=] of |input|, exclusive:
1. [=list/For each=] |index| in [=the range=] 0 to the [=rank=] of |input|, exclusive:
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|].
Expand Down Expand Up @@ -3845,7 +3845,7 @@ The {{MLLayerNormalizationOptions}} members are:
<div class=algorithm-steps>
1. If the [=rank=] of |options|.{{MLLayerNormalizationOptions/scale}} is not equal to the [=list/size=] of |options|.{{MLLayerNormalizationOptions/axes}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}.
1. If the [=rank=] of |options|.{{MLLayerNormalizationOptions/bias}} is not equal to the [=list/size=] of |options|.{{MLLayerNormalizationOptions/axes}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}.
1. [=map/For each=] |index| in [=the range=] 0 to the [=list/size=] of |options|.{{MLLayerNormalizationOptions/axes}}, exclusive:
1. [=list/For each=] |index| in [=the range=] 0 to the [=list/size=] of |options|.{{MLLayerNormalizationOptions/axes}}, exclusive:
1. Let |axis| be |options|.{{MLLayerNormalizationOptions/axes}}[|index|].
1. If |axis| is greater or equal to the [=list/size=] of |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}, then [=exception/throw=] a "{{DataError}}" {{DOMException}}.
1. Let |size| be |input|.{{MLOperand/[[descriptor]]}}.{{MLOperandDescriptor/dimensions}}[|axis|].
Expand Down Expand Up @@ -4548,7 +4548,7 @@ partial interface MLGraphBuilder {
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. [=list/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|.
</div>
Expand Down Expand Up @@ -6252,7 +6252,7 @@ dictionary MLOperandDescriptor {
</summary>
<div class=algorithm-steps>
1. Let |elementLength| be 1.
1. [=map/For each=] |dimension| of |desc|.{{MLOperandDescriptor/dimensions}}:
1. [=list/For each=] |dimension| of |desc|.{{MLOperandDescriptor/dimensions}}:
1. Set |elementLength| to |elementLength| × |dimension|.
1. Let |elementSize| be the [=element size=] of one of the {{ArrayBufferView}} types that matches |desc|.{{MLOperandDescriptor/dataType}} according to [this table](#appendices-mloperanddatatype-arraybufferview-compatibility).
1. Return |elementLength| × |elementSize|.
Expand Down

0 comments on commit 4a7622a

Please sign in to comment.