commit 1ed8d51accf511f093a676d907c56c5e23a5bddf
parent d121846642f80b36deb2a8531fb44d64187e364b
Author: Miao Bin <bin.miao@intel.com>
Date: Thu, 9 Oct 2025 20:31:16 +0000
Bug 1992118 [wpt PR 55149] - Reland "WebNN: Implement constant(dataType, value)", a=testonly
Automatic update from web-platform-tests
Reland "WebNN: Implement constant(dataType, value)"
This is a reland of commit cad9e7f7b19890c31644ac60db20c4eef12ec6bf
The original CL was reverted due to test failures on Mac platform caused
by missing WPT baseline updates. This reland CL includes the necessary
WPT baseline updates for Mac platform.
Original change's description:
> WebNN: Implement constant(dataType, value)
>
> This CL implements creating a scalar constant MLOperand of the specified
> value and data type (constant(dataType, value)) [1].
>
> This CL also adds WPT validation and conformance tests for creating
> scalar constants.
>
> [1]
> https://www.w3.org/TR/webnn/#api-mlgraphbuilder-constant-datatype-value
>
> Bug: 40206287
> Change-Id: I5dfd158c6374db037347fd4cfc855e355ea211de
> Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6918680
> Reviewed-by: Reilly Grant <reillyg@chromium.org>
> Reviewed-by: ningxin hu <ningxin.hu@intel.com>
> Commit-Queue: Bin Miao <bin.miao@intel.com>
> Cr-Commit-Position: refs/heads/main@{#1519067}
Bug: 40206287
Change-Id: Id9eb88847d5e8f0c5504ac66617e500e8291cf3c
Cq-Include-Trybots: luci.chromium.try:win11-blink-rel, mac14.arm64-blink-rel, mac14-blink-rel, mac15.arm64-blink-rel, mac15-blink-rel, linux-blink-rel
Include-Ci-Only-Tests: chromium.mac:mac14-arm64-rel-tests|blink_wpt_tests
Change-Id: Id9eb88847d5e8f0c5504ac66617e500e8291cf3c
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6977892
Reviewed-by: Reilly Grant <reillyg@chromium.org>
Reviewed-by: ningxin hu <ningxin.hu@intel.com>
Commit-Queue: Bin Miao <bin.miao@intel.com>
Cr-Commit-Position: refs/heads/main@{#1522661}
--
wpt-commits: a9e319edd6798c271d96407103c3176b455662c4
wpt-pr: 55149
Diffstat:
2 files changed, 175 insertions(+), 0 deletions(-)
diff --git a/testing/web-platform/tests/webnn/conformance_tests/scalars.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/scalars.https.any.js
@@ -77,3 +77,65 @@ promise_test(async () => {
new Int32Array(await mlContext.readTensor(outputTensor)),
Int32Array.from([7]));
}, 'int32 scalar input, constant, and output');
+
+// Tests for constant(type, value)
+promise_test(async () => {
+ const builder = new MLGraphBuilder(mlContext);
+ const inputOperand = builder.input('input', {dataType: 'float32', shape: []});
+ const constantOperand = builder.constant('float32', 3.0);
+ const addOperand = builder.add(inputOperand, constantOperand);
+
+ const [inputTensor, outputTensor, mlGraph] = await Promise.all([
+ mlContext.createTensor({dataType: 'float32', shape: [], writable: true}),
+ mlContext.createTensor({dataType: 'float32', shape: [], readable: true}),
+ builder.build({'output': addOperand})
+ ]);
+
+ mlContext.writeTensor(inputTensor, Float32Array.from([2.0]));
+ mlContext.dispatch(mlGraph, {'input': inputTensor}, {'output': outputTensor});
+
+ const result = new Float32Array(await mlContext.readTensor(outputTensor));
+ assert_array_equals(result, Float32Array.from([5.0]));
+}, 'scalar constant created with constant(type, value) - float32');
+
+promise_test(async () => {
+ const builder = new MLGraphBuilder(mlContext);
+ const inputOperand = builder.input('input', {dataType: 'int32', shape: []});
+ const constantOperand = builder.constant('int32', 42);
+ const mulOperand = builder.mul(inputOperand, constantOperand);
+
+ const [inputTensor, outputTensor, mlGraph] = await Promise.all([
+ mlContext.createTensor({dataType: 'int32', shape: [], writable: true}),
+ mlContext.createTensor({dataType: 'int32', shape: [], readable: true}),
+ builder.build({'output': mulOperand})
+ ]);
+
+ mlContext.writeTensor(inputTensor, Int32Array.from([3]));
+ mlContext.dispatch(mlGraph, {'input': inputTensor}, {'output': outputTensor});
+ assert_array_equals(
+ new Int32Array(await mlContext.readTensor(outputTensor)),
+ Int32Array.from([126]));
+}, 'scalar constant created with constant(type, value) - int32');
+
+promise_test(async () => {
+ const builder = new MLGraphBuilder(mlContext);
+ const inputOperand = builder.input('input', {dataType: 'float16', shape: [3]});
+ const zeroConstant = builder.constant('float16', 2.0);
+ const negativeConstant = builder.constant('float16', -1.0);
+
+ // Test complex expression: input * 2 + (-1.0)
+ const mulResult = builder.mul(inputOperand, zeroConstant);
+ const addResult = builder.add(mulResult, negativeConstant);
+
+ const [inputTensor, outputTensor, mlGraph] = await Promise.all([
+ mlContext.createTensor({dataType: 'float16', shape: [3], writable: true}),
+ mlContext.createTensor({dataType: 'float16', shape: [3], readable: true}),
+ builder.build({'output': addResult})
+ ]);
+
+ mlContext.writeTensor(inputTensor, Float16Array.from([1.0, 2.0, 3.0]));
+ mlContext.dispatch(mlGraph, {'input': inputTensor}, {'output': outputTensor});
+
+ const result = new Float16Array(await mlContext.readTensor(outputTensor));
+ assert_array_equals(result, Float16Array.from([1.0, 3.0, 5.0]));
+}, 'multiple scalar constants in expression - float16');
diff --git a/testing/web-platform/tests/webnn/validation_tests/constant.https.any.js b/testing/web-platform/tests/webnn/validation_tests/constant.https.any.js
@@ -204,6 +204,102 @@ const tests = [
}
];
+// Tests for constant(type, value)
+const scalarTests = [
+ {
+ name: '[constant] Test building a scalar constant with float32 data type',
+ dataType: 'float32',
+ value: 3.14,
+ output: {dataType: 'float32'}
+ },
+ {
+ name: '[constant] Test building a scalar constant with float16 data type',
+ dataType: 'float16',
+ value: 2.5,
+ output: {dataType: 'float16'}
+ },
+ {
+ name: '[constant] Test building a scalar constant with int32 data type',
+ dataType: 'int32',
+ value: 42,
+ output: {dataType: 'int32'}
+ },
+ {
+ name: '[constant] Test building a scalar constant with uint32 data type',
+ dataType: 'uint32',
+ value: 123,
+ output: {dataType: 'uint32'}
+ },
+ {
+ name: '[constant] Test building a scalar constant with max safe integer as BigInt',
+ dataType: 'int64',
+ value: 9007199254740991n,
+ output: {dataType: 'int64'}
+ },
+ {
+ name: '[constant] Test building a scalar constant with max uint64 as BigInt',
+ dataType: 'uint64',
+ value: 18446744073709551615n,
+ output: {dataType: 'uint64'}
+ },
+ {
+ name: '[constant] Test building a scalar constant with int8 data type',
+ dataType: 'int8',
+ value: -128,
+ output: {dataType: 'int8'}
+ },
+ {
+ name: '[constant] Test building a scalar constant with uint8 data type',
+ dataType: 'uint8',
+ value: 255,
+ output: {dataType: 'uint8'}
+ },
+ {
+ name: '[constant] Test building a scalar constant with zero value',
+ dataType: 'float32',
+ value: 0.0,
+ output: {dataType: 'float32'}
+ },
+ {
+ name: '[constant] Test building a scalar constant with negative value',
+ dataType: 'int32',
+ value: -42,
+ output: {dataType: 'int32'}
+ },
+ {
+ name: '[constant] Test building a scalar constant with large float32 value',
+ dataType: 'float32',
+ value: 3.4028235e+38,
+ output: {dataType: 'float32'}
+ },
+ {
+ name: '[constant] Test building a scalar constant with small float32 value',
+ dataType: 'float32',
+ value: 1.175494e-38,
+ output: {dataType: 'float32'}
+ },
+ {
+ name: '[constant] Throw if building a scalar constant with int4 data type',
+ dataType: 'int4',
+ value: -2
+ },
+ {
+ name: '[constant] Throw if building a scalar constant with uint4 data type',
+ dataType: 'uint4',
+ value: 2
+ },
+ {
+ name: '[constant] Throw if using operand data type that isn\'t of type MLOperandDataType',
+ dataType: 'int16',
+ value: 123
+ },
+ {
+ name: '[constant] Throw if using BigInt value for float32 data type',
+ dataType: 'float32',
+ value: 123n
+ },
+];
+
tests.forEach(
test => promise_test(async t => {
const builder = new MLGraphBuilder(context);
@@ -261,3 +357,20 @@ tests.forEach(
}
}
}, test.name));
+
+// Test scalar constant cases
+scalarTests.forEach(
+ test => promise_test(async t => {
+ const builder = new MLGraphBuilder(context);
+
+ if (test.output) {
+ // Test successful case
+ const constantOperand = builder.constant(test.dataType, test.value);
+ assert_equals(constantOperand.dataType, test.output.dataType);
+ assert_array_equals(constantOperand.shape, []);
+ } else {
+ // Test error case
+ assert_throws_js(
+ TypeError, () => builder.constant(test.dataType, test.value));
+ }
+ }, test.name));