Files
sousa-gecko/testing/web-platform/tests/webnn/validation_tests/argMinMax.https.any.js
T
Ningxin Hu b8ab0b6ce9 Bug 1993493 [wpt PR 55147] - WebNN: Align tensor limits implementation with spec, a=testonly
Automatic update from web-platform-tests
WebNN: Align tensor limits implementation with spec

This CL aligns the tensor limits setting in
`WebNNContextImpl::IntersectWithBaseProperties` with spec, especially
for scalar operand limits that was fixed by spec PR [1].

The change includes:
1. argMin/Max doesn't accept scalar input and output data types except
   int32 and int64 [2]
2. batchNormalization doesn't accept scalar input [3]
3. concat doesn't accept scalar input [4]
4. conv2d/convTranspose2d only accept floating-point input data types
   [5]
5. softmax doesn't accept scalar input [6]
6. split doesn't accept scalar input [7]

Pad [8] and slice [9] support scalar input as a no-op. This CL
replaces pad or slice having scalar input with an identity operator at
MLGraphBuilder to unify the behaviors across backends.

[1]: https://github.com/webmachinelearning/webnn/pull/882
[2]: https://www.w3.org/TR/webnn/#tensor-limits-argMin-argMax
[3]: https://www.w3.org/TR/webnn/#tensor-limits-batchNormalization
[4]: https://www.w3.org/TR/webnn/#tensor-limits-concat
[5]: https://www.w3.org/TR/webnn/#tensor-limits-conv2d
[6]: https://www.w3.org/TR/webnn/#tensor-limits-softmax
[7]: https://www.w3.org/TR/webnn/#tensor-limits-split
[8]: https://www.w3.org/TR/webnn/#tensor-limits-pad
[9]: https://www.w3.org/TR/webnn/#tensor-limits-slice

Change-Id: I8480cf9ef1e9e18a175677a16a553c1562a747c5
Bug: 446481989
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6972256
Commit-Queue: ningxin hu <ningxin.hu@intel.com>
Reviewed-by: Reilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1527306}

--

wpt-commits: a460ea73b9d67a705401622c6a7f8c0088b6a036
wpt-pr: 55147
2025-10-20 16:38:43 +00:00

113 lines
3.2 KiB
JavaScript

// META: title=validation tests for WebNN API argMin/Max operations
// META: global=window
// META: variant=?cpu
// META: variant=?gpu
// META: variant=?npu
// META: script=../resources/utils_validation.js
'use strict';
const kArgMinMaxOperators = [
'argMin',
'argMax',
];
const label = 'arg_min_max_1_!';
const tests = [
{
name: '[argMin/Max] Test with default options.',
input: {dataType: 'float32', shape: [1, 2, 3, 4]},
axis: 0,
output: {shape: [2, 3, 4]}
},
{
name: '[argMin/Max] Test with axes=1.',
input: {dataType: 'float32', shape: [1, 2, 3, 4]},
axis: 1,
output: {shape: [1, 3, 4]}
},
{
name: '[argMin/Max] Test with outputDataType=int32',
input: {dataType: 'float32', shape: [1, 2, 3, 4]},
axis: 1,
options: {
outputDataType: 'int32',
},
output: {shape: [1, 3, 4]}
},
{
name: '[argMin/Max] Test with outputDataType=int64',
input: {dataType: 'float32', shape: [1, 2, 3, 4]},
axis: 1,
options: {
outputDataType: 'int64',
},
output: {shape: [1, 3, 4]}
},
{
name:
'[argMin/Max] Throw if the value in axis is greater than or equal to input rank.',
input: {dataType: 'float32', shape: [1, 2, 3, 4]},
axis: 4,
options: {
label: label,
},
},
{
name: '[argMin/Max] Throw if input is a scalar and axis=0.',
input: {dataType: 'float32', shape: []},
axis: 0,
options: {
label: label,
},
},
{
name: '[argMin/Max] Throw if outputDataType=float32',
input: {dataType: 'float32', shape: [1, 2, 3, 4]},
axis: 1,
options: {outputDataType: 'float32', label: label}
}
];
function runTests(operatorName, tests) {
tests.forEach(test => {
promise_test(async t => {
const builder = new MLGraphBuilder(context);
const input = builder.input('input', test.input);
const axis = test.axis;
if (!context.opSupportLimits()[operatorName].input.dataTypes.includes(test.input.dataType)){
assert_throws_js(
TypeError, () => builder[operatorName](input, axis, test.options));
return;
}
if (test.options && test.options.outputDataType !== undefined) {
if (context.opSupportLimits()[operatorName].output.dataTypes.includes(
test.options.outputDataType)) {
const output = builder[operatorName](input, axis, test.options);
assert_equals(output.dataType, test.options.outputDataType);
assert_array_equals(output.shape, test.output.shape);
} else {
assert_throws_js(
TypeError, () => builder[operatorName](input, axis, test.options));
}
return;
}
if (test.output) {
const output = builder[operatorName](input, axis, test.options);
assert_equals(output.dataType, 'int32');
assert_array_equals(output.shape, test.output.shape);
} else {
const regrexp = /\[arg_min_max_1_\!\]/;
assert_throws_with_label(
() => builder[operatorName](input, axis, test.options), regrexp);
}
}, test.name.replace('[argMin/Max]', `[${operatorName}]`));
});
}
kArgMinMaxOperators.forEach((operatorName) => {
validateInputFromAnotherBuilder(operatorName);
runTests(operatorName, tests);
});