From 830e7471567c09a4a9fd209def34ec713483b9a7 Mon Sep 17 00:00:00 2001 From: Ningxin Hu Date: Sat, 16 Nov 2024 08:59:49 +0800 Subject: [PATCH 1/3] Allow shared array buffer view for `MLGraphBuilder.constant()` Fix #788 --- index.bs | 34 +++++++++++----------------------- 1 file changed, 11 insertions(+), 23 deletions(-) diff --git a/index.bs b/index.bs index 6bb68043..66a04651 100644 --- a/index.bs +++ b/index.bs @@ -1341,7 +1341,8 @@ interface MLGraphBuilder { MLOperand input(USVString name, MLOperandDescriptor descriptor); // Create an operand for a graph constant. - MLOperand constant(MLOperandDescriptor descriptor, ArrayBufferView bufferView); + MLOperand constant(MLOperandDescriptor descriptor, + [AllowShared] ArrayBufferView bufferView); // Create a scalar operand from the specified number of the specified type. MLOperand constant(MLOperandDataType type, MLNumber value); @@ -2012,8 +2013,7 @@ partial dictionary MLOpSupportLimits { input, builder.constant(input.dataType, options.minValue)); } else { return builder.min( - builder.max( - input, builder.constant(input.dataType, options.minValue)), + builder.max(input, builder.constant(input.dataType, options.minValue)), builder.constant(input.dataType, options.maxValue)); } } @@ -3421,8 +3421,8 @@ partial dictionary MLOpSupportLimits { {shape: [4, 3]}, new Float32Array([0, 1, 2, 10, 11, 12, 20, 21, 22, 30, 31, 32])); - const indices1 = builder.constant( - {dataType: 'uint32', shape: [2]}, new Uint32Array([3, 1])); + const indices1 = + builder.constant({dataType: 'uint32', shape: [2]}, new Uint32Array([3, 1])); const indices2 = builder.constant( {dataType: 'uint32', shape: [3]}, new Uint32Array([2, 1, 1])); @@ -3937,10 +3937,7 @@ partial dictionary MLOpSupportLimits { let hiddenState = options.initialHiddenState; if (!hiddenState) { - const desc = { - dataType: 'float32', - shape: [numDirections, 1, hiddenSize] - }; + const desc = {dataType: 'float32', shape: [numDirections, 1, hiddenSize]}; const totalSize = numDirections * hiddenSize; hiddenState = builder.constant(desc, new Float32Array(totalSize).fill(0)); } @@ -4619,8 +4616,7 @@ partial dictionary MLOpSupportLimits { const reduceOptions = {axes: [2, 3], keepDimensions: true}; const mean = builder.reduceMean(input, reduceOptions); const variance = builder.reduceMean( - builder.pow( - builder.sub(input, mean), builder.constant(input.dataType, 2)), + builder.pow(builder.sub(input, mean), builder.constant(input.dataType, 2)), reduceOptions); // The scale and bias values are applied per input feature @@ -4765,8 +4761,7 @@ partial dictionary MLOpSupportLimits { const reduceOptions = {axes: [1, 2, 3], keepDimensions: true}; const mean = builder.reduceMean(input, reduceOptions); const variance = builder.reduceMean( - builder.pow( - builder.sub(input, mean), builder.constant(input.dataType, 2)), + builder.pow(builder.sub(input, mean), builder.constant(input.dataType, 2)), reduceOptions); // The scale and bias tensors are of the shape of the input @@ -5222,19 +5217,13 @@ partial dictionary MLOpSupportLimits { let cellState = options.initialCellState; if (!hiddenState) { - const desc = { - dataType: 'float32', - shape: [numDirections, 1, hiddenSize] - }; + const desc = {dataType: 'float32', shape: [numDirections, 1, hiddenSize]}; const totalSize = numDirections * hiddenSize; hiddenState = builder.constant(desc, new Float32Array(totalSize).fill(0)); } if (!cellState) { - const desc = { - dataType: 'float32', - shape: [numDirections, 1, hiddenSize] - }; + const desc = {dataType: 'float32', shape: [numDirections, 1, hiddenSize]}; const totalSize = numDirections * hiddenSize; cellState = builder.constant(desc, new Float32Array(totalSize).fill(0)); } @@ -5878,8 +5867,7 @@ partial dictionary MLOpSupportLimits {
     // input: [[1,2,3], [4,5,6]]
     const input = builder.constant(
-      {dataType: 'float32', shape: [2, 3]},
-      new Float32Array([1, 2, 3, 4, 5, 6]));
+      {dataType: 'float32', shape: [2, 3]}, new Float32Array([1, 2, 3, 4, 5, 6]));
 
     const beginningPadding = [1, 2];
     const endingPadding = [1, 2];

From 1dc2694e350d43d5fb2785b490f45b0f717ddcd7 Mon Sep 17 00:00:00 2001
From: Ningxin Hu 
Date: Thu, 21 Nov 2024 14:25:24 +0800
Subject: [PATCH 2/3] Use AllowSharedBufferSource

---
 index.bs | 19 ++++++++-----------
 1 file changed, 8 insertions(+), 11 deletions(-)

diff --git a/index.bs b/index.bs
index 66a04651..126c6c19 100644
--- a/index.bs
+++ b/index.bs
@@ -1342,7 +1342,7 @@ interface MLGraphBuilder {
 
   // Create an operand for a graph constant.
   MLOperand constant(MLOperandDescriptor descriptor,
-                     [AllowShared] ArrayBufferView bufferView);
+                     AllowSharedBufferSource bufferSource);
 
   // Create a scalar operand from the specified number of the specified type.
   MLOperand constant(MLOperandDataType type, MLNumber value);
@@ -1353,7 +1353,7 @@ interface MLGraphBuilder {
 
 
 
-The {{MLGraphBuilder}}.{{MLGraphBuilder/build()}} method compiles the graph builder state up to the specified output operands into a compiled graph according to the type of {{MLContext}} that creates it. When the {{MLContext/[[contextType]]}} of the {{MLContext}} is set to "[=context type/default=]", the compiled graph is initialized right before the {{MLGraph}} is returned. This graph initialization stage is important for optimal performance of the subsequent graph executions. It typically involves a process known as "weight preprocessing" where all the constant inputs to the graph are preprocessed and cached at the operating system level for subsequent graph execution calls. The initializing inputs are typically the constant weight data specified through the {{MLGraphBuilder/constant(descriptor, bufferView)|constant()}} method as constant operands during graph construction time. +The {{MLGraphBuilder}}.{{MLGraphBuilder/build()}} method compiles the graph builder state up to the specified output operands into a compiled graph according to the type of {{MLContext}} that creates it. When the {{MLContext/[[contextType]]}} of the {{MLContext}} is set to "[=context type/default=]", the compiled graph is initialized right before the {{MLGraph}} is returned. This graph initialization stage is important for optimal performance of the subsequent graph executions. It typically involves a process known as "weight preprocessing" where all the constant inputs to the graph are preprocessed and cached at the operating system level for subsequent graph execution calls. The initializing inputs are typically the constant weight data specified through the {{MLGraphBuilder/constant(descriptor, bufferSource)|constant()}} method as constant operands during graph construction time.
@@ -1417,26 +1417,26 @@ Create a named {{MLOperand}} based on a descriptor, that can be used as an input ### constant operands ### {#api-mlgraphbuilder-constant} Create a constant {{MLOperand}} that can be used in {{MLGraphBuilder}} methods. -#### {{MLGraphBuilder/constant(descriptor, bufferView)}} #### {#api-mlgraphbuilder-constant-bufferview} +#### {{MLGraphBuilder/constant(descriptor, bufferSource)}} #### {#api-mlgraphbuilder-constant-buffersource} Create a constant {{MLOperand}} of the specified data type and shape that contains the initializing data. -
+
**Arguments:** - descriptor: an {{MLOperandDescriptor}}. The descriptor of the output tensor. - - bufferView: an {{ArrayBufferView}}. The view of the buffer containing the initializing data. + - bufferSource: an {{AllowSharedBufferSource}}. The buffer containing the initializing data. **Returns:** an {{MLOperand}}. The constant output tensor.
- The constant(|descriptor|, |bufferView|) method steps are: + The constant(|descriptor|, |bufferSource|) method steps are: 1. If [=this=].{{MLGraphBuilder/[[hasBuilt]]}} is true, then [=exception/throw=] an "{{InvalidStateError}}" {{DOMException}}. 1. If [=MLOperandDescriptor/checking dimensions=] given |descriptor| returns false, then [=exception/throw=] a {{TypeError}}. - 1. If [=validating buffer with descriptor=] given |bufferView| and |descriptor| returns false, then [=exception/throw=] a {{TypeError}}. + 1. If [=validating buffer with descriptor=] given |bufferSource| and |descriptor| returns false, then [=exception/throw=] a {{TypeError}}. 1. *Make graph connections:* 1. Let |operand| be the result of [=creating an MLOperand=] given [=this=] and |descriptor|. - 1. Let |bytes| be the result of [=getting a copy of the bytes held by the buffer source=] given |bufferView|. + 1. Let |bytes| be the result of [=getting a copy of the bytes held by the buffer source=] given |bufferSource|. 1. Add |operand| to [=this=]'s [=MLGraphBuilder/graph=]'s [=computational graph/constants=] with |bytes| as value. 1. Return |operand|.
@@ -1504,9 +1504,6 @@ Build a composed graph up to a given output operand into a computational graph a 1. Set |graph|.{{MLGraph/[[context]]}} to [=this=].{{MLGraphBuilder/[[context]]}}. 1. [=set/For each=] |operand| in |inputs|: 1. Set |graph|.{{MLGraph/[[inputDescriptors]]}}[|operand|.{{MLOperand/[[name]]}}] to |operand|.{{MLOperand/[[descriptor]]}}. - - Issue(566): If {{MLGraphBuilder/constant(descriptor, bufferView)|constants'}} {{ArrayBuffer}}s are not [=ArrayBuffer/transferred=], make copies for [=MLGraphBuilder/graph=]'s [=computational graph/constants=] here. - 1. [=map/For each=] |name| → |operand| of |outputs|: 1. Set |graph|.{{MLGraph/[[outputDescriptors]]}}[|name|] to |operand|.{{MLOperand/[[descriptor]]}}. 1. Let |promise| be [=a new promise=]. From 0bd2d0a8ce755be2f8e2e9cd1fb4a4ba685caff3 Mon Sep 17 00:00:00 2001 From: Ningxin Hu Date: Wed, 27 Nov 2024 14:20:19 +0800 Subject: [PATCH 3/3] Rename bufferSource to buffer --- index.bs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/index.bs b/index.bs index 126c6c19..ad8417b7 100644 --- a/index.bs +++ b/index.bs @@ -1342,7 +1342,7 @@ interface MLGraphBuilder { // Create an operand for a graph constant. MLOperand constant(MLOperandDescriptor descriptor, - AllowSharedBufferSource bufferSource); + AllowSharedBufferSource buffer); // Create a scalar operand from the specified number of the specified type. MLOperand constant(MLOperandDataType type, MLNumber value); @@ -1353,7 +1353,7 @@ interface MLGraphBuilder {
-The {{MLGraphBuilder}}.{{MLGraphBuilder/build()}} method compiles the graph builder state up to the specified output operands into a compiled graph according to the type of {{MLContext}} that creates it. When the {{MLContext/[[contextType]]}} of the {{MLContext}} is set to "[=context type/default=]", the compiled graph is initialized right before the {{MLGraph}} is returned. This graph initialization stage is important for optimal performance of the subsequent graph executions. It typically involves a process known as "weight preprocessing" where all the constant inputs to the graph are preprocessed and cached at the operating system level for subsequent graph execution calls. The initializing inputs are typically the constant weight data specified through the {{MLGraphBuilder/constant(descriptor, bufferSource)|constant()}} method as constant operands during graph construction time. +The {{MLGraphBuilder}}.{{MLGraphBuilder/build()}} method compiles the graph builder state up to the specified output operands into a compiled graph according to the type of {{MLContext}} that creates it. When the {{MLContext/[[contextType]]}} of the {{MLContext}} is set to "[=context type/default=]", the compiled graph is initialized right before the {{MLGraph}} is returned. This graph initialization stage is important for optimal performance of the subsequent graph executions. It typically involves a process known as "weight preprocessing" where all the constant inputs to the graph are preprocessed and cached at the operating system level for subsequent graph execution calls. The initializing inputs are typically the constant weight data specified through the {{MLGraphBuilder/constant(descriptor, buffer)|constant()}} method as constant operands during graph construction time.
@@ -1417,26 +1417,26 @@ Create a named {{MLOperand}} based on a descriptor, that can be used as an input ### constant operands ### {#api-mlgraphbuilder-constant} Create a constant {{MLOperand}} that can be used in {{MLGraphBuilder}} methods. -#### {{MLGraphBuilder/constant(descriptor, bufferSource)}} #### {#api-mlgraphbuilder-constant-buffersource} +#### {{MLGraphBuilder/constant(descriptor, buffer)}} #### {#api-mlgraphbuilder-constant-buffer} Create a constant {{MLOperand}} of the specified data type and shape that contains the initializing data. -
+
**Arguments:** - descriptor: an {{MLOperandDescriptor}}. The descriptor of the output tensor. - - bufferSource: an {{AllowSharedBufferSource}}. The buffer containing the initializing data. + - buffer: an {{AllowSharedBufferSource}}. The buffer containing the initializing data. **Returns:** an {{MLOperand}}. The constant output tensor.
- The constant(|descriptor|, |bufferSource|) method steps are: + The constant(|descriptor|, |buffer|) method steps are: 1. If [=this=].{{MLGraphBuilder/[[hasBuilt]]}} is true, then [=exception/throw=] an "{{InvalidStateError}}" {{DOMException}}. 1. If [=MLOperandDescriptor/checking dimensions=] given |descriptor| returns false, then [=exception/throw=] a {{TypeError}}. - 1. If [=validating buffer with descriptor=] given |bufferSource| and |descriptor| returns false, then [=exception/throw=] a {{TypeError}}. + 1. If [=validating buffer with descriptor=] given |buffer| and |descriptor| returns false, then [=exception/throw=] a {{TypeError}}. 1. *Make graph connections:* 1. Let |operand| be the result of [=creating an MLOperand=] given [=this=] and |descriptor|. - 1. Let |bytes| be the result of [=getting a copy of the bytes held by the buffer source=] given |bufferSource|. + 1. Let |bytes| be the result of [=getting a copy of the bytes held by the buffer source=] given |buffer|. 1. Add |operand| to [=this=]'s [=MLGraphBuilder/graph=]'s [=computational graph/constants=] with |bytes| as value. 1. Return |operand|.