diff --git a/index.bs b/index.bs index 5ad2643c..f6fafdc0 100644 --- a/index.bs +++ b/index.bs @@ -67,19 +67,19 @@ urlPrefix: https://tc39.es/proposal-float16array/; spec: 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/"
- ]
- }
+ "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/"
+ ]
+ }
}
@@ -104,19 +104,19 @@ p, ul, ol, dl {
margin: 1em 0;
}
-/* Box for Valid Usage requirements. */
-div.validusage {
- padding: .5em;
- border: thin solid #88e !important;
- border-radius: .5em;
-}
-
/*
* Stylistic labels, for clarity of presentation of these blocks.
*
* NOTE: This text is non-accessible and non-selectable; surrounding
* text must also explain the context.
*/
+
+/* Box for Valid Usage requirements. */
+div.validusage {
+ padding: .5em;
+ border: thin solid #88e !important;
+ border-radius: .5em;
+}
.validusage {
position: relative;
}
@@ -134,19 +134,51 @@ div.validusage {
content: "Valid Usage";
}
-/* Box for Informal steps. */
+details {
+ padding: .5em;
+ border: thin solid #88e !important;
+ border-radius: .5em;
+}
+
+summary {
+ font-weight: bold;
+ margin: -0.5em -0.5em 0;
+ padding: 0.5em;
+}
+
+/* Box for algorithm steps. */
+
+div.algorithm-steps {
+ padding: .5em;
+ background-color: ghostwhite;
+}
+
+.algorithm-steps {
+ position: relative;
+ overflow: hidden;
+}
+.algorithm-steps::after {
+ font-weight: bold;
+ font-style: italic;
+ font-size: 130%;
+ color: rgba(0, 0, 0, 0.15);
+ color: var(--watermark-text);
+ position: absolute;
+ right: .3em;
+ bottom: .1em;
+}
+.algorithm-steps::after {
+ content: "Algorithm";
+}
+
+/* Informal steps */
div.informalsteps {
padding: .5em;
border: thin solid #88e !important;
border-radius: .5em;
+ background-color: ghostwhite;
}
-/*
- * Stylistic labels, for clarity of presentation of these blocks.
- *
- * NOTE: This text is non-accessible and non-selectable; surrounding
- * text must also explain the context.
- */
.informalsteps {
position: relative;
}
@@ -164,6 +196,28 @@ div.informalsteps {
content: "Non-normative";
}
+/* Internal slots */
+div.internal-slots {
+ padding: .5em;
+ border: thin solid #88e !important;
+ border-radius: .5em;
+ background-color: aliceblue;
+}
+
+.internal-slots {
+ position: relative;
+}
+.internal-slots::after {
+ font-weight: bold;
+ font-style: italic;
+ font-size: 130%;
+ color: rgba(0, 0, 0, 0.15);
+ color: var(--watermark-text);
+ position: absolute;
+ right: .3em;
+ bottom: .1em;
+}
+
/*
* Ensure that argumentdef blocks don't overflow algorithm section borders. This is made far harder
* than it needs to be because the top-level W3C stylesheet has several @media + min-width variants
@@ -262,8 +316,116 @@ th, td {
}
}
+
+/* Floating button for collapse/expand all details elements */
+
+.collapse-expand-button {
+ position: fixed;
+ bottom: 40px;
+ right: 40px;
+ width: 40px;
+ height: 40px;
+ border: none;
+ border-radius: 50%;
+ background-color: green;
+ color: ghostwhite;
+ font-size: 32px;
+ text-align: center;
+ align-items:center;
+ justify-content:center;
+ cursor: pointer;
+}
+
+.collapse-expand-button:hover {
+ background-color: green;
+}
+
+.collapse-expand-button.expand {
+ background-color: red;
+}
+
+.collapse-expand-button.expand::before {
+ content: "+";
+}
+
+.collapse-expand-button.collapse {
+ background-color: green;
+}
+
+.collapse-expand-button.collapse::before {
+ content: "-";
+}
+
+.collapse-expand-button .tooltiptext {
+ visibility: hidden;
+ bottom: 20px;
+ right: 20px;
+ width: 120px;
+ background-color: ghostwhite;
+ color: black;
+ font-size: 18px;
+ text-align: center;
+ align-items:center;
+ justify-content:center;
+ padding: 5px 0;
+ border-radius: 5px;
+
+ /* position */
+ position: absolute;
+ z-index: 1;
+ bottom: 100%;
+ left: 50%;
+ margin-left: -60px;
+ /* Use half of the width (120/2 = 60), to center the tooltip */
+}
+
+.collapse-expand-button:hover .tooltiptext {
+ visibility: visible;
+ opacity: 0.75;
+}
+
+/* end of floating collapse/expand button */
+
+
+
+
+
Introduction {#intro}
=====================
@@ -647,31 +809,43 @@ string "webnn".
Its default allowlist is 'self'.
### The {{ML/createContext()}} method ### {#api-ml-createcontext}
-The {{ML/createContext()}} method steps are:
-1. If [=this=]'s [=relevant global object=]'s [=associated Document=] is not [=allowed to use=] the [=webnn-feature|webnn=] feature, return [=a new promise=] [=rejected=] with a "{{SecurityError}}" {{DOMException}} and abort these steps.
-1. Let |promise| be [=a new promise=].
-1. Return |promise| and run the following steps [=in parallel=].
-1. Let |options| be the first argument.
-1. Run the create context steps given |options|:
- 1. Let |context| be a new {{MLContext}} object.
- 1. If |options| is a {{GPUDevice}} object,
- 1. Set |context|.{{[[contextType]]}} to "[=webgpu-context|webgpu=]".
- 1. Set |context|.{{[[deviceType]]}} to "[=device-type-gpu|gpu=]".
- 1. Set |context|.{{[[powerPreference]]}} to "[=power-preference-default|default=]".
- 1. Otherwise,
- 1. Set |context|.{{[[contextType]]}} to "[=default-context|default=]".
- 1. If |options|["{{deviceType}}"] [=map/exists=], then set |context|.{{[[deviceType]]}} to |options|["{{deviceType}}"]. Otherwise, set |context|.{{[[deviceType]]}} to "[=device-type-cpu|cpu=]".
- 1. If |options|["{{powerPreference}}"] [=map/exists=], then set |context|.{{[[powerPreference]]}} to |options|["{{powerPreference}}"]. Otherwise, set |context|.{{[[powerPreference]]}} to "[=power-preference-default|default=]".
-1. If the validate MLContext steps given |context| return `false`, [=reject=] |promise| with a "{{NotSupportedError}}" {{DOMException}} and abort these steps.
-1. [=Resolve=] |promise| with |context|.
+
-const context = navigator.ml.createContextSync();
-
-// Build a graph with two outputs.
-const builder = new MLGraphBuilder(context);
-const descA = {type: 'float32', dimensions: [3, 4]};
-const a = builder.input('a', descA);
-const descB = {type: 'float32', dimensions: [4, 3]};
-const bufferB = new Float32Array(sizeOfShape(descB.dimensions)).fill(0.5);
-const b = builder.constant(descB, bufferB);
-const descC = {type: 'float32', dimensions: [3, 3]};
-const bufferC = new Float32Array(sizeOfShape(descC.dimensions)).fill(1);
-const c = builder.constant(descC, bufferC);
-const d = builder.matmul(a, b);
-const e = builder.add(d, c);
-const graph = builder.buildSync({'d': d, 'e': e});
-
-const bufferA = new Float32Array(sizeOfShape(descA.dimensions)).fill(0.5);
-const inputs = {'a': bufferA};
-
-// Compute d.
-const bufferD = new Float32Array(sizeOfShape([3, 3]));
-context.computeSync(graph, inputs, {'d': bufferD});
-console.log(`values: ${bufferD}`);
-
-// Compute e.
-const bufferE = new Float32Array(sizeOfShape([3, 3]));
-context.computeSync(graph, inputs, {'e': bufferE});
-console.log(`values: ${bufferE}`);
-
+
+ const context = navigator.ml.createContextSync();
+
+ // Build a graph with two outputs.
+ const builder = new MLGraphBuilder(context);
+ const descA = {type: 'float32', dimensions: [3, 4]};
+ const a = builder.input('a', descA);
+ const descB = {type: 'float32', dimensions: [4, 3]};
+ const bufferB = new Float32Array(sizeOfShape(descB.dimensions)).fill(0.5);
+ const b = builder.constant(descB, bufferB);
+ const descC = {type: 'float32', dimensions: [3, 3]};
+ const bufferC = new Float32Array(sizeOfShape(descC.dimensions)).fill(1);
+ const c = builder.constant(descC, bufferC);
+ const d = builder.matmul(a, b);
+ const e = builder.add(d, c);
+ const graph = builder.buildSync({'d': d, 'e': e});
+
+ const bufferA = new Float32Array(sizeOfShape(descA.dimensions)).fill(0.5);
+ const inputs = {'a': bufferA};
+
+ // Compute d.
+ const bufferD = new Float32Array(sizeOfShape([3, 3]));
+ context.computeSync(graph, inputs, {'d': bufferD});
+ console.log(`values: ${bufferD}`);
+
+ // Compute e.
+ const bufferE = new Float32Array(sizeOfShape([3, 3]));
+ context.computeSync(graph, inputs, {'e': bufferE});
+ console.log(`values: ${bufferE}`);
+
+
-const operandType = {type: 'float32', dimensions: [2, 2]};
-const context = await navigator.ml.createContext();
-const builder = new MLGraphBuilder(context);
-// 1. Create a computational graph 'C = 0.2 * A + B'.
-const constant = builder.constant(0.2);
-const A = builder.input('A', operandType);
-const B = builder.input('B', operandType);
-const C = builder.add(builder.mul(A, constant), B);
-// 2. Compile it into an executable.
-const graph = await builder.build({'C': C});
-// 3. Bind inputs to the graph and execute for the result.
-const bufferA = new Float32Array(4).fill(1.0);
-const bufferB = new Float32Array(4).fill(0.8);
-const bufferC = new Float32Array(4);
-const inputs = {'A': bufferA, 'B': bufferB};
-const outputs = {'C': bufferC};
-const result = await context.compute(graph, inputs, outputs);
-// The computed result of [[1, 1], [1, 1]] is in the buffer associated with
-// the output operand.
-console.log('Output value: ' + result.outputs.C);
-// Note: the result.outputs.C buffer is different from the bufferC, but it
-// shares the same backing memory allocation.
-
+
+ const operandType = {type: 'float32', dimensions: [2, 2]};
+ const context = await navigator.ml.createContext();
+ const builder = new MLGraphBuilder(context);
+ // 1. Create a computational graph 'C = 0.2 * A + B'.
+ const constant = builder.constant(0.2);
+ const A = builder.input('A', operandType);
+ const B = builder.input('B', operandType);
+ const C = builder.add(builder.mul(A, constant), B);
+ // 2. Compile it into an executable.
+ const graph = await builder.build({'C': C});
+ // 3. Bind inputs to the graph and execute for the result.
+ const bufferA = new Float32Array(4).fill(1.0);
+ const bufferB = new Float32Array(4).fill(0.8);
+ const bufferC = new Float32Array(4);
+ const inputs = {'A': bufferA, 'B': bufferB};
+ const outputs = {'C': bufferC};
+ const result = await context.compute(graph, inputs, outputs);
+ // The computed result of [[1, 1], [1, 1]] is in the buffer associated with
+ // the output operand.
+ console.log('Output value: ' + result.outputs.C);
+ // Note: the result.outputs.C buffer is different from the bufferC, but it
+ // shares the same backing memory allocation.
+
++
if (options.minValue === undefined) {
if (options.maxValue === undefined) {
return x;
@@ -1537,17 +1790,23 @@ partial interface MLGraphBuilder {
builder.constant(options.maxValue));
}
}
-
+
+
// This sample shows the case that the splits parameter is an array.
const outputs = [];
let starts = Array(input_rank).fill(0);
@@ -3195,8 +3472,8 @@ partial interface MLGraphBuilder {
start += size;
}
return outputs;
-
- -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); +
-// 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
-
+
+ // 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
+
+