Files
sousa-gecko/testing/web-platform/tests/webnn/validation_tests/resample2d.https.any.js
T
Joshua Bell 5ae4280952 Bug 1950253 [wpt PR 50919] - WebNN: Don't run per-op WPTs in non-window contexts, a=testonly
Automatic update from web-platform-tests
WebNN: Don't run per-op WPTs in non-window contexts

The WebNN tests are written as ".any.js" tests which can run in both
Window and Worker contexts. This is great! But we running every test
on every combination of (CPU, GPU, NPU) x (Window, Worker) consumes
significant cycles for little benefit. While tests and various backend
and platform implementations are in flux, it also adds significant
burden to gardeners.

Scope down to running just the Window variations for op-specific
tests. Tests for things like inputs, constants, tensors, and object
lifecycles are still run in all contexts, and identity() is retained
as a "canary".

Change-Id: I1f1c749ea4d002a578d6d2ca89579cec6b0090e2
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/6299831
Reviewed-by: Weizhong Xia <weizhong@google.com>
Commit-Queue: Weizhong Xia <weizhong@google.com>
Auto-Submit: Joshua Bell <jsbell@chromium.org>
Reviewed-by: Reilly Grant <reillyg@chromium.org>
Cr-Commit-Position: refs/heads/main@{#1424187}

--

wpt-commits: 092e1df62b17a27e7658334ee585c102fa25478d
wpt-pr: 50919
2025-02-28 06:54:48 +00:00

256 lines
8.1 KiB
JavaScript

// META: title=validation tests for WebNN API resample2d operation
// META: global=window
// META: variant=?cpu
// META: variant=?gpu
// META: variant=?npu
// META: script=../resources/utils_validation.js
'use strict';
const label = 'resample-2d';
const regrexp = new RegExp('\\[' + label + '\\]');
// Tests for resample2d(input, options)
const tests = [
{
name: '[resample2d] Test building resample2d with default options',
input: {dataType: 'float32', shape: [1, 1, 2, 4]},
output: {dataType: 'float32', shape: [1, 1, 2, 4]},
},
{
name: '[resample2d] Test building resample2d with scales=[2.0, 2.0]',
input: {dataType: 'float32', shape: [1, 1, 2, 4]},
options: {scales: [2.0, 2.0]},
output: {dataType: 'float32', shape: [1, 1, 4, 8]},
},
{
name: '[resample2d] Test building resample2d with scales=[0.5, 0.5]',
input: {dataType: 'float32', shape: [1, 1, 5, 5]},
options: {scales: [0.5, 0.5]},
output: {dataType: 'float32', shape: [1, 1, 2, 2]},
},
{
name:
'[resample2d] Test building resample2d with scales=[0.5, 0.5] and explicit axes=[2, 3]',
input: {dataType: 'float32', shape: [1, 1, 5, 5]},
options: {scales: [0.5, 0.5], axes: [2, 3]},
output: {dataType: 'float32', shape: [1, 1, 2, 2]},
},
{
name:
'[resample2d] Test building resample2d with scales=[1.0, 2.0] and axes=[0, 1]',
input: {dataType: 'float32', shape: [1, 1, 2, 4]},
options: {scales: [1.0, 2.0], axes: [0, 1]},
output: {dataType: 'float32', shape: [1, 2, 2, 4]},
},
{
name:
'[resample2d] Test building resample2d with scales=[2.0, 2.0] and axes=[1, 2]',
input: {dataType: 'float32', shape: [1, 1, 2, 4]},
options: {scales: [2.0, 2.0], axes: [1, 2]},
output: {dataType: 'float32', shape: [1, 2, 4, 4]},
},
{
name:
'[resample2d] Test building resample2d with sizes=[3, 6] ignored scales',
input: {dataType: 'float32', shape: [1, 1, 2, 4]},
options: {scales: [2.0, 2.0], sizes: [3, 6]},
output: {dataType: 'float32', shape: [1, 1, 3, 6]},
},
{
name:
'[resample2d] Test building resample2d with non consecutive axes=[0,2]',
input: {dataType: 'float32', shape: [1, 1, 2, 4]},
options: {
axes: [0, 2],
label: label,
},
output: {dataType: 'float32', shape: [1, 1, 2, 4]},
},
{
name:
'[resample2d] Throw if the dataType of input is not float32 or float16',
input: {dataType: 'int32', shape: [2, 4]},
options: {label},
},
{
name: '[resample2d] Throw if the rank of input is not 4',
input: {dataType: 'float32', shape: [2, 4]},
options: {label},
},
{
name: '[resample2d] Throw if the length of scales is not 2',
input: {dataType: 'float32', shape: [1, 1, 2, 4]},
options: {
scales: [1.0, 1.0, 2.0, 2.0],
label: label,
},
},
{
name: '[resample2d] Throw if any scale value is negative',
input: {dataType: 'float32', shape: [1, 1, 2, 4]},
options: {
scales: [1.0, -2.0],
label: label,
},
},
{
name: '[resample2d] Throw if any scale value is 0',
input: {dataType: 'float32', shape: [1, 1, 2, 4]},
options: {
scales: [0, 2.0],
label: label,
},
},
{
name: '[resample2d] Throw if the length of sizes is not 2',
input: {dataType: 'float32', shape: [1, 1, 2, 4]},
options: {
sizes: [1, 1, 4, 6],
label: label,
},
},
{
name: '[resample2d] Throw if sizes[0] is not a valid dimension',
input: {dataType: 'float32', shape: [1, 1, 2, 4]},
options: {
sizes: [0, 1],
label: label,
},
},
{
name: '[resample2d] Throw if sizes[1] is not a valid dimension',
input: {dataType: 'float32', shape: [1, 1, 2, 4]},
options: {
sizes: [1, 0],
label: label,
},
},
{
name:
'[resample2d] Throw if any size value is out of \'unsigned long\' value range',
input: {dataType: 'float32', shape: [1, 1, 2, 4]},
options: {sizes: [kMaxUnsignedLong + 1, kMaxUnsignedLong + 1]},
},
{
name:
'[resample2d] Throw if outputHeight being floor(scaleHeight*inputHeight) is too large',
input: {dataType: 'float32', shape: [1, 1, 2, 4]},
// The maximum dimension size is kMaxUnsignedLong (2 ** 32 - 1).
// Here scaleHeight=kMaxUnsignedLong and inputHeight=2,
// so outputHeight being kMaxUnsignedLong*2 > kMaxUnsignedLong .
options: {scales: /*[scaleHeight, scaleWidth]*/[kMaxUnsignedLong, 1]},
},
{
name: '[resample2d] Throw if scaleHeight is too small',
input: {dataType: 'float32', shape: [1, 1, 2, 4]},
// Here scaleHeight=0.02 and inputHeight=2,
// so outputHeight would be 0.
// Link to https://github.com/webmachinelearning/webnn/issues/391.
options: {
scales: /*[scaleHeight, scaleWidth]*/[0.02, 0.8],
label: label,
},
},
{
name:
'[resample2d] Throw if outputWidth being floor(scaleWidth*inputWidth) is too large',
input: {dataType: 'float32', shape: [1, 1, 4, 2]},
// The maximum dimension size is kMaxUnsignedLong (2 ** 32 - 1).
// Here scaleWidth=kMaxUnsignedLong and inputWidth=2,
// so outputWidth being kMaxUnsignedLong*2 > kMaxUnsignedLong .
options: {scales: /*[scaleHeight, scaleWidth]*/[1, kMaxUnsignedLong]},
},
{
name: '[resample2d] Throw if scaleWidth is too small',
input: {dataType: 'float32', shape: [1, 1, 2, 4]},
// Here scaleWidth=0.1 and inputWidth=4,
// so outputWidth would be 0.
// Link to https://github.com/webmachinelearning/webnn/issues/391.
options: {
scales: /*[scaleHeight, scaleWidth]*/[0.7, 0.1],
label: label,
},
},
{
name: '[resample2d] Throw if the length of axes is not 2',
input: {dataType: 'float32', shape: [1, 1, 2, 4]},
options: {
axes: [0, 1, 2],
label: label,
},
},
{
name:
'[resample2d] Throw if any axis value is greater than or equal to the input rank',
input: {dataType: 'float32', shape: [1, 1, 2, 4]},
options: {
axes: [3, 4],
label: label,
},
},
{
name: '[resample2d] Throw if the values of axes are same',
input: {dataType: 'float32', shape: [1, 1, 2, 4]},
options: {
axes: [0, 0],
label: label,
},
},
];
tests.forEach(
test => promise_test(async t => {
const builder = new MLGraphBuilder(context);
const input = builder.input('input', test.input);
const options = test.options ?? {};
if (test.output) {
const output = builder.resample2d(input, options);
assert_equals(output.dataType, test.output.dataType);
assert_array_equals(output.shape, test.output.shape);
} else {
const options = {...test.options};
if (options.label) {
assert_throws_with_label(
() => builder.resample2d(input, options), regrexp);
} else {
assert_throws_js(TypeError, () => builder.resample2d(input, options));
}
}
}, test.name));
validateInputFromAnotherBuilder(
'resample2d', {dataType: 'float32', shape: [2, 2, 2, 2]});
promise_test(async t => {
for (let dataType of allWebNNOperandDataTypes) {
if (!context.opSupportLimits().input.dataTypes.includes(dataType)) {
continue;
}
const builder = new MLGraphBuilder(context);
const shape = [1, 1, 2, 4];
const input = builder.input(`input`, {dataType, shape});
if (context.opSupportLimits().resample2d.input.dataTypes.includes(
dataType)) {
const output = builder.resample2d(input);
assert_equals(output.dataType, dataType);
assert_array_equals(output.shape, shape);
} else {
assert_throws_js(TypeError, () => builder.resample2d(input));
}
}
}, `[resample2d] Test resample2d with all of the data types.`);
promise_test(async t => {
const builder = new MLGraphBuilder(context);
const input = builder.input('input', {
dataType: 'float32',
shape: [1, 1, context.opSupportLimits().maxTensorByteLength / 4, 1]});
const options = {};
options.scales = [2.0, 2.0];
options.label = label;
assert_throws_with_label(
() => builder.resample2d(input, options), regrexp);
}, '[resample2d] throw if the output tensor byte length exceeds limit');