Automatic update from web-platform-tests webnn: limit concat and split inputs/outputs Validate that split inputs and concat outputs can't exceed 8192. Bug: 505137978, 505136542 Change-Id: I0caad753c6ef2685e3ccbfe3dc70821c78cb7d8c Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/7842056 Commit-Queue: Phillis Tang <phillis@chromium.org> Reviewed-by: Reilly Grant <reillyg@chromium.org> Cr-Commit-Position: refs/heads/main@{#1630257} -- wpt-commits: 82795e6da319636a10b90999cf32aa1070713129 wpt-pr: 59857
160 lines
5.0 KiB
JavaScript
160 lines
5.0 KiB
JavaScript
// META: title=validation tests for WebNN API concat operation
|
|
// META: global=window
|
|
// META: variant=?cpu
|
|
// META: variant=?gpu
|
|
// META: variant=?npu
|
|
// META: script=../resources/utils_validation.js
|
|
|
|
'use strict';
|
|
|
|
const label = `concate_123`;
|
|
const tests = [
|
|
{
|
|
name: '[concat] Test building Concat with one input.',
|
|
inputs: [{dataType: 'float32', shape: [4, 4, 3]}],
|
|
axis: 2,
|
|
output: {dataType: 'float32', shape: [4, 4, 3]}
|
|
},
|
|
{
|
|
name: '[concat] Test building Concat with two inputs',
|
|
inputs: [
|
|
{dataType: 'float32', shape: [3, 1, 5]},
|
|
{dataType: 'float32', shape: [3, 2, 5]}
|
|
],
|
|
axis: 1,
|
|
output: {dataType: 'float32', shape: [3, 3, 5]}
|
|
},
|
|
{
|
|
name: '[concat] Test building Concat with three inputs',
|
|
inputs: [
|
|
{dataType: 'float32', shape: [3, 5, 1]},
|
|
{dataType: 'float32', shape: [3, 5, 2]},
|
|
{dataType: 'float32', shape: [3, 5, 3]}
|
|
],
|
|
axis: 2,
|
|
output: {dataType: 'float32', shape: [3, 5, 6]}
|
|
},
|
|
{
|
|
name: '[concat] Test building Concat with two 1D inputs.',
|
|
inputs:
|
|
[{dataType: 'float32', shape: [1]}, {dataType: 'float32', shape: [1]}],
|
|
axis: 0,
|
|
output: {dataType: 'float32', shape: [2]}
|
|
},
|
|
{
|
|
name: '[concat] Throw if the inputs are empty.',
|
|
axis: 0,
|
|
},
|
|
{
|
|
name: '[concat] Throw if the argument types are inconsistent.',
|
|
inputs: [
|
|
{dataType: 'float32', shape: [1, 1]}, {dataType: 'int32', shape: [1, 1]}
|
|
],
|
|
axis: 0,
|
|
},
|
|
{
|
|
name: '[concat] Throw if the inputs have different ranks.',
|
|
inputs: [
|
|
{dataType: 'float32', shape: [1, 1]},
|
|
{dataType: 'float32', shape: [1, 1, 1]}
|
|
],
|
|
axis: 0,
|
|
},
|
|
{
|
|
name:
|
|
'[concat] Throw if the axis is equal to or greater than the size of ranks',
|
|
inputs: [
|
|
{dataType: 'float32', shape: [1, 1]}, {dataType: 'float32', shape: [1, 1]}
|
|
],
|
|
axis: 2,
|
|
},
|
|
{
|
|
name: '[concat] Throw if concat with two 0-D scalars.',
|
|
inputs:
|
|
[{dataType: 'float32', shape: []}, {dataType: 'float32', shape: []}],
|
|
axis: 0,
|
|
},
|
|
{
|
|
name:
|
|
'[concat] Throw if the inputs have other axes with different sizes except on the axis.',
|
|
inputs: [
|
|
{dataType: 'float32', shape: [1, 1, 1]},
|
|
{dataType: 'float32', shape: [1, 2, 3]}
|
|
],
|
|
axis: 1,
|
|
},
|
|
];
|
|
|
|
tests.forEach(
|
|
test => promise_test(async t => {
|
|
const builder = new MLGraphBuilder(context);
|
|
let inputs = [];
|
|
if (test.inputs) {
|
|
for (let i = 0; i < test.inputs.length; ++i) {
|
|
inputs[i] = builder.input(`inputs[${i}]`, test.inputs[i]);
|
|
}
|
|
}
|
|
if (test.output) {
|
|
const output = builder.concat(inputs, test.axis);
|
|
assert_equals(output.dataType, test.output.dataType);
|
|
assert_array_equals(output.shape, test.output.shape);
|
|
} else {
|
|
const options = {label};
|
|
const regrexp = new RegExp('\\[' + label + '\\]');
|
|
assert_throws_with_label(
|
|
() => builder.concat(inputs, test.axis, options), regrexp);
|
|
}
|
|
}, test.name));
|
|
|
|
multi_builder_test(async (t, builder, otherBuilder) => {
|
|
const operandDescriptor = {dataType: 'float32', shape: [2, 2]};
|
|
|
|
const inputFromOtherBuilder = otherBuilder.input('input', operandDescriptor);
|
|
|
|
const input1 = builder.input('input', operandDescriptor);
|
|
const input2 = builder.input('input', operandDescriptor);
|
|
const input3 = builder.input('input', operandDescriptor);
|
|
|
|
assert_throws_js(
|
|
TypeError,
|
|
() => builder.concat([input1, input2, inputFromOtherBuilder, input3]));
|
|
}, '[concat] throw if any input is from another builder');
|
|
|
|
promise_test(async t => {
|
|
const builder = new MLGraphBuilder(context);
|
|
|
|
const operandDescriptor = {
|
|
dataType: 'float32',
|
|
shape: [context.opSupportLimits().maxTensorByteLength / 4]
|
|
};
|
|
const input1 = builder.input('input1', operandDescriptor);
|
|
const input2 = builder.input('input2', operandDescriptor);
|
|
const input3 = builder.input('input3', operandDescriptor);
|
|
|
|
assert_throws_js(
|
|
TypeError, () => builder.concat(input1, input2, input3));
|
|
}, '[concat] throw if the output tensor byte length exceeds limit');
|
|
|
|
// TODO(crbug.com/492421926): Add an element count limit to the spec.
|
|
promise_test(async t => {
|
|
const builder = new MLGraphBuilder(context);
|
|
if (!context.opSupportLimits().input.dataTypes.includes('int4')) {
|
|
return;
|
|
}
|
|
const operandDescriptor = {dataType: 'int4', shape: [46341, 46340]};
|
|
const input1 = builder.input('input1', operandDescriptor);
|
|
const input2 = builder.input('input2', operandDescriptor);
|
|
|
|
assert_throws_js(TypeError, () => builder.concat(input1, input2));
|
|
}, '[concat] throw if the output number of elements is too large');
|
|
|
|
promise_test(async t => {
|
|
const builder = new MLGraphBuilder(context);
|
|
const operandDescriptor = {dataType: 'float32', shape: [1]};
|
|
const inputs = [];
|
|
for (let i = 0; i < 8193; ++i) {
|
|
inputs.push(builder.input(`input${i}`, operandDescriptor));
|
|
}
|
|
assert_throws_js(TypeError, () => builder.concat(inputs));
|
|
}, '[concat] throw if the number of inputs exceeds limit');
|