diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-12 05:43:14 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-06-12 05:43:14 +0000 |
commit | 8dd16259287f58f9273002717ec4d27e97127719 (patch) | |
tree | 3863e62a53829a84037444beab3abd4ed9dfc7d0 /testing/web-platform/tests/webnn | |
parent | Releasing progress-linux version 126.0.1-1~progress7.99u1. (diff) | |
download | firefox-8dd16259287f58f9273002717ec4d27e97127719.tar.xz firefox-8dd16259287f58f9273002717ec4d27e97127719.zip |
Merging upstream version 127.0.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to '')
118 files changed, 2652 insertions, 1094 deletions
diff --git a/testing/web-platform/tests/webnn/conformance_tests/arg_min_max.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/arg_min_max.https.any.js index 123c8b1048..0f9e590fc8 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/arg_min_max.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/arg_min_max.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API argMin/Max operations // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-argminmax -testWebNNOperation(['argMin', 'argMax'], buildOperationWithSingleInput);
\ No newline at end of file +runWebNNConformanceTests(['argMin', 'argMax'], buildOperationWithSingleInput); diff --git a/testing/web-platform/tests/webnn/conformance_tests/batch_normalization.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/batch_normalization.https.any.js index 9a1c85db19..d3107820db 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/batch_normalization.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/batch_normalization.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API batchNormalization operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-batchnorm -testWebNNOperation('batchNormalization', buildBatchNorm);
\ No newline at end of file +runWebNNConformanceTests('batchNormalization', buildBatchNorm); diff --git a/testing/web-platform/tests/webnn/conformance_tests/buffer.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/buffer.https.any.js index 9391be8dbf..5a09b05c7d 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/buffer.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/buffer.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API buffer operations // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,10 +9,11 @@ // https://webmachinelearning.github.io/webnn/#api-mlbuffer -testCreateWebNNBuffer("create", 4); - -testDestroyWebNNBuffer('destroyTwice'); - -testReadWebNNBuffer('read'); - -testWriteWebNNBuffer('write'); +if (navigator.ml) { + testCreateWebNNBuffer('create', 4); + testDestroyWebNNBuffer('destroyTwice'); + testReadWebNNBuffer('read'); + testWriteWebNNBuffer('write'); +} else { + test(() => assert_implements(navigator.ml, 'missing navigator.ml')); +} diff --git a/testing/web-platform/tests/webnn/conformance_tests/cast.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/cast.https.any.js index bde2b9a4ce..086428dd96 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/cast.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/cast.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API cast operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-cast -testWebNNOperation('cast', buildCast);
\ No newline at end of file +runWebNNConformanceTests('cast', buildCast); diff --git a/testing/web-platform/tests/webnn/conformance_tests/clamp.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/clamp.https.any.js index 7b60c41f2c..ab47ac9c5c 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/clamp.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/clamp.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API clamp operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-clamp -testWebNNOperation('clamp', buildOperationWithSingleInput);
\ No newline at end of file +runWebNNConformanceTests('clamp', buildOperationWithSingleInput); diff --git a/testing/web-platform/tests/webnn/conformance_tests/compute-arraybufferview-with-bigger-arraybuffer.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/compute-arraybufferview-with-bigger-arraybuffer.https.any.js new file mode 100644 index 0000000000..62ce16c93e --- /dev/null +++ b/testing/web-platform/tests/webnn/conformance_tests/compute-arraybufferview-with-bigger-arraybuffer.https.any.js @@ -0,0 +1,61 @@ +// META: title=test WebNN MLContext.compute() for ArrayBufferView created from bigger ArrayBuffer +// META: global=window,dedicatedworker +// META: variant=?gpu +// META: script=../resources/utils.js + +'use strict'; + +// These tests are used to reproduce the Chromium issue: +// https://issues.chromium.org/issues/332151809 + +if (navigator.ml) { + const variant = location.search.substring(1); + const contextOptions = kContextOptionsForVariant[variant]; + + let context; + let builder; + + promise_setup(async () => { + let supported = false; + try { + context = await navigator.ml.createContext(contextOptions); + supported = true; + } catch (e) { + } + assert_implements( + supported, `Unable to create context for ${variant} variant`); + builder = new MLGraphBuilder(context); + }); + + promise_test(async t => { + const a = builder.input('a', {dataType: 'float32', dimensions: [2]}); + const b = builder.relu(a); + const graph = await builder.build({b}); + const arraybuffer = new ArrayBuffer(100); + const aBuffer = + new Float32Array(arraybuffer, /*byteOffset*/ 4, /*length*/ 2) + aBuffer.set([1, -1]); + const bBuffer = new Float32Array(2); + const results = + await context.compute(graph, {'a': aBuffer}, {'b': bBuffer}); + assert_array_approx_equals_ulp( + results.outputs.b, [1, 0], /*nulp*/ 0, 'float32'); + }, 'Test compute() working for input ArrayBufferView created from bigger ArrayBuffer'); + + promise_test(async t => { + const a = builder.input('a', {dataType: 'float32', dimensions: [2]}); + const b = builder.relu(a); + const graph = await builder.build({b}); + const aBuffer = new Float32Array(2); + aBuffer.set([1, -1]); + const arraybuffer = new ArrayBuffer(100); + const bBuffer = + new Float32Array(arraybuffer, /*byteOffset*/ 8, /*length*/ 2); + const results = + await context.compute(graph, {'a': aBuffer}, {'b': bBuffer}); + assert_array_approx_equals_ulp( + results.outputs.b, [1, 0], /*nulp*/ 0, 'float32'); + }, 'Test compute() working for output ArrayBufferView created from bigger ArrayBuffer'); +} else { + test(() => assert_implements(navigator.ml, 'missing navigator.ml')); +} diff --git a/testing/web-platform/tests/webnn/conformance_tests/concat.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/concat.https.any.js index 254e0b657b..619f20fe1c 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/concat.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/concat.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API concat operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-concat -testWebNNOperation('concat', buildConcat);
\ No newline at end of file +runWebNNConformanceTests('concat', buildConcat); diff --git a/testing/web-platform/tests/webnn/conformance_tests/constant.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/constant.https.any.js index 4814734886..79362947f1 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/constant.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/constant.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API constant // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-constant-range -testWebNNOperation('constant', buildConstantRange);
\ No newline at end of file +runWebNNConformanceTests('constant', buildConstantRange); diff --git a/testing/web-platform/tests/webnn/conformance_tests/conv2d.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/conv2d.https.any.js index 0d9a621356..34af583162 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/conv2d.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/conv2d.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API conv2d operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-conv2d -testWebNNOperation('conv2d', buildConv2d);
\ No newline at end of file +runWebNNConformanceTests('conv2d', buildConv2d); diff --git a/testing/web-platform/tests/webnn/conformance_tests/conv_transpose2d.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/conv_transpose2d.https.any.js index ee5d28c72a..2943e67851 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/conv_transpose2d.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/conv_transpose2d.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API convTranspose2d operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-convtranspose2d -testWebNNOperation('convTranspose2d', buildConvTranspose2d);
\ No newline at end of file +runWebNNConformanceTests('convTranspose2d', buildConvTranspose2d); diff --git a/testing/web-platform/tests/webnn/conformance_tests/elementwise_binary.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/elementwise_binary.https.any.js index 5db14a43a1..a85a06e1d2 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/elementwise_binary.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/elementwise_binary.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API element-wise binary operations // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,6 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-binary -testWebNNOperation(['add', 'sub', 'mul', 'div', 'max', 'min', 'pow'], buildOperationWithTwoInputs);
\ No newline at end of file +runWebNNConformanceTests( + ['add', 'sub', 'mul', 'div', 'max', 'min', 'pow'], + buildOperationWithTwoInputs); diff --git a/testing/web-platform/tests/webnn/conformance_tests/elementwise_logical.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/elementwise_logical.https.any.js index a60c199447..3d3a825f9c 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/elementwise_logical.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/elementwise_logical.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API element-wise logical operations // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,14 +9,17 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-logical -testWebNNOperation( - [ - 'equal', - 'greater', - 'greaterOrEqual', - 'lesser', - 'lesserOrEqual', - ], - buildOperationWithTwoInputs -); -testWebNNOperation('logicalNot', buildOperationWithSingleInput);
\ No newline at end of file +if (navigator.ml) { + testWebNNOperation( + [ + 'equal', + 'greater', + 'greaterOrEqual', + 'lesser', + 'lesserOrEqual', + ], + buildOperationWithTwoInputs); + testWebNNOperation('logicalNot', buildOperationWithSingleInput); +} else { + test(() => assert_implements(navigator.ml, 'missing navigator.ml')); +} diff --git a/testing/web-platform/tests/webnn/conformance_tests/elementwise_unary.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/elementwise_unary.https.any.js index 8029539eda..f202af01e5 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/elementwise_unary.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/elementwise_unary.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API element-wise unary operations // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,7 +9,9 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-unary -testWebNNOperation( - ['abs', 'ceil', 'cos', 'erf', 'exp', 'floor', 'identity', 'log', 'neg', 'reciprocal', 'sin', 'sqrt', 'tan'], - buildOperationWithSingleInput -);
\ No newline at end of file +runWebNNConformanceTests( + [ + 'abs', 'ceil', 'cos', 'erf', 'exp', 'floor', 'identity', 'log', 'neg', + 'reciprocal', 'sin', 'sqrt', 'tan' + ], + buildOperationWithSingleInput); diff --git a/testing/web-platform/tests/webnn/conformance_tests/elu.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/elu.https.any.js index 382faa97fd..ac1c19a80b 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/elu.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/elu.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API elu operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-elu -testWebNNOperation('elu', buildOperationWithSingleInput);
\ No newline at end of file +runWebNNConformanceTests('elu', buildOperationWithSingleInput); diff --git a/testing/web-platform/tests/webnn/conformance_tests/expand.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/expand.https.any.js index b1be129eac..e7bf106f96 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/expand.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/expand.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API expand operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,5 +9,5 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-expand -// reuse buildReshape method -testWebNNOperation('expand', buildReshape);
\ No newline at end of file +// Reuse buildReshape method +runWebNNConformanceTests('expand', buildReshape); diff --git a/testing/web-platform/tests/webnn/conformance_tests/gather.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gather.https.any.js index 39b1970563..504f2dd792 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/gather.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/gather.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API gather operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-gather -testWebNNOperation('gather', buildOperationWithTwoInputs);
\ No newline at end of file +runWebNNConformanceTests('gather', buildOperationWithTwoInputs); diff --git a/testing/web-platform/tests/webnn/conformance_tests/gemm.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gemm.https.any.js index 61fd7c9b39..03a836a44a 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/gemm.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/gemm.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API gemm operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-gemm -testWebNNOperation('gemm', buildGemm);
\ No newline at end of file +runWebNNConformanceTests('gemm', buildGemm); diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/arg_min_max.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/arg_min_max.https.any.js deleted file mode 100644 index c700ee5cad..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/arg_min_max.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API argMin/Max operations -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-argminmax - -testWebNNOperation(['argMin', 'argMax'], buildOperationWithSingleInput, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/batch_normalization.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/batch_normalization.https.any.js deleted file mode 100644 index 534cdf6365..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/batch_normalization.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API batchNormalization operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-batchnorm - -testWebNNOperation('batchNormalization', buildBatchNorm, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/buffer.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/buffer.https.any.js deleted file mode 100644 index 225bc40185..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/buffer.https.any.js +++ /dev/null @@ -1,16 +0,0 @@ -// META: title=test WebNN API buffer operations -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlbuffer - -testCreateWebNNBuffer("create", 4, 'gpu'); - -testDestroyWebNNBuffer('destroyTwice', 'gpu'); - -testReadWebNNBuffer('read', 'gpu'); - -testWriteWebNNBuffer('write', 'gpu'); diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/cast.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/cast.https.any.js deleted file mode 100644 index e4309ffd8e..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/cast.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API cast operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-cast - -testWebNNOperation('cast', buildCast, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/clamp.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/clamp.https.any.js deleted file mode 100644 index 9b3f93ecc7..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/clamp.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API clamp operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-clamp - -testWebNNOperation('clamp', buildOperationWithSingleInput, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/concat.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/concat.https.any.js deleted file mode 100644 index c0cfb8626b..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/concat.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API concat operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-concat - -testWebNNOperation('concat', buildConcat, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/constant.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/constant.https.any.js deleted file mode 100644 index 77b4d889a2..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/constant.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API constant -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-constant-range - -testWebNNOperation('constant', buildConstantRange, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/conv2d.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/conv2d.https.any.js deleted file mode 100644 index 770540abd8..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/conv2d.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API conv2d operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-conv2d - -testWebNNOperation('conv2d', buildConv2d, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/conv_transpose2d.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/conv_transpose2d.https.any.js deleted file mode 100644 index 08c441b5b4..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/conv_transpose2d.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API convTranspose2d operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-convtranspose2d - -testWebNNOperation('convTranspose2d', buildConvTranspose2d, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/elementwise_binary.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/elementwise_binary.https.any.js deleted file mode 100644 index 8b9fa486f8..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/elementwise_binary.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API element-wise binary operations -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-binary - -testWebNNOperation(['add', 'sub', 'mul', 'div', 'max', 'min', 'pow'], buildOperationWithTwoInputs, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/elementwise_logical.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/elementwise_logical.https.any.js deleted file mode 100644 index 70a887a147..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/elementwise_logical.https.any.js +++ /dev/null @@ -1,20 +0,0 @@ -// META: title=test WebNN API element-wise logical operations -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-logical - -testWebNNOperation( - [ - 'equal', - 'greater', - 'greaterOrEqual', - 'lesser', - 'lesserOrEqual', - ], - buildOperationWithTwoInputs, 'gpu' -); -testWebNNOperation('logicalNot', buildOperationWithSingleInput, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/elementwise_unary.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/elementwise_unary.https.any.js deleted file mode 100644 index 8871129311..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/elementwise_unary.https.any.js +++ /dev/null @@ -1,13 +0,0 @@ -// META: title=test WebNN API element-wise unary operations -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-unary - -testWebNNOperation( - ['abs', 'ceil', 'cos', 'erf', 'exp', 'floor', 'identity', 'log', 'neg', 'reciprocal', 'sin', 'sqrt', 'tan'], - buildOperationWithSingleInput, 'gpu' -);
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/elu.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/elu.https.any.js deleted file mode 100644 index db14442641..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/elu.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API elu operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-elu - -testWebNNOperation('elu', buildOperationWithSingleInput, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/expand.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/expand.https.any.js deleted file mode 100644 index f46f463781..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/expand.https.any.js +++ /dev/null @@ -1,11 +0,0 @@ -// META: title=test WebNN API expand operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-expand - -// reuse buildReshape method -testWebNNOperation('expand', buildReshape, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/gather.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/gather.https.any.js deleted file mode 100644 index 8e457192d8..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/gather.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API gather operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-gather - -testWebNNOperation('gather', buildOperationWithTwoInputs, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/gemm.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/gemm.https.any.js deleted file mode 100644 index f288c31bed..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/gemm.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API gemm operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-gemm - -testWebNNOperation('gemm', buildGemm, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/hard_sigmoid.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/hard_sigmoid.https.any.js deleted file mode 100644 index d40e42a211..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/hard_sigmoid.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API hardSigmoid operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-hard-sigmoid - -testWebNNOperation('hardSigmoid', buildOperationWithSingleInput, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/hard_swish.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/hard_swish.https.any.js deleted file mode 100644 index 031e65ee16..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/hard_swish.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API tanh operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-hard-swish - -testWebNNOperation('hardSwish', buildOperationWithSingleInput, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/instance_normalization.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/instance_normalization.https.any.js deleted file mode 100644 index ecfaac71ee..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/instance_normalization.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API instanceNormalization operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-instancenorm - -testWebNNOperation('instanceNormalization', buildLayerNorm, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/layer_normalization.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/layer_normalization.https.any.js deleted file mode 100644 index 0e4f6caebf..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/layer_normalization.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API layerNormalization operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-layernorm - -testWebNNOperation('layerNormalization', buildLayerNorm, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/leaky_relu.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/leaky_relu.https.any.js deleted file mode 100644 index 9fab2353b9..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/leaky_relu.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API leakyRelu operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-leakyrelu - -testWebNNOperation('leakyRelu', buildOperationWithSingleInput, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/linear.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/linear.https.any.js deleted file mode 100644 index ccec2c3eac..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/linear.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API linear operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-linear - -testWebNNOperation('linear', buildOperationWithSingleInput, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/matmul.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/matmul.https.any.js deleted file mode 100644 index 635ce84ac6..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/matmul.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API matmul operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-matmul - -testWebNNOperation('matmul', buildOperationWithTwoInputs, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/pad.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/pad.https.any.js deleted file mode 100644 index f313e2c9f9..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/pad.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API pad operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-pad - -testWebNNOperation('pad', buildPad, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/pooling.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/pooling.https.any.js deleted file mode 100644 index 837bca2c71..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/pooling.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API pooling operations -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-pool2d - -testWebNNOperation(['averagePool2d', 'l2Pool2d', 'maxPool2d'], buildOperationWithSingleInput, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/prelu.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/prelu.https.any.js deleted file mode 100644 index 475cd9e5ce..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/prelu.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API prelu operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-prelu - -testWebNNOperation('prelu', buildOperationWithTwoInputs, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/reduction.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/reduction.https.any.js deleted file mode 100644 index 0f3cefa02e..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/reduction.https.any.js +++ /dev/null @@ -1,24 +0,0 @@ -// META: title=test WebNN API reduction operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-reduce - -testWebNNOperation( - [ - 'reduceL1', - 'reduceL2', - 'reduceLogSum', - 'reduceLogSumExp', - 'reduceMax', - 'reduceMean', - 'reduceMin', - 'reduceProduct', - 'reduceSum', - 'reduceSumSquare', - ], - buildOperationWithSingleInput, 'gpu' -);
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/relu.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/relu.https.any.js deleted file mode 100644 index d1a35367df..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/relu.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API relu operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-relu - -testWebNNOperation('relu', buildOperationWithSingleInput, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/resample2d.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/resample2d.https.any.js deleted file mode 100644 index dd8e441946..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/resample2d.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API resample2d operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-resample2d-method - -testWebNNOperation('resample2d', buildOperationWithSingleInput, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/reshape.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/reshape.https.any.js deleted file mode 100644 index b0217d2e67..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/reshape.https.any.js +++ /dev/null @@ -1,11 +0,0 @@ -// META: title=test WebNN API reshape operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-reshape - -testWebNNOperation('reshape', buildReshape, 'gpu'); - diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/sigmoid.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/sigmoid.https.any.js deleted file mode 100644 index 26116c0ff9..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/sigmoid.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API sigmoid operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-sigmoid - -testWebNNOperation('sigmoid', buildOperationWithSingleInput, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/slice.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/slice.https.any.js deleted file mode 100644 index 1710c79a9c..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/slice.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API slice operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-slice - -testWebNNOperation('slice', buildSlice, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/softmax.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/softmax.https.any.js deleted file mode 100644 index 9eaffe2beb..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/softmax.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API softmax operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-softmax - -testWebNNOperation('softmax', buildOperationWithSingleInput, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/softplus.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/softplus.https.any.js deleted file mode 100644 index 5f06846113..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/softplus.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API softplus operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-softplus - -testWebNNOperation('softplus', buildOperationWithSingleInput, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/softsign.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/softsign.https.any.js deleted file mode 100644 index eac0b7ec40..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/softsign.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API softsign operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-softsign - -testWebNNOperation('softsign', buildOperationWithSingleInput, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/split.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/split.https.any.js deleted file mode 100644 index 3b0aafd787..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/split.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API split operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-split - -testWebNNOperation('split', buildSplit, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/tanh.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/tanh.https.any.js deleted file mode 100644 index 3029f4865a..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/tanh.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API tanh operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-tanh - -testWebNNOperation('tanh', buildOperationWithSingleInput, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/transpose.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/transpose.https.any.js deleted file mode 100644 index 295ef43ec1..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/transpose.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API transpose operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-transpose - -testWebNNOperation('transpose', buildOperationWithSingleInput, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/triangular.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/triangular.https.any.js deleted file mode 100644 index 3e1b0d5ab1..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/triangular.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API triangular operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-triangular - -testWebNNOperation('triangular', buildOperationWithSingleInput, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/gpu/where.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/gpu/where.https.any.js deleted file mode 100644 index 49c6cbd4e3..0000000000 --- a/testing/web-platform/tests/webnn/conformance_tests/gpu/where.https.any.js +++ /dev/null @@ -1,10 +0,0 @@ -// META: title=test WebNN API where operation -// META: global=window,dedicatedworker -// META: script=../../resources/utils.js -// META: timeout=long - -'use strict'; - -// https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-where - -testWebNNOperation('where', buildWhere, 'gpu');
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/conformance_tests/hard_sigmoid.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/hard_sigmoid.https.any.js index 8161a24538..55391e7f1c 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/hard_sigmoid.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/hard_sigmoid.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API hardSigmoid operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-hard-sigmoid -testWebNNOperation('hardSigmoid', buildOperationWithSingleInput);
\ No newline at end of file +runWebNNConformanceTests('hardSigmoid', buildOperationWithSingleInput); diff --git a/testing/web-platform/tests/webnn/conformance_tests/hard_swish.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/hard_swish.https.any.js index b4a7c53d8d..24b8c413bb 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/hard_swish.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/hard_swish.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API tanh operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-hard-swish -testWebNNOperation('hardSwish', buildOperationWithSingleInput);
\ No newline at end of file +runWebNNConformanceTests('hardSwish', buildOperationWithSingleInput); diff --git a/testing/web-platform/tests/webnn/conformance_tests/instance_normalization.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/instance_normalization.https.any.js index fce879172e..fc339e5bab 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/instance_normalization.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/instance_normalization.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API instanceNormalization operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-instancenorm -testWebNNOperation('instanceNormalization', buildLayerNorm);
\ No newline at end of file +runWebNNConformanceTests('instanceNormalization', buildLayerNorm); diff --git a/testing/web-platform/tests/webnn/conformance_tests/layer_normalization.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/layer_normalization.https.any.js index ab8a50cc03..ea3cd04240 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/layer_normalization.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/layer_normalization.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API layerNormalization operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-layernorm -testWebNNOperation('layerNormalization', buildLayerNorm);
\ No newline at end of file +runWebNNConformanceTests('layerNormalization', buildLayerNorm); diff --git a/testing/web-platform/tests/webnn/conformance_tests/leaky_relu.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/leaky_relu.https.any.js index 2b6f17e95d..b2a4055bde 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/leaky_relu.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/leaky_relu.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API leakyRelu operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-leakyrelu -testWebNNOperation('leakyRelu', buildOperationWithSingleInput);
\ No newline at end of file +runWebNNConformanceTests('leakyRelu', buildOperationWithSingleInput); diff --git a/testing/web-platform/tests/webnn/conformance_tests/linear.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/linear.https.any.js index 465b697f29..0e22f7a036 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/linear.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/linear.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API linear operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-linear -testWebNNOperation('linear', buildOperationWithSingleInput);
\ No newline at end of file +runWebNNConformanceTests('linear', buildOperationWithSingleInput); diff --git a/testing/web-platform/tests/webnn/conformance_tests/matmul.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/matmul.https.any.js index 64eeb37f08..da78230579 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/matmul.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/matmul.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API matmul operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-matmul -testWebNNOperation('matmul', buildOperationWithTwoInputs);
\ No newline at end of file +runWebNNConformanceTests('matmul', buildOperationWithTwoInputs); diff --git a/testing/web-platform/tests/webnn/conformance_tests/pad.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/pad.https.any.js index f1a2400d1c..d733cbb6ed 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/pad.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/pad.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API pad operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-pad -testWebNNOperation('pad', buildPad);
\ No newline at end of file +runWebNNConformanceTests('pad', buildPad); diff --git a/testing/web-platform/tests/webnn/conformance_tests/parallel-compute.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/parallel-compute.https.any.js new file mode 100644 index 0000000000..642fec9f73 --- /dev/null +++ b/testing/web-platform/tests/webnn/conformance_tests/parallel-compute.https.any.js @@ -0,0 +1,19 @@ +// META: title=test parallel WebNN API compute operations +// META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu +// META: script=../resources/utils.js +// META: timeout=long + +'use strict'; + +// https://webmachinelearning.github.io/webnn/#api-mlcontext-compute + +if (navigator.ml) { + testParallelCompute(); +} else { + // Show indication to users why the test failed + test( + () => assert_not_equals( + navigator.ml, undefined, 'ml property is defined on navigator')); +} diff --git a/testing/web-platform/tests/webnn/conformance_tests/pooling.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/pooling.https.any.js index 400d5ed37d..de2ae35a9c 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/pooling.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/pooling.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API pooling operations // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,5 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-pool2d -testWebNNOperation(['averagePool2d', 'l2Pool2d', 'maxPool2d'], buildOperationWithSingleInput);
\ No newline at end of file +runWebNNConformanceTests( + ['averagePool2d', 'l2Pool2d', 'maxPool2d'], buildOperationWithSingleInput); diff --git a/testing/web-platform/tests/webnn/conformance_tests/prelu.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/prelu.https.any.js index 83cc9db4b4..9337211e54 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/prelu.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/prelu.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API prelu operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-prelu -testWebNNOperation('prelu', buildOperationWithTwoInputs);
\ No newline at end of file +runWebNNConformanceTests('prelu', buildOperationWithTwoInputs); diff --git a/testing/web-platform/tests/webnn/conformance_tests/reduction.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/reduction.https.any.js index 30bfb4ba7a..c291906ba1 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/reduction.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/reduction.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API reduction operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,18 +9,17 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-reduce -testWebNNOperation( - [ - 'reduceL1', - 'reduceL2', - 'reduceLogSum', - 'reduceLogSumExp', - 'reduceMax', - 'reduceMean', - 'reduceMin', - 'reduceProduct', - 'reduceSum', - 'reduceSumSquare', - ], - buildOperationWithSingleInput -);
\ No newline at end of file +runWebNNConformanceTests( + [ + 'reduceL1', + 'reduceL2', + 'reduceLogSum', + 'reduceLogSumExp', + 'reduceMax', + 'reduceMean', + 'reduceMin', + 'reduceProduct', + 'reduceSum', + 'reduceSumSquare', + ], + buildOperationWithSingleInput); diff --git a/testing/web-platform/tests/webnn/conformance_tests/relu.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/relu.https.any.js index 51e427898f..7cb23eea1b 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/relu.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/relu.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API relu operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-relu -testWebNNOperation('relu', buildOperationWithSingleInput);
\ No newline at end of file +runWebNNConformanceTests('relu', buildOperationWithSingleInput); diff --git a/testing/web-platform/tests/webnn/conformance_tests/resample2d.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/resample2d.https.any.js index 0b5b3e0032..b5bdda7197 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/resample2d.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/resample2d.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API resample2d operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-resample2d-method -testWebNNOperation('resample2d', buildOperationWithSingleInput);
\ No newline at end of file +runWebNNConformanceTests('resample2d', buildOperationWithSingleInput); diff --git a/testing/web-platform/tests/webnn/conformance_tests/reshape.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/reshape.https.any.js index c0dafb176c..a7d03b2a0c 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/reshape.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/reshape.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API reshape operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,5 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-reshape -testWebNNOperation('reshape', buildReshape); - +runWebNNConformanceTests('reshape', buildReshape); diff --git a/testing/web-platform/tests/webnn/conformance_tests/sigmoid.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/sigmoid.https.any.js index 186f468918..9730b548b5 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/sigmoid.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/sigmoid.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API sigmoid operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-sigmoid -testWebNNOperation('sigmoid', buildOperationWithSingleInput);
\ No newline at end of file +runWebNNConformanceTests('sigmoid', buildOperationWithSingleInput); diff --git a/testing/web-platform/tests/webnn/conformance_tests/slice.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/slice.https.any.js index 6441204517..b316ea58c4 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/slice.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/slice.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API slice operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-slice -testWebNNOperation('slice', buildSlice);
\ No newline at end of file +runWebNNConformanceTests('slice', buildSlice); diff --git a/testing/web-platform/tests/webnn/conformance_tests/softmax.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/softmax.https.any.js index 143b7d969f..a68a32c45f 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/softmax.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/softmax.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API softmax operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-softmax -testWebNNOperation('softmax', buildOperationWithSingleInput);
\ No newline at end of file +runWebNNConformanceTests('softmax', buildOperationWithSingleInput); diff --git a/testing/web-platform/tests/webnn/conformance_tests/softplus.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/softplus.https.any.js index fcd6410bdb..7d89b117eb 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/softplus.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/softplus.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API softplus operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-softplus -testWebNNOperation('softplus', buildOperationWithSingleInput);
\ No newline at end of file +runWebNNConformanceTests('softplus', buildOperationWithSingleInput); diff --git a/testing/web-platform/tests/webnn/conformance_tests/softsign.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/softsign.https.any.js index 6e26afdade..e175e0de56 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/softsign.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/softsign.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API softsign operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-softsign -testWebNNOperation('softsign', buildOperationWithSingleInput);
\ No newline at end of file +runWebNNConformanceTests('softsign', buildOperationWithSingleInput); diff --git a/testing/web-platform/tests/webnn/conformance_tests/split.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/split.https.any.js index 0de6cb4d8d..78d707687f 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/split.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/split.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API split operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-split -testWebNNOperation('split', buildSplit);
\ No newline at end of file +runWebNNConformanceTests('split', buildSplit); diff --git a/testing/web-platform/tests/webnn/conformance_tests/tanh.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/tanh.https.any.js index c5d1f86ab1..e3ab5e9192 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/tanh.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/tanh.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API tanh operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-tanh -testWebNNOperation('tanh', buildOperationWithSingleInput);
\ No newline at end of file +runWebNNConformanceTests('tanh', buildOperationWithSingleInput); diff --git a/testing/web-platform/tests/webnn/conformance_tests/transpose.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/transpose.https.any.js index 746e53d512..83bd7a45c1 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/transpose.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/transpose.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API transpose operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-transpose -testWebNNOperation('transpose', buildOperationWithSingleInput);
\ No newline at end of file +runWebNNConformanceTests('transpose', buildOperationWithSingleInput); diff --git a/testing/web-platform/tests/webnn/conformance_tests/triangular.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/triangular.https.any.js index 503f310620..499f60ed36 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/triangular.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/triangular.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API triangular operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-triangular -testWebNNOperation('triangular', buildOperationWithSingleInput);
\ No newline at end of file +runWebNNConformanceTests('triangular', buildOperationWithSingleInput); diff --git a/testing/web-platform/tests/webnn/conformance_tests/where.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/where.https.any.js index 7926221d3a..4ab453ab24 100644 --- a/testing/web-platform/tests/webnn/conformance_tests/where.https.any.js +++ b/testing/web-platform/tests/webnn/conformance_tests/where.https.any.js @@ -1,5 +1,7 @@ // META: title=test WebNN API where operation // META: global=window,dedicatedworker +// META: variant=?cpu +// META: variant=?gpu // META: script=../resources/utils.js // META: timeout=long @@ -7,4 +9,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-where -testWebNNOperation('where', buildWhere);
\ No newline at end of file +runWebNNConformanceTests('where', buildWhere); diff --git a/testing/web-platform/tests/webnn/resources/test_data/arg_max.json b/testing/web-platform/tests/webnn/resources/test_data/arg_max.json index d2fe9e62ca..348a54dc24 100644 --- a/testing/web-platform/tests/webnn/resources/test_data/arg_max.json +++ b/testing/web-platform/tests/webnn/resources/test_data/arg_max.json @@ -460,7 +460,7 @@ } }, "options": { - "keepDimensions": true + "keepDimensions": false }, "expected": { "name": "output", diff --git a/testing/web-platform/tests/webnn/resources/test_data/arg_min.json b/testing/web-platform/tests/webnn/resources/test_data/arg_min.json index 132a2dc3e8..330afbc710 100644 --- a/testing/web-platform/tests/webnn/resources/test_data/arg_min.json +++ b/testing/web-platform/tests/webnn/resources/test_data/arg_min.json @@ -460,7 +460,7 @@ } }, "options": { - "keepDimensions": true + "keepDimensions": false }, "expected": { "name": "output", diff --git a/testing/web-platform/tests/webnn/resources/test_data/matmul.json b/testing/web-platform/tests/webnn/resources/test_data/matmul.json index f3a03e442e..cc1789ee25 100644 --- a/testing/web-platform/tests/webnn/resources/test_data/matmul.json +++ b/testing/web-platform/tests/webnn/resources/test_data/matmul.json @@ -1,332 +1,6 @@ { "tests": [ { - "name": "matmul float32 constant 1D and 1D tensors all positive produces a scalar", - "inputs": { - "a": { - "shape": [4], - "data": [ - 50.10142534731317, - 22.2193058046253, - 34.65448469299386, - 36.35148095671881 - ], - "type": "float32", - "constant": true - }, - "b": { - "shape": [4], - "data": [ - 27.829805134194842, - 83.14548502311283, - 34.4128942110155, - 83.20379675185079 - ], - "type": "float32", - "constant": true - } - }, - "expected": { - "name": "output", - "data": 7458.89013671875, - "type": "float32" - } - }, - { - "name": "matmul float32 1D and 1D tensors all positive produces a scalar", - "inputs": { - "a": { - "shape": [4], - "data": [ - 50.10142534731317, - 22.2193058046253, - 34.65448469299386, - 36.35148095671881 - ], - "type": "float32" - }, - "b": { - "shape": [4], - "data": [ - 27.829805134194842, - 83.14548502311283, - 34.4128942110155, - 83.20379675185079 - ], - "type": "float32" - } - }, - "expected": { - "name": "output", - "data": 7458.89013671875, - "type": "float32" - } - }, - { - "name": "matmul float32 1D and 1D tensors all negative produces a scalar", - "inputs": { - "a": { - "shape": [4], - "data": [ - -86.60583871803968, - -94.74202421330796, - -86.16720380573273, - -76.0215630990851 - ], - "type": "float32" - }, - "b": { - "shape": [4], - "data": [ - -21.22328469397374, - -56.66441199254357, - -77.66753889428908, - -56.55797454862353 - ], - "type": "float32" - } - }, - "expected": { - "name": "output", - "data": 18198.58203125, - "type": "float32" - } - }, - { - "name": "matmul float32 positive 1D and negative 1D tensors produces a scalar", - "inputs": { - "a": { - "shape": [4], - "data": [ - 50.10142534731317, - 22.2193058046253, - 34.65448469299386, - 36.35148095671881 - ], - "type": "float32" - }, - "b": { - "shape": [4], - "data": [ - -21.22328469397374, - -56.66441199254357, - -77.66753889428908, - -56.55797454862353 - ], - "type": "float32" - } - }, - "expected": { - "name": "output", - "data": -7069.85546875, - "type": "float32" - } - }, - { - "name": "matmul float32 negative 1D and positive 1D tensors produces a scalar", - "inputs": { - "a": { - "shape": [4], - "data": [ - -86.60583871803968, - -94.74202421330796, - -86.16720380573273, - -76.0215630990851 - ], - "type": "float32" - }, - "b": { - "shape": [4], - "data": [ - 27.829805134194842, - 83.14548502311283, - 34.4128942110155, - 83.20379675185079 - ], - "type": "float32" - } - }, - "expected": { - "name": "output", - "data": -19578.140625, - "type": "float32" - } - }, - { - "name": "matmul float32 1D and 2D tensors", - "inputs": { - "a": { - "shape": [4], - "data": [ - 50.10142534731317, - 22.2193058046253, - 34.65448469299386, - 36.35148095671881 - ], - "type": "float32" - }, - "b": { - "shape": [4, 5], - "data": [ - 88.17004408170853, - 78.40126706348094, - 14.819002753540623, - 3.692303791736573, - 45.9064286713635, - 43.08391896733015, - 47.19946845924572, - 60.925216107016425, - 8.162760351602216, - 20.33326305093228, - 20.438397895943282, - 27.01940859922867, - 15.601424432184263, - 87.46969388883927, - 65.79554455585657, - 69.31696864490797, - 31.984439910782992, - 12.291812891860388, - 13.304834654547172, - 85.26705387930089 - ], - "type": "float32" - } - }, - "expected": { - "name": "output", - "shape": [1, 5], - "data": [ - 8602.796875, - 7075.7802734375, - 3083.654052734375, - 3881.228271484375, - 8131.462890625 - ], - "type": "float32" - } - }, - { - "name": "matmul float32 1D and 4D tensors", - "inputs": { - "a": { - "shape": [4], - "data": [ - 50.10142534731317, - 22.2193058046253, - 34.65448469299386, - 36.35148095671881 - ], - "type": "float32" - }, - "b": { - "shape": [2, 2, 4, 2], - "data": [ - 71.54684436671175, - 78.61926127874348, - 2.246814764541316, - 12.044773359659434, - 1.8342867333124069, - 82.09732511549477, - 43.884761946067094, - 5.616231825100204, - 34.67424097413332, - 49.152710076333506, - 75.34904358690912, - 84.74523302920429, - 36.56497325521975, - 22.89479672718755, - 15.02636975800511, - 66.49530785246675, - 65.81345056776044, - 26.749681209347376, - 19.415639234175774, - 98.60692665127114, - 65.39448996549784, - 56.47023672202065, - 80.64523905250766, - 82.20401464839868, - 70.84606482516416, - 50.27994995977012, - 67.39406108056262, - 75.35806805146241, - 2.7487208784167327, - 68.0645872775828, - 70.73791158057968, - 46.26436742398676 - ], - "type": "float32" - } - }, - "expected": { - "name": "output", - "shape": [2, 2, 1, 2], - "data": [ - 5293.36376953125, - 7255.7626953125, - 5224.80322265625, - 7556.21142578125, - 8926.5361328125, - 8476.359375, - 7713.62158203125, - 8234.0224609375 - ], - "type": "float32" - } - }, - { - "name": "matmul float32 2D and 1D tensors", - "inputs": { - "a": { - "shape": [5, 4], - "data": [ - 88.17004408170853, - 43.08391896733015, - 20.438397895943282, - 69.31696864490797, - 78.40126706348094, - 47.19946845924572, - 27.01940859922867, - 31.984439910782992, - 14.819002753540623, - 60.925216107016425, - 15.601424432184263, - 12.291812891860388, - 3.692303791736573, - 8.162760351602216, - 87.46969388883927, - 13.304834654547172, - 45.9064286713635, - 20.33326305093228, - 65.79554455585657, - 85.26705387930089 - ], - "type": "float32" - }, - "b": { - "shape": [4], - "data": [ - 50.10142534731317, - 22.2193058046253, - 34.65448469299386, - 36.35148095671881 - ], - "type": "float32" - } - }, - "expected": { - "name": "output", - "shape": [5, 1], - "data": [ - 8602.796875, - 7075.7802734375, - 3083.654052734375, - 3881.228271484375, - 8131.462890625 - ], - "type": "float32" - } - }, - { "name": "matmul float32 2D and 2D tensors", "inputs": { "a": { @@ -750,64 +424,6 @@ } }, { - "name": "matmul float32 3D and 1D tensors", - "inputs": { - "a": { - "shape": [2, 3, 4], - "data": [ - 56.46701250066562, - 99.86045478237251, - 71.05493372292567, - 32.45438455331333, - 17.310747999630017, - 2.586275053048559, - 92.31499166302054, - 96.9758519231732, - 26.4721315276526, - 77.67031776320978, - 29.278788710989147, - 82.12142428847062, - 89.89308471484885, - 82.49795321217854, - 64.36866008901963, - 23.75928513568486, - 6.67026681065197, - 81.55583129445503, - 16.142963270263433, - 57.45134849716054, - 26.82641739603182, - 85.0296980735713, - 36.198863464757956, - 89.60960360138286 - ], - "type": "float32" - }, - "b": { - "shape": [4], - "data": [ - 27.829805134194842, - 83.14548502311283, - 34.4128942110155, - 83.20379675185079 - ], - "type": "float32" - } - }, - "expected": { - "name": "output", - "shape": [2, 3, 1], - "data": [ - 15019.9462890625, - 11942.376953125, - 15035.0322265625, - 13553.013671875, - 12302.328125, - 16517.9765625 - ], - "type": "float32" - } - }, - { "name": "matmul float32 4D and 4D (broadcast) tensors", "inputs": { "a": { diff --git a/testing/web-platform/tests/webnn/resources/test_data/prelu.json b/testing/web-platform/tests/webnn/resources/test_data/prelu.json index cf79bee7a9..14a7c412dd 100644 --- a/testing/web-platform/tests/webnn/resources/test_data/prelu.json +++ b/testing/web-platform/tests/webnn/resources/test_data/prelu.json @@ -1,6 +1,34 @@ { "tests": [ { + "name": "prelu float32 0D scalar", + "inputs": { + "x": { + "shape": [], + "data": [ + -4.794857500523286 + ], + "type": "float32" + }, + "slope": { + "shape": [], + "data": [ + 1.1202747481570352 + ], + "type": "float32", + "constant": true + } + }, + "expected": { + "name": "output", + "shape": [], + "data": [ + -5.371557712554932 + ], + "type": "float32" + } + }, + { "name": "prelu float32 1D constant tensors", "inputs": { "x": { diff --git a/testing/web-platform/tests/webnn/resources/test_data/reduce_l1.json b/testing/web-platform/tests/webnn/resources/test_data/reduce_l1.json index 7cbc442511..c3f2b618e9 100644 --- a/testing/web-platform/tests/webnn/resources/test_data/reduce_l1.json +++ b/testing/web-platform/tests/webnn/resources/test_data/reduce_l1.json @@ -676,7 +676,8 @@ } }, "options": { - "axes": [1, 3] + "axes": [1, 3], + "keepDimensions": false }, "expected": { "name": "output", @@ -725,11 +726,12 @@ } }, "options": { - "axes": [1, 3] + "axes": [1, 3], + "keepDimensions": true }, "expected": { "name": "output", - "shape": [1, 2, 2, 1], + "shape": [2, 1, 2, 1], "data": [ 108.43173217773438, 315.6007995605469, diff --git a/testing/web-platform/tests/webnn/resources/test_data/reduce_l2.json b/testing/web-platform/tests/webnn/resources/test_data/reduce_l2.json index 7e59a45d5e..d83eea9dfb 100644 --- a/testing/web-platform/tests/webnn/resources/test_data/reduce_l2.json +++ b/testing/web-platform/tests/webnn/resources/test_data/reduce_l2.json @@ -676,7 +676,8 @@ } }, "options": { - "axes": [1, 3] + "axes": [1, 3], + "keepDimensions": false }, "expected": { "name": "output", @@ -725,11 +726,12 @@ } }, "options": { - "axes": [1, 3] + "axes": [1, 3], + "keepDimensions": true }, "expected": { "name": "output", - "shape": [1, 2, 2, 1], + "shape": [2, 1, 2, 1], "data": [ 138.580078125, 166.67791748046875, diff --git a/testing/web-platform/tests/webnn/resources/test_data/reduce_log_sum.json b/testing/web-platform/tests/webnn/resources/test_data/reduce_log_sum.json index 250398d227..061e12ad51 100644 --- a/testing/web-platform/tests/webnn/resources/test_data/reduce_log_sum.json +++ b/testing/web-platform/tests/webnn/resources/test_data/reduce_log_sum.json @@ -596,7 +596,8 @@ } }, "options": { - "axes": [1, 3] + "axes": [1, 3], + "keepDimensions": false }, "expected": { "name": "output", @@ -645,11 +646,12 @@ } }, "options": { - "axes": [1, 3] + "axes": [1, 3], + "keepDimensions": true }, "expected": { "name": "output", - "shape": [1, 2, 2, 1], + "shape": [2, 1, 2, 1], "data": [ 5.7273993492126465, 5.64375114440918, diff --git a/testing/web-platform/tests/webnn/resources/test_data/reduce_log_sum_exp.json b/testing/web-platform/tests/webnn/resources/test_data/reduce_log_sum_exp.json index b7f39abd52..3577d6aa9e 100644 --- a/testing/web-platform/tests/webnn/resources/test_data/reduce_log_sum_exp.json +++ b/testing/web-platform/tests/webnn/resources/test_data/reduce_log_sum_exp.json @@ -676,7 +676,8 @@ } }, "options": { - "axes": [1, 3] + "axes": [1, 3], + "keepDimensions": false }, "expected": { "name": "output", @@ -725,11 +726,12 @@ } }, "options": { - "axes": [1, 3] + "axes": [1, 3], + "keepDimensions": true }, "expected": { "name": "output", - "shape": [1, 2, 2, 1], + "shape": [2, 1, 2, 1], "data": [ 8.563796997070312, 5.500619411468506, diff --git a/testing/web-platform/tests/webnn/resources/test_data/reduce_max.json b/testing/web-platform/tests/webnn/resources/test_data/reduce_max.json index 967aea8bf4..11ed0ed919 100644 --- a/testing/web-platform/tests/webnn/resources/test_data/reduce_max.json +++ b/testing/web-platform/tests/webnn/resources/test_data/reduce_max.json @@ -556,7 +556,8 @@ } }, "options": { - "axes": [1, 3] + "axes": [1, 3], + "keepDimensions": false }, "expected": { "name": "output", @@ -605,11 +606,12 @@ } }, "options": { - "axes": [1, 3] + "axes": [1, 3], + "keepDimensions": true }, "expected": { "name": "output", - "shape": [1, 2, 2, 1], + "shape": [2, 1, 2, 1], "data": [ 90.42288208007812, 94.99645233154297, diff --git a/testing/web-platform/tests/webnn/resources/test_data/reduce_mean.json b/testing/web-platform/tests/webnn/resources/test_data/reduce_mean.json index 5a48952c06..8c26d0a562 100644 --- a/testing/web-platform/tests/webnn/resources/test_data/reduce_mean.json +++ b/testing/web-platform/tests/webnn/resources/test_data/reduce_mean.json @@ -670,7 +670,8 @@ } }, "options": { - "axes": [1, 3] + "axes": [1, 3], + "keepDimensions": false }, "expected": { "shape": [2, 2], @@ -718,10 +719,11 @@ } }, "options": { - "axes": [1, 3] + "axes": [1, 3], + "keepDimensions": true }, "expected": { - "shape": [1, 2, 2, 1], + "shape": [2, 1, 2, 1], "data": [ 52.287559509277344, 45.10261917114258, diff --git a/testing/web-platform/tests/webnn/resources/test_data/reduce_min.json b/testing/web-platform/tests/webnn/resources/test_data/reduce_min.json index 92de75e92a..6c26df5db1 100644 --- a/testing/web-platform/tests/webnn/resources/test_data/reduce_min.json +++ b/testing/web-platform/tests/webnn/resources/test_data/reduce_min.json @@ -556,7 +556,8 @@ } }, "options": { - "axes": [1, 3] + "axes": [1, 3], + "keepDimensions": false }, "expected": { "name": "output", @@ -605,11 +606,12 @@ } }, "options": { - "axes": [1, 3] + "axes": [1, 3], + "keepDimensions": true }, "expected": { "name": "output", - "shape": [1, 2, 2, 1], + "shape": [2, 1, 2, 1], "data": [ -87.9623031616211, -53.747413635253906, diff --git a/testing/web-platform/tests/webnn/resources/test_data/reduce_product.json b/testing/web-platform/tests/webnn/resources/test_data/reduce_product.json index 691bf4da9b..d58af30ec1 100644 --- a/testing/web-platform/tests/webnn/resources/test_data/reduce_product.json +++ b/testing/web-platform/tests/webnn/resources/test_data/reduce_product.json @@ -556,7 +556,8 @@ } }, "options": { - "axes": [1, 3] + "axes": [1, 3], + "keepDimensions": false }, "expected": { "name": "output", @@ -605,11 +606,12 @@ } }, "options": { - "axes": [1, 3] + "axes": [1, 3], + "keepDimensions": true }, "expected": { "name": "output", - "shape": [1, 2, 2, 1], + "shape": [2, 1, 2, 1], "data": [ -3638925568, 6523364352, diff --git a/testing/web-platform/tests/webnn/resources/test_data/reduce_sum.json b/testing/web-platform/tests/webnn/resources/test_data/reduce_sum.json index df47a1a2b2..7027d38b67 100644 --- a/testing/web-platform/tests/webnn/resources/test_data/reduce_sum.json +++ b/testing/web-platform/tests/webnn/resources/test_data/reduce_sum.json @@ -670,7 +670,8 @@ } }, "options": { - "axes": [1, 3] + "axes": [1, 3], + "keepDimensions": false }, "expected": { "shape": [2, 2], @@ -718,10 +719,11 @@ } }, "options": { - "axes": [1, 3] + "axes": [1, 3], + "keepDimensions": true }, "expected": { - "shape": [1, 2, 2, 1], + "shape": [2, 1, 2, 1], "data": [ 355.21942138671875, 185.98255920410156, diff --git a/testing/web-platform/tests/webnn/resources/test_data/reduce_sum_square.json b/testing/web-platform/tests/webnn/resources/test_data/reduce_sum_square.json index 8ac373e4b3..bd2ebb341a 100644 --- a/testing/web-platform/tests/webnn/resources/test_data/reduce_sum_square.json +++ b/testing/web-platform/tests/webnn/resources/test_data/reduce_sum_square.json @@ -676,7 +676,8 @@ } }, "options": { - "axes": [1, 3] + "axes": [1, 3], + "keepDimensions": false }, "expected": { "name": "output", @@ -725,11 +726,12 @@ } }, "options": { - "axes": [1, 3] + "axes": [1, 3], + "keepDimensions": true }, "expected": { "name": "output", - "shape": [1, 2, 2, 1], + "shape": [2, 1, 2, 1], "data": [ 12302.474609375, 22772.77734375, diff --git a/testing/web-platform/tests/webnn/resources/test_data/softplus.json b/testing/web-platform/tests/webnn/resources/test_data/softplus.json index eb05b7b281..373612d5ca 100644 --- a/testing/web-platform/tests/webnn/resources/test_data/softplus.json +++ b/testing/web-platform/tests/webnn/resources/test_data/softplus.json @@ -1,7 +1,7 @@ -{ // softplus: The calculation follows the expression ln(1 + exp(steepness * x)) / steepness. +{ // softplus: The calculation follows the expression ln(1 + exp(x)). "tests": [ { - "name": "softplus float32 1D constant tensor default options", // default options: {steepness: 1} + "name": "softplus float32 1D constant tensor", "inputs": { "x": { "shape": [24], @@ -68,7 +68,7 @@ } }, { - "name": "softplus float32 1D tensor default options", // default options: {steepness: 1} + "name": "softplus float32 1D tensor", "inputs": { "x": { "shape": [24], @@ -134,7 +134,7 @@ } }, { - "name": "softplus float32 2D tensor default options", + "name": "softplus float32 2D tensor", "inputs": { "x": { "shape": [4, 6], @@ -200,7 +200,7 @@ } }, { - "name": "softplus float32 3D tensor default options", + "name": "softplus float32 3D tensor", "inputs": { "x": { "shape": [2, 3, 4], @@ -266,7 +266,7 @@ } }, { - "name": "softplus float32 4D tensor default options", + "name": "softplus float32 4D tensor", "inputs": { "x": { "shape": [1, 2, 3, 4], @@ -332,7 +332,7 @@ } }, { - "name": "softplus float32 5D tensor default options", + "name": "softplus float32 5D tensor", "inputs": { "x": { "shape": [1, 2, 1, 3, 4], @@ -396,144 +396,6 @@ ], "type": "float32" } - }, - { - "name": "softplus both positive float32 4D tensor and options.steepness", - "inputs": { - "x": { - "shape": [1, 2, 3, 4], - "data": [ - 5.626614582460632, - 5.167487045486892, - 4.0146356193402655, - 9.48003299650489, - 9.989938045769978, - 7.0654412821434125, - 2.132681001794825, - 8.187151346059956, - 5.169976220175496, - 2.1044997879382077, - 3.523329401138895, - 4.136340646976668, - 1.7418719794295656, - 5.145224066290767, - 5.015515309165462, - 0.045903935074711466, - 2.9570898924917377, - 3.959244712098706, - 5.517926978255181, - 7.192322388417094, - 8.76492480390928, - 1.3734704039113388, - 8.930669016709397, - 8.660283210871246 - ], - "type": "float32" - } - }, - "options": { - "steepness": 1.5104469060897827 - }, - "expected": { - "name": "output", - "shape": [1, 2, 3, 4], - "data": [ - 5.626749515533447, - 5.167757034301758, - 4.016173362731934, - 9.480032920837402, - 9.989937782287598, - 7.065456390380859, - 2.158585548400879, - 8.187153816223145, - 5.170245170593262, - 2.1315081119537354, - 3.526555061340332, - 4.137620449066162, - 1.7879058122634888, - 5.145503044128418, - 5.015854835510254, - 0.4822517931461334, - 2.964651584625244, - 3.960916519165039, - 5.518085956573486, - 7.19233512878418, - 8.764925956726074, - 1.4518096446990967, - 8.930669784545898, - 8.660284042358398 - ], - "type": "float32" - } - }, - { - "name": "softplus both negative float32 4D tensor and options.steepness", - "inputs": { - "x": { - "shape": [1, 2, 3, 4], - "data": [ - -5.584833476104802, - -8.188738740810354, - -8.981280004134987, - -1.7315531899284586, - -0.7266543578958906, - -0.0034800119290885334, - -7.378389455552106, - -8.907525953796949, - -6.0483786568116304, - -6.328561142365743, - -2.6006513567654626, - -5.02005264196455, - -2.0647716093484414, - -1.5499896740695434, - -2.221591675966657, - -1.1088025713211636, - -2.7854626064634385, - -2.105037489961294, - -5.144277741727352, - -5.081219916574497, - -7.499426297617635, - -2.4305558382286545, - -8.390520024268328, - -0.07117499202643174 - ], - "type": "float32" - } - }, - "options": { - "steepness": -1.2985155767552126 - }, - "expected": { - "name": "output", - "shape": [1, 2, 3, 4], - "data": [ - -5.585379123687744, - -8.188756942749023, - -8.981287002563477, - -1.8088372945785522, - -0.9798305630683899, - -0.5355416536331177, - -7.378442287445068, - -8.907533645629883, - -6.048677444458008, - -6.328769207000732, - -2.626511573791504, - -5.021188259124756, - -2.1157851219177246, - -1.6465802192687988, - -2.2634570598602295, - -1.2725814580917358, - -2.805877923965454, - -2.1535322666168213, - -5.145244121551514, - -5.082269191741943, - -7.499471664428711, - -2.4626762866973877, - -8.390534400939941, - -0.5702091455459595 - ], - "type": "float32" - } } ] }
\ No newline at end of file diff --git a/testing/web-platform/tests/webnn/resources/utils.js b/testing/web-platform/tests/webnn/resources/utils.js index d1dc0675a7..e5b80ae9f7 100644 --- a/testing/web-platform/tests/webnn/resources/utils.js +++ b/testing/web-platform/tests/webnn/resources/utils.js @@ -13,6 +13,15 @@ const TypedArrayDict = { int64: BigInt64Array, }; +const kContextOptionsForVariant = { + cpu: { + deviceType: 'cpu', + }, + gpu: { + deviceType: 'gpu', + } +}; + // The maximum index to validate for the output's expected value. const kMaximumIndexToValidate = 1000; @@ -867,17 +876,15 @@ const run = async (operationName, context, builder, resources, buildFunc) => { checkResults(operationName, namedOutputOperands, result.outputs, resources); }; +const variant = location.search.substring(1); +const contextOptions = kContextOptionsForVariant[variant]; + /** * Run WebNN operation tests. * @param {(String[]|String)} operationName - An operation name array or an operation name * @param {Function} buildFunc - A build function for an operation - * @param {String} deviceType - The execution device type for this test */ -const testWebNNOperation = (operationName, buildFunc, deviceType = 'cpu') => { - test(() => assert_not_equals(navigator.ml, undefined, "ml property is defined on navigator")); - if (navigator.ml === undefined) { - return; - } +const testWebNNOperation = (operationName, buildFunc) => { let operationNameArray; if (typeof operationName === 'string') { operationNameArray = [operationName]; @@ -890,7 +897,14 @@ const testWebNNOperation = (operationName, buildFunc, deviceType = 'cpu') => { operationNameArray.forEach((subOperationName) => { const tests = loadTests(subOperationName); promise_setup(async () => { - context = await navigator.ml.createContext({deviceType}); + let supported = false; + try { + context = await navigator.ml.createContext(contextOptions); + supported = true; + } catch (e) { + } + assert_implements( + supported, `Unable to create context for ${variant} variant`); builder = new MLGraphBuilder(context); }); for (const subTest of tests) { @@ -901,6 +915,65 @@ const testWebNNOperation = (operationName, buildFunc, deviceType = 'cpu') => { }); }; +/** + * WebNN parallel compute operation test. + */ +const testParallelCompute = () => { + let ml_context; + let ml_graph; + + promise_setup(async () => { + let supported = false; + try { + ml_context = await navigator.ml.createContext(contextOptions); + supported = true; + } catch (e) { + } + assert_implements( + supported, `Unable to create context for ${variant} variant`); + // Construct a simple graph: A = B * 2. + const builder = new MLGraphBuilder(ml_context); + const operandType = {dataType: 'float32', dimensions: [1]}; + const input_operand = builder.input('input', operandType); + const const_operand = builder.constant(operandType, Float32Array.from([2])); + const output_operand = builder.mul(input_operand, const_operand); + ml_graph = await builder.build({'output': output_operand}); + }); + + promise_test(async () => { + const test_inputs = [1, 2, 3, 4]; + + const actual_outputs = await Promise.all(test_inputs.map(async (input) => { + let inputs = {'input': Float32Array.from([input])}; + let outputs = {'output': new Float32Array(1)}; + ({inputs, outputs} = await ml_context.compute(ml_graph, inputs, outputs)); + return outputs.output[0]; + })); + + const expected_outputs = [2, 4, 6, 8]; + assert_array_equals(actual_outputs, expected_outputs); + }); +}; + +/** + * Run WebNN conformance tests by specified operation. + * @param {(String[]|String)} operationName - An operation name array or an + * operation name + * @param {Function} buildFunc - A build function for an operation + */ +const runWebNNConformanceTests = (operationName, buildFunc) => { + // Link to https://github.com/web-platform-tests/wpt/pull/44883 + // Check navigator.ml is defined before trying to run WebNN tests + if (navigator.ml) { + testWebNNOperation(operationName, buildFunc); + } else { + // Show indication to users why the test failed + test( + () => assert_not_equals( + navigator.ml, undefined, 'ml property is defined on navigator')); + } +}; + // ref: http://stackoverflow.com/questions/32633585/how-do-you-convert-to-half-floats-in-javascript const toHalf = (value) => { let floatView = new Float32Array(1); @@ -970,13 +1043,19 @@ const createBuffer = (context, bufferSize) => { /** * WebNN destroy buffer twice test. * @param {String} testName - The name of the test operation. - * @param {String} deviceType - The execution device type for this test. */ -const testDestroyWebNNBuffer = (testName, deviceType = 'cpu') => { +const testDestroyWebNNBuffer = (testName) => { let context; let buffer; promise_setup(async () => { - context = await navigator.ml.createContext({deviceType}); + let supported = false; + try { + context = await navigator.ml.createContext(contextOptions); + supported = true; + } catch (e) { + } + assert_implements( + supported, `Unable to create context for ${variant} variant`); buffer = createBuffer(context, 4); }); promise_test(async () => { @@ -993,12 +1072,19 @@ const testDestroyWebNNBuffer = (testName, deviceType = 'cpu') => { * WebNN create buffer test. * @param {String} testName - The name of the test operation. * @param {Number} bufferSize - Size of the buffer to create, in bytes. - * @param {String} deviceType - The execution device type for this test. */ -const testCreateWebNNBuffer = (testName, bufferSize, deviceType = 'cpu') => { +const testCreateWebNNBuffer = (testName, bufferSize) => { let context; + promise_setup(async () => { - context = await navigator.ml.createContext({deviceType}); + let supported = false; + try { + context = await navigator.ml.createContext(contextOptions); + supported = true; + } catch (e) { + } + assert_implements( + supported, `Unable to create context for ${variant} variant`); }); promise_test(async () => { createBuffer(context, bufferSize); @@ -1021,12 +1107,18 @@ const assert_buffer_data_equals = async (ml_context, ml_buffer, expected) => { /** * WebNN write buffer operation test. * @param {String} testName - The name of the test operation. - * @param {String} deviceType - The execution device type for this test. */ -const testWriteWebNNBuffer = (testName, deviceType = 'cpu') => { +const testWriteWebNNBuffer = (testName) => { let ml_context; promise_setup(async () => { - ml_context = await navigator.ml.createContext({deviceType}); + let supported = false; + try { + ml_context = await navigator.ml.createContext(contextOptions); + supported = true; + } catch (e) { + } + assert_implements( + supported, `Unable to create context for ${variant} variant`); }); promise_test(async () => { @@ -1117,7 +1209,7 @@ const testWriteWebNNBuffer = (testName, deviceType = 'cpu') => { return; } - let another_ml_context = await navigator.ml.createContext({deviceType}); + let another_ml_context = await navigator.ml.createContext(contextOptions); let another_ml_buffer = createBuffer(another_ml_context, ml_buffer.size); let input_data = new Uint8Array(ml_buffer.size).fill(0xAA); @@ -1131,12 +1223,18 @@ const testWriteWebNNBuffer = (testName, deviceType = 'cpu') => { /** * WebNN read buffer operation test. * @param {String} testName - The name of the test operation. - * @param {String} deviceType - The execution device type for this test. */ -const testReadWebNNBuffer = (testName, deviceType = 'cpu') => { +const testReadWebNNBuffer = (testName) => { let ml_context; promise_setup(async () => { - ml_context = await navigator.ml.createContext({deviceType}); + let supported = false; + try { + ml_context = await navigator.ml.createContext(contextOptions); + supported = true; + } catch (e) { + } + assert_implements( + supported, `Unable to create context for ${variant} variant`); }); promise_test(async t => { @@ -1277,7 +1375,7 @@ const testReadWebNNBuffer = (testName, deviceType = 'cpu') => { return; } - let another_ml_context = await navigator.ml.createContext({deviceType}); + let another_ml_context = await navigator.ml.createContext(contextOptions); let another_ml_buffer = createBuffer(another_ml_context, ml_buffer.size); await promise_rejects_js( diff --git a/testing/web-platform/tests/webnn/validation_tests/clamp.https.any.js b/testing/web-platform/tests/webnn/validation_tests/clamp.https.any.js index 85cd19a566..126fa90e16 100644 --- a/testing/web-platform/tests/webnn/validation_tests/clamp.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/clamp.https.any.js @@ -5,3 +5,56 @@ 'use strict'; validateInputFromAnotherBuilder('clamp'); + +validateUnaryOperation( + 'clamp', allWebNNOperandDataTypes, /*alsoBuildActivation=*/ true); + +promise_test(async t => { + const options = {minValue: 1.0, maxValue: 3.0}; + const input = + builder.input('input', {dataType: 'uint32', dimensions: [1, 2, 3]}); + const output = builder.clamp(input, options); + assert_equals(output.dataType(), 'uint32'); + assert_array_equals(output.shape(), [1, 2, 3]); +}, '[clamp] Test building an operator with options'); + +promise_test(async t => { + const options = {minValue: 0, maxValue: 0}; + const input = + builder.input('input', {dataType: 'int32', dimensions: [1, 2, 3, 4]}); + const output = builder.clamp(input, options); + assert_equals(output.dataType(), 'int32'); + assert_array_equals(output.shape(), [1, 2, 3, 4]); +}, '[clamp] Test building an operator with options.minValue == options.maxValue'); + +promise_test(async t => { + const options = {minValue: 2.0}; + builder.clamp(options); +}, '[clamp] Test building an activation with options'); + +promise_test(async t => { + const options = {minValue: 3.0, maxValue: 1.0}; + const input = + builder.input('input', {dataType: 'uint8', dimensions: [1, 2, 3]}); + assert_throws_js(TypeError, () => builder.clamp(input, options)); +}, '[clamp] Throw if options.minValue > options.maxValue when building an operator'); + +// To be removed once infinite `minValue` is allowed. Tracked in +// https://github.com/webmachinelearning/webnn/pull/647. +promise_test(async t => { + const options = {minValue: -Infinity}; + const input = builder.input('input', {dataType: 'float16', dimensions: []}); + assert_throws_js(TypeError, () => builder.clamp(input, options)); +}, '[clamp] Throw if options.minValue is -Infinity when building an operator'); + +promise_test(async t => { + const options = {minValue: 2.0, maxValue: -1.0}; + assert_throws_js(TypeError, () => builder.clamp(options)); +}, '[clamp] Throw if options.minValue > options.maxValue when building an activation'); + +// To be removed once NaN `maxValue` is allowed. Tracked in +// https://github.com/webmachinelearning/webnn/pull/647. +promise_test(async t => { + const options = {maxValue: NaN}; + assert_throws_js(TypeError, () => builder.clamp(options)); +}, '[clamp] Throw if options.maxValue is NaN when building an activation'); diff --git a/testing/web-platform/tests/webnn/validation_tests/conv2d.https.any.js b/testing/web-platform/tests/webnn/validation_tests/conv2d.https.any.js index ffc9c2c65d..7dac654951 100644 --- a/testing/web-platform/tests/webnn/validation_tests/conv2d.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/conv2d.https.any.js @@ -55,3 +55,478 @@ multi_builder_test(async (t, builder, otherBuilder) => { const filter = builder.input('filter', kExampleFilterDescriptor); assert_throws_js(TypeError, () => builder.conv2d(input, filter, options)); }, '[conv2d] throw if activation option is from another builder'); + +const tests = [ + { + name: '[conv2d] Test with default options.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + output: {dataType: 'float32', dimensions: [1, 1, 3, 3]} + }, + { + name: '[conv2d] Test with padding.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + options: { + padding: [1, 1, 1, 1], + }, + output: {dataType: 'float32', dimensions: [1, 1, 5, 5]} + }, + { + name: '[conv2d] Test with strides and padding.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + options: { + padding: [1, 1, 1, 1], + strides: [2, 2], + }, + output: {dataType: 'float32', dimensions: [1, 1, 3, 3]} + }, + { + name: '[conv2d] Test with strides and asymmetric padding.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 4, 2]}, + options: { + padding: [1, 2, 0, 1], + strides: [2, 2], + }, + output: {dataType: 'float32', dimensions: [1, 1, 3, 3]} + }, + { + name: '[conv2d] Test depthwise conv2d by setting groups to input channels.', + input: {dataType: 'float32', dimensions: [1, 4, 2, 2]}, + filter: {dataType: 'float32', dimensions: [4, 1, 2, 2]}, + options: { + groups: 4, + }, + output: {dataType: 'float32', dimensions: [1, 4, 1, 1]} + }, + { + name: + '[conv2d] Test depthwise conv2d with groups, inputLayout="nhwc" and filterLayout="ihwo".', + input: {dataType: 'float32', dimensions: [1, 2, 2, 4]}, + filter: {dataType: 'float32', dimensions: [1, 2, 2, 4]}, + options: { + groups: 4, + inputLayout: 'nhwc', + filterLayout: 'ihwo', + }, + output: {dataType: 'float32', dimensions: [1, 1, 1, 4]} + }, + { + name: + '[conv2d] Test with dilations, inputLayout="nhwc" and filterLayout="ihwo".', + input: {dataType: 'float32', dimensions: [1, 65, 65, 1]}, + filter: {dataType: 'float32', dimensions: [1, 3, 3, 1]}, + options: { + inputLayout: 'nhwc', + filterLayout: 'ihwo', + dilations: [4, 4], + }, + output: {dataType: 'float32', dimensions: [1, 57, 57, 1]} + }, + { + name: '[conv2d] Test with inputLayout="nchw" and filterLayout="oihw".', + input: {dataType: 'float32', dimensions: [1, 2, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 2, 3, 3]}, + options: { + inputLayout: 'nchw', + filterLayout: 'oihw', + }, + output: {dataType: 'float32', dimensions: [1, 1, 3, 3]} + }, + { + name: '[conv2d] Test with inputLayout="nchw" and filterLayout="hwio".', + input: {dataType: 'float32', dimensions: [1, 2, 5, 5]}, + filter: {dataType: 'float32', dimensions: [3, 3, 2, 1]}, + options: { + inputLayout: 'nchw', + filterLayout: 'hwio', + }, + output: {dataType: 'float32', dimensions: [1, 1, 3, 3]} + }, + { + name: '[conv2d] Test with inputLayout="nchw" and filterLayout="ohwi".', + input: {dataType: 'float32', dimensions: [1, 2, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 3, 3, 2]}, + options: { + inputLayout: 'nchw', + filterLayout: 'ohwi', + }, + output: {dataType: 'float32', dimensions: [1, 1, 3, 3]} + }, + { + name: '[conv2d] Test with inputLayout="nchw" and filterLayout="ihwo".', + input: {dataType: 'float32', dimensions: [1, 2, 5, 5]}, + filter: {dataType: 'float32', dimensions: [2, 3, 3, 1]}, + options: { + inputLayout: 'nchw', + filterLayout: 'ihwo', + }, + output: {dataType: 'float32', dimensions: [1, 1, 3, 3]} + }, + { + name: '[conv2d] Test with inputLayout="nhwc" and filterLayout="oihw".', + input: {dataType: 'float32', dimensions: [1, 5, 5, 2]}, + filter: {dataType: 'float32', dimensions: [1, 2, 3, 3]}, + options: { + inputLayout: 'nhwc', + filterLayout: 'oihw', + }, + output: {dataType: 'float32', dimensions: [1, 3, 3, 1]} + }, + { + name: '[conv2d] Test with inputLayout="nhwc" and filterLayout="hwio".', + input: {dataType: 'float32', dimensions: [1, 5, 5, 2]}, + filter: {dataType: 'float32', dimensions: [3, 3, 2, 1]}, + options: { + inputLayout: 'nhwc', + filterLayout: 'hwio', + }, + output: {dataType: 'float32', dimensions: [1, 3, 3, 1]} + }, + { + name: '[conv2d] Test with inputLayout="nhwc" and filterLayout="ohwi".', + input: {dataType: 'float32', dimensions: [1, 5, 5, 2]}, + filter: {dataType: 'float32', dimensions: [1, 3, 3, 2]}, + options: { + inputLayout: 'nhwc', + filterLayout: 'ohwi', + }, + output: {dataType: 'float32', dimensions: [1, 3, 3, 1]} + }, + { + name: '[conv2d] Test with inputLayout="nhwc" and filterLayout="ihwo".', + input: {dataType: 'float32', dimensions: [1, 5, 5, 2]}, + filter: {dataType: 'float32', dimensions: [2, 3, 3, 1]}, + options: { + inputLayout: 'nhwc', + filterLayout: 'ihwo', + }, + output: {dataType: 'float32', dimensions: [1, 3, 3, 1]} + }, + { + name: '[conv2d] Throw if the input is not a 4-D tensor.', + input: {dataType: 'float32', dimensions: [1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 2, 2, 1]}, + }, + { + name: '[conv2d] Throw if the input data type is not floating point.', + input: {dataType: 'int32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'int32', dimensions: [1, 1, 2, 2]}, + }, + { + name: '[conv2d] Throw if the filter is not a 4-D tensor.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [2, 2]}, + }, + { + name: + '[conv2d] Throw if the filter data type doesn\'t match the input data type.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'int32', dimensions: [1, 1, 2, 2]}, + }, + { + name: '[conv2d] Throw if the length of padding is not 4.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + padding: [2, 2], + }, + }, + { + name: '[conv2d] Throw if the length of strides is not 2.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + strides: [2], + }, + }, + { + name: '[conv2d] Throw if strideHeight is smaller than 1.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + strides: [0, 1], + }, + }, + { + name: '[conv2d] Throw if strideWidth is smaller than 1.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + strides: [1, 0], + }, + }, + { + name: '[conv2d] Throw if the length of dilations is not 2.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + dilations: [1], + }, + }, + { + name: '[conv2d] Throw if dilationHeight is smaller than 1.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + dilations: [0, 1], + }, + }, + { + name: '[conv2d] Throw if dilationWidth is smaller than 1.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + dilations: [1, 0], + }, + }, + { + name: '[conv2d] Throw if inputChannels % groups is not 0.', + input: {dataType: 'float32', dimensions: [1, 4, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + groups: 3, + }, + }, + { + name: + '[conv2d] Throw if inputChannels / groups is not equal to filterInputChannels.', + input: {dataType: 'float32', dimensions: [1, 4, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + groups: 2, + }, + }, + { + name: '[conv2d] Throw if the groups is smaller than 1.', + input: {dataType: 'float32', dimensions: [1, 4, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + groups: 0, + }, + }, + { + name: + '[conv2d] Throw due to overflow when calculating the effective filter height.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 434983, 2]}, + options: { + dilations: [328442, 1], + }, + }, + { + name: + '[conv2d] Throw due to overflow when calculating the effective filter width.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 234545]}, + options: { + dilations: [2, 843452], + }, + }, + { + name: '[conv2d] Throw due to overflow when dilation height is too large.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + options: { + dilations: [kMaxUnsignedLong, 1], + }, + }, + { + name: '[conv2d] Throw due to overflow when dilation width is too large.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + options: { + dilations: [1, kMaxUnsignedLong], + }, + }, + { + name: '[conv2d] Throw due to underflow when calculating the output height.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 4, 2]}, + options: { + dilations: [4, 1], + padding: [1, 1, 1, 1], + strides: [2, 2], + }, + }, + { + name: '[conv2d] Throw due to underflow when calculating the output width.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 8]}, + options: { + dilations: [1, 4], + padding: [1, 1, 1, 1], + strides: [2, 2], + }, + }, + { + name: '[conv2d] Throw if the bias is not a 1-D tensor.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + bias: {dataType: 'float32', dimensions: [1, 2]}, + }, + }, + { + name: + '[conv2d] Throw if the bias shape is not equal to [output_channels] with filterLayout="oihw".', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + bias: {dataType: 'float32', dimensions: [2]}, + }, + }, + { + name: + '[conv2d] Throw if the bias shape is not equal to [output_channels] with filterLayout="hwio".', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [2, 2, 1, 1]}, + options: { + bias: {dataType: 'float32', dimensions: [2]}, + }, + }, + { + name: + '[conv2d] Throw if the bias shape is not equal to [output_channels] with filterLayout="ohwi".', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 2, 2, 1]}, + options: { + bias: {dataType: 'float32', dimensions: [2]}, + }, + }, + { + name: + '[conv2d] Throw if the bias shape is not equal to [output_channels] with filterLayout="ihwo".', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 2, 2, 1]}, + options: { + bias: {dataType: 'float32', dimensions: [2]}, + }, + }, + { + name: + '[conv2d] Throw if the bias data type doesn\'t match input data type.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + bias: {dataType: 'int32', dimensions: [1]}, + }, + }, + { + name: + '[conv2d] Throw if inputChannels / groups is not equal to filterInputChannels with inputLayout="nchw" and filterLayout="oihw".', + input: {dataType: 'float32', dimensions: [1, 2, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 2, 3, 3]}, + options: { + inputLayout: 'nchw', + filterLayout: 'oihw', + groups: 2, + }, + }, + { + name: + '[conv2d] Throw if inputChannels / groups is not equal to filterInputChannels with inputLayout="nchw" and filterLayout="hwio".', + input: {dataType: 'float32', dimensions: [1, 2, 5, 5]}, + filter: {dataType: 'float32', dimensions: [3, 3, 2, 1]}, + options: { + inputLayout: 'nchw', + filterLayout: 'hwio', + groups: 2, + }, + }, + { + name: + '[conv2d] Throw if inputChannels / groups is not equal to filterInputChannels with inputLayout="nchw" and filterLayout="ohwi".', + input: {dataType: 'float32', dimensions: [1, 2, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 3, 3, 2]}, + options: { + inputLayout: 'nchw', + filterLayout: 'ohwi', + groups: 2, + }, + }, + { + name: + '[conv2d] Throw if inputChannels / groups is not equal to filterInputChannels with inputLayout="nchw" and filterLayout="ihwo".', + input: {dataType: 'float32', dimensions: [1, 2, 5, 5]}, + filter: {dataType: 'float32', dimensions: [2, 3, 3, 1]}, + options: { + inputLayout: 'nchw', + filterLayout: 'ihwo', + groups: 2, + }, + + }, + { + name: + '[conv2d] Throw if inputChannels / groups is not equal to filterInputChannels with inputLayout="nhwc" and filterLayout="oihw".', + input: {dataType: 'float32', dimensions: [1, 5, 5, 2]}, + filter: {dataType: 'float32', dimensions: [1, 2, 3, 3]}, + options: { + inputLayout: 'nhwc', + filterLayout: 'oihw', + groups: 2, + }, + }, + { + name: + '[conv2d] Throw if inputChannels / groups is not equal to filterInputChannels with inputLayout="nhwc" and filterLayout="hwio".', + input: {dataType: 'float32', dimensions: [1, 5, 5, 2]}, + filter: {dataType: 'float32', dimensions: [3, 3, 2, 1]}, + options: { + inputLayout: 'nhwc', + filterLayout: 'hwio', + groups: 2, + }, + }, + { + name: + '[conv2d] Throw if inputChannels / groups is not equal to filterInputChannels with inputLayout="nhwc" and filterLayout="ohwi".', + input: {dataType: 'float32', dimensions: [1, 5, 5, 2]}, + filter: {dataType: 'float32', dimensions: [1, 3, 3, 2]}, + options: { + inputLayout: 'nhwc', + filterLayout: 'ohwi', + groups: 2, + }, + }, + { + name: + '[conv2d] Throw if inputChannels / groups is not equal to filterInputChannels with inputLayout="nhwc" and filterLayout="ihwo".', + input: {dataType: 'float32', dimensions: [1, 5, 5, 2]}, + filter: {dataType: 'float32', dimensions: [2, 3, 3, 1]}, + options: { + inputLayout: 'nhwc', + filterLayout: 'ihwo', + groups: 2, + }, + }, +]; + +tests.forEach( + test => promise_test(async t => { + const input = builder.input( + 'input', + {dataType: test.input.dataType, dimensions: test.input.dimensions}); + const filter = builder.input( + 'filter', + {dataType: test.filter.dataType, dimensions: test.filter.dimensions}); + + if (test.options && test.options.bias) { + test.options.bias = builder.input('bias', { + dataType: test.options.bias.dataType, + dimensions: test.options.bias.dimensions + }); + } + + if (test.output) { + const output = builder.conv2d(input, filter, test.options); + assert_equals(output.dataType(), test.output.dataType); + assert_array_equals(output.shape(), test.output.dimensions); + } else { + assert_throws_js( + TypeError, () => builder.conv2d(input, filter, test.options)); + } + }, test.name)); diff --git a/testing/web-platform/tests/webnn/validation_tests/convTranspose2d.https.any.js b/testing/web-platform/tests/webnn/validation_tests/convTranspose2d.https.any.js index c14f445bf3..02822c5274 100644 --- a/testing/web-platform/tests/webnn/validation_tests/convTranspose2d.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/convTranspose2d.https.any.js @@ -57,3 +57,473 @@ multi_builder_test(async (t, builder, otherBuilder) => { assert_throws_js( TypeError, () => builder.convTranspose2d(input, filter, options)); }, '[convTranspose2d] throw if activation option is from another builder'); + +const tests = [ + { + name: '[convTranspose2d] Test with default options.', + input: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + filter: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + output: {dataType: 'float32', dimensions: [1, 1, 5, 5]} + }, + { + name: + '[convTranspose2d] Test with inputLayout="nchw" and filterLayout="hwoi".', + input: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + filter: {dataType: 'float32', dimensions: [3, 3, 2, 1]}, + options: { + filterLayout: 'hwoi', + inputLayout: 'nchw', + }, + output: {dataType: 'float32', dimensions: [1, 2, 5, 5]} + }, + { + name: + '[convTranspose2d] Test with inputLayout="nchw" and filterLayout="ohwi".', + input: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + filter: {dataType: 'float32', dimensions: [2, 3, 3, 1]}, + options: { + filterLayout: 'ohwi', + inputLayout: 'nchw', + }, + output: {dataType: 'float32', dimensions: [1, 2, 5, 5]} + }, + { + name: + '[convTranspose2d] Test with inputLayout="nhwc" and filterLayout="iohw".', + input: {dataType: 'float32', dimensions: [1, 3, 3, 1]}, + filter: {dataType: 'float32', dimensions: [1, 2, 3, 3]}, + options: { + filterLayout: 'iohw', + inputLayout: 'nhwc', + }, + output: {dataType: 'float32', dimensions: [1, 5, 5, 2]} + }, + { + name: + '[convTranspose2d] Test with inputLayout="nhwc" and filterLayout="hwoi".', + input: {dataType: 'float32', dimensions: [1, 3, 3, 1]}, + filter: {dataType: 'float32', dimensions: [3, 3, 2, 1]}, + options: { + filterLayout: 'hwoi', + inputLayout: 'nhwc', + }, + output: {dataType: 'float32', dimensions: [1, 5, 5, 2]} + }, + { + name: + '[convTranspose2d] Test with inputLayout="nhwc" and filterLayout="ohwi".', + input: {dataType: 'float32', dimensions: [1, 3, 3, 1]}, + filter: {dataType: 'float32', dimensions: [2, 3, 3, 1]}, + options: { + filterLayout: 'ohwi', + inputLayout: 'nhwc', + }, + output: {dataType: 'float32', dimensions: [1, 5, 5, 2]} + }, + { + name: '[convTranspose2d] Test with strides=[3, 2], outputSizes=[10, 8].', + input: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + filter: {dataType: 'float32', dimensions: [1, 2, 3, 3]}, + options: { + strides: [3, 2], + outputSizes: [10, 8], + }, + output: {dataType: 'float32', dimensions: [1, 2, 10, 8]} + }, + { + name: '[convTranspose2d] Test with strides=[3, 2], outputPadding=[1, 1].', + input: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + filter: {dataType: 'float32', dimensions: [1, 2, 3, 3]}, + options: { + strides: [3, 2], + outputPadding: [1, 1], + }, + output: {dataType: 'float32', dimensions: [1, 2, 10, 8]} + }, + { + name: '[convTranspose2d] Test with padding=1.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + options: { + padding: [1, 1, 1, 1], + }, + output: {dataType: 'float32', dimensions: [1, 1, 5, 5]} + }, + { + name: '[convTranspose2d] Test with padding=1, groups=3.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + options: { + padding: [1, 1, 1, 1], + groups: 3, + }, + output: {dataType: 'float32', dimensions: [1, 3, 5, 5]} + }, + { + name: '[convTranspose2d] Test with strides=2.', + input: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + filter: {dataType: 'float32', dimensions: [1, 2, 3, 3]}, + options: { + strides: [2, 2], + }, + output: {dataType: 'float32', dimensions: [1, 2, 7, 7]} + }, + { + name: '[convTranspose2d] Test with strides=2 and padding=1.', + input: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + filter: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + options: { + padding: [1, 1, 1, 1], + strides: [2, 2], + }, + output: {dataType: 'float32', dimensions: [1, 1, 5, 5]} + }, + { + name: + '[convTranspose2d] Test when the output sizes are explicitly specified, the output padding values are ignored though padding value is not smaller than stride along the same axis.', + input: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + filter: {dataType: 'float32', dimensions: [1, 2, 3, 3]}, + options: { + outputPadding: [3, 3], + strides: [3, 2], + outputSizes: [10, 8], + }, + output: {dataType: 'float32', dimensions: [1, 2, 10, 8]} + }, + { + name: '[convTranspose2d] Throw if the input is not a 4-D tensor.', + input: {dataType: 'float32', dimensions: [1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + }, + { + name: + '[convTranspose2d] Throw if the input data type is not floating point.', + input: {dataType: 'int32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'int32', dimensions: [1, 1, 2, 2]}, + }, + { + name: '[convTranspose2d] Throw if the filter is not a 4-D tensor.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [2, 2]}, + }, + { + name: + '[convTranspose2d] Throw if the filter data type doesn\'t match the input data type.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'int32', dimensions: [1, 1, 2, 2]}, + }, + { + name: '[convTranspose2d] Throw if the length of padding is not 4.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + padding: [2, 2], + }, + }, + { + name: '[convTranspose2d] Throw if the length of strides is not 2.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + strides: [2], + }, + }, + { + name: '[convTranspose2d] Throw if one stride value is smaller than 1.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + strides: [1, 0], + }, + }, + { + name: '[convTranspose2d] Throw if the length of dilations is not 2.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + dilations: [1], + }, + }, + { + name: + '[convTranspose2d] Throw if the one dilation value is smaller than 1.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + dilations: [1, 0], + }, + }, + { + name: + '[convTranspose2d] Throw if the input channels is not equal to the filter input channels with inputLayout="nchw" and filterLayout="iohw".', + input: {dataType: 'float32', dimensions: [1, 3, 3, 3]}, + filter: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + options: { + filterLayout: 'iohw', + inputLayout: 'nchw', + groups: 1, + }, + }, + { + name: + '[convTranspose2d] Throw if the input channels is not equal to the filter input channels with inputLayout="nchw" and filterLayout="hwoi".', + input: {dataType: 'float32', dimensions: [1, 3, 3, 3]}, + filter: {dataType: 'float32', dimensions: [3, 1, 2, 1]}, + options: { + filterLayout: 'hwoi', + inputLayout: 'nchw', + }, + }, + { + name: + '[convTranspose2d] Throw if the input channels is not equal to the filter input channels with inputLayout="nchw" and filterLayout="ohwi".', + input: {dataType: 'float32', dimensions: [1, 2, 3, 3]}, + filter: {dataType: 'float32', dimensions: [2, 3, 3, 1]}, + options: { + filterLayout: 'ohwi', + inputLayout: 'nchw', + }, + }, + { + name: + '[convTranspose2d] Throw if the input channels is not equal to the filter input channels with inputLayout="nhwc" and filterLayout="iohw".', + input: {dataType: 'float32', dimensions: [1, 3, 3, 2]}, + filter: {dataType: 'float32', dimensions: [1, 2, 3, 3]}, + options: { + filterLayout: 'iohw', + inputLayout: 'nhwc', + }, + }, + { + name: + '[convTranspose2d] Throw if the input channels is not equal to the filter input channels inputLayout="nhwc" and filterLayout="hwoi".', + input: {dataType: 'float32', dimensions: [1, 3, 3, 2]}, + filter: {dataType: 'float32', dimensions: [3, 3, 2, 1]}, + options: { + filterLayout: 'hwoi', + inputLayout: 'nhwc', + }, + }, + { + name: + '[convTranspose2d] Throw if the input channels is not equal to the filter input channels with inputLayout="nhwc" and filterLayout="ohwi".', + input: {dataType: 'float32', dimensions: [1, 3, 3, 2]}, + filter: {dataType: 'float32', dimensions: [2, 3, 3, 1]}, + options: { + filterLayout: 'ohwi', + inputLayout: 'nhwc', + }, + }, + { + name: '[convTranspose2d] Throw if output channels is too large.', + input: {dataType: 'float32', dimensions: [1, 4, 5, 5]}, + filter: {dataType: 'float32', dimensions: [4, 2, 2, 2]}, + options: { + groups: kMaxUnsignedLong, + }, + }, + { + name: '[convTranspose2d] Throw if the groups is smaller than 1.', + input: {dataType: 'float32', dimensions: [1, 4, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + groups: 0, + }, + }, + { + name: + '[convTranspose2d] Throw due to overflow when calculating the effective filter height.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 434983, 2]}, + options: { + dilations: [328443, 1], + }, + }, + { + name: + '[convTranspose2d] Throw due to overflow when calculating the effective filter width.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 234545]}, + options: { + dilations: [2, 843452], + }, + }, + { + name: + '[convTranspose2d] Throw due to overflow when dilation height is too large.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 3, 2]}, + options: { + dilations: [kMaxUnsignedLong, 1], + }, + }, + { + name: + '[convTranspose2d] Throw due to overflow when dilation width is too large.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 3, 2]}, + options: { + dilations: [1, kMaxUnsignedLong], + }, + }, + { + name: '[convTranspose2d] Throw if the bias is not a 1-D tensor.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + bias: {dataType: 'float32', dimensions: [1, 2]}, + }, + }, + { + name: + '[convTranspose2d] Throw if the bias shape is not equal to [output_channels] with filterLayout="iohw".', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + filterLayout: 'iohw', + bias: {dataType: 'float32', dimensions: [2]}, + }, + }, + { + name: + '[convTranspose2d] Throw if the bias shape is not equal to [output_channels] with filterLayout="hwoi".', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [2, 2, 1, 1]}, + options: { + filterLayout: 'hwoi', + bias: {dataType: 'float32', dimensions: [2]}, + }, + }, + { + name: + '[convTranspose2d] Throw if the bias shape is not equal to [output_channels] with filterLayout="ohwi".', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 2, 2, 1]}, + options: { + filterLayout: 'ohwi', + bias: {dataType: 'float32', dimensions: [2]}, + }, + }, + { + name: + '[convTranspose2d] Throw if the bias data type doesn\'t match input data type.', + input: {dataType: 'float32', dimensions: [1, 1, 5, 5]}, + filter: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + options: { + bias: {dataType: 'int32', dimensions: [1]}, + }, + }, + { + name: + '[convTranspose2d] Throw if the outputPadding is not a sequence of length 2.', + input: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + filter: {dataType: 'float32', dimensions: [1, 2, 3, 3]}, + options: { + strides: [3, 2], + outputPadding: [1, 1, 1, 1], + }, + }, + { + name: + '[convTranspose2d] Throw if the outputPadding is not smaller than stride along the width dimension.', + input: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + filter: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + options: { + padding: [0, 0, 3, 3], + strides: [2, 2], + outputPadding: [0, 2], + }, + }, + { + name: + '[convTranspose2d] Throw if the outputPadding is not smaller than stride along the height dimension.', + input: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + filter: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + options: { + padding: [0, 0, 3, 3], + strides: [2, 2], + outputPadding: [2, 0], + }, + }, + { + name: + '[convTranspose2d] Throw if the outputSizes is not a sequence of length 2.', + input: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + filter: {dataType: 'float32', dimensions: [1, 2, 3, 3]}, + options: { + strides: [3, 2], + outputSizes: [1, 2, 10, 8], + }, + }, + { + name: '[convTranspose2d] Throw if the padding height is too large.', + input: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + filter: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + options: { + padding: [4, 4, 0, 0], + strides: [2, 2], + outputPadding: [1, 0], + }, + }, + { + name: '[convTranspose2d] Throw if the padding width is too large.', + input: {dataType: 'float32', dimensions: [1, 1, 2, 2]}, + filter: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + options: { + padding: [0, 0, 4, 4], + strides: [2, 2], + outputPadding: [0, 1], + }, + }, + { + name: + '[convTranspose2d] Throw due to outputSizes values are smaller than the output sizes calculated by not using outputPadding.', + input: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + filter: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + options: { + padding: [1, 1, 1, 1], + strides: [2, 2], + outputSizes: [4, 4], + outputPadding: [1, 1], + }, + }, + { + name: + '[convTranspose2d] Throw due to outputSizes values are greater than the output sizes calculated by not using outputPadding.', + input: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + filter: {dataType: 'float32', dimensions: [1, 1, 3, 3]}, + options: { + padding: [1, 1, 1, 1], + strides: [2, 2], + outputSizes: [6, 8], + outputPadding: [1, 1], + }, + }, +]; + +tests.forEach( + test => promise_test(async t => { + const input = builder.input( + 'input', + {dataType: test.input.dataType, dimensions: test.input.dimensions}); + const filter = builder.input( + 'filter', + {dataType: test.filter.dataType, dimensions: test.filter.dimensions}); + + if (test.options && test.options.bias) { + test.options.bias = builder.input('bias', { + dataType: test.options.bias.dataType, + dimensions: test.options.bias.dimensions + }); + } + + if (test.output) { + const output = builder.convTranspose2d(input, filter, test.options); + assert_equals(output.dataType(), test.output.dataType); + assert_array_equals(output.shape(), test.output.dimensions); + } else { + assert_throws_js( + TypeError, + () => builder.convTranspose2d(input, filter, test.options)); + } + }, test.name)); diff --git a/testing/web-platform/tests/webnn/validation_tests/elu.https.any.js b/testing/web-platform/tests/webnn/validation_tests/elu.https.any.js index 6e842cb691..53ec5e54ae 100644 --- a/testing/web-platform/tests/webnn/validation_tests/elu.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/elu.https.any.js @@ -5,3 +5,43 @@ 'use strict'; validateInputFromAnotherBuilder('elu'); + +validateUnaryOperation( + 'elu', floatingPointTypes, /*alsoBuildActivation=*/ true); + +promise_test(async t => { + const options = {alpha: 1.0}; + const input = + builder.input('input', {dataType: 'float32', dimensions: [1, 2, 3]}); + const output = builder.elu(input, options); + assert_equals(output.dataType(), 'float32'); + assert_array_equals(output.shape(), [1, 2, 3]); +}, '[elu] Test building an operator with options'); + +promise_test(async t => { + const options = {alpha: 1.5}; + builder.elu(options); +}, '[elu] Test building an activation with options'); + +promise_test(async t => { + const options = {alpha: -1.0}; + const input = + builder.input('input', {dataType: 'float32', dimensions: [1, 2, 3]}); + assert_throws_js(TypeError, () => builder.elu(input, options)); +}, '[elu] Throw if options.alpha <= 0 when building an operator'); + +promise_test(async t => { + const options = {alpha: NaN}; + const input = builder.input('input', {dataType: 'float16', dimensions: []}); + assert_throws_js(TypeError, () => builder.elu(input, options)); +}, '[elu] Throw if options.alpha is NaN when building an operator'); + +promise_test(async t => { + const options = {alpha: 0}; + assert_throws_js(TypeError, () => builder.elu(options)); +}, '[elu] Throw if options.alpha <= 0 when building an activation'); + +promise_test(async t => { + const options = {alpha: Infinity}; + assert_throws_js(TypeError, () => builder.elu(options)); +}, '[elu] Throw if options.alpha is Infinity when building an activation'); diff --git a/testing/web-platform/tests/webnn/validation_tests/expand.https.any.js b/testing/web-platform/tests/webnn/validation_tests/expand.https.any.js index d90ab89468..088d826df7 100644 --- a/testing/web-platform/tests/webnn/validation_tests/expand.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/expand.https.any.js @@ -12,3 +12,66 @@ multi_builder_test(async (t, builder, otherBuilder) => { assert_throws_js( TypeError, () => builder.expand(inputFromOtherBuilder, newShape)); }, '[expand] throw if input is from another builder'); + +const tests = [ + { + name: '[expand] Test with 0-D scalar to 3-D tensor.', + input: {dataType: 'float32', dimensions: []}, + newShape: [3, 4, 5], + output: {dataType: 'float32', dimensions: [3, 4, 5]} + }, + { + name: '[expand] Test with the new shapes that are the same as input.', + input: {dataType: 'float32', dimensions: [4]}, + newShape: [4], + output: {dataType: 'float32', dimensions: [4]} + }, + { + name: '[expand] Test with the new shapes that are broadcastable.', + input: {dataType: 'int32', dimensions: [3, 1, 5]}, + newShape: [3, 4, 5], + output: {dataType: 'int32', dimensions: [3, 4, 5]} + }, + { + name: + '[expand] Test with the new shapes that are broadcastable and the rank of new shapes is larger than input.', + input: {dataType: 'int32', dimensions: [2, 5]}, + newShape: [3, 2, 5], + output: {dataType: 'int32', dimensions: [3, 2, 5]} + }, + { + name: + '[expand] Throw if the input shapes are the same rank but not broadcastable.', + input: {dataType: 'uint32', dimensions: [3, 6, 2]}, + newShape: [4, 3, 5], + }, + { + name: '[expand] Throw if the input shapes are not broadcastable.', + input: {dataType: 'uint32', dimensions: [5, 4]}, + newShape: [5], + }, + { + name: '[expand] Throw if the number of new shapes is too large.', + input: {dataType: 'float32', dimensions: [1, 2, 1, 1]}, + newShape: [1, 2, kMaxUnsignedLong, kMaxUnsignedLong], + }, +]; + +tests.forEach( + test => promise_test(async t => { + const input = builder.input( + 'input', + {dataType: test.input.dataType, dimensions: test.input.dimensions}); + const options = {}; + if (test.axis) { + options.axis = test.axis; + } + + if (test.output) { + const output = builder.expand(input, test.newShape); + assert_equals(output.dataType(), test.output.dataType); + assert_array_equals(output.shape(), test.output.dimensions); + } else { + assert_throws_js(TypeError, () => builder.expand(input, test.newShape)); + } + }, test.name)); diff --git a/testing/web-platform/tests/webnn/validation_tests/gelu.https.any.js b/testing/web-platform/tests/webnn/validation_tests/gelu.https.any.js new file mode 100644 index 0000000000..c758c61f4c --- /dev/null +++ b/testing/web-platform/tests/webnn/validation_tests/gelu.https.any.js @@ -0,0 +1,10 @@ +// META: title=validation tests for WebNN API gelu operation +// META: global=window,dedicatedworker +// META: script=../resources/utils_validation.js + +'use strict'; + +validateInputFromAnotherBuilder('gelu'); + +validateUnaryOperation( + 'gelu', floatingPointTypes, /*alsoBuildActivation=*/ true); diff --git a/testing/web-platform/tests/webnn/validation_tests/gemm.https.any.js b/testing/web-platform/tests/webnn/validation_tests/gemm.https.any.js index 77ce6383cc..abe0ba6193 100644 --- a/testing/web-platform/tests/webnn/validation_tests/gemm.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/gemm.https.any.js @@ -19,3 +19,143 @@ multi_builder_test(async (t, builder, otherBuilder) => { const b = builder.input('b', kExampleInputDescriptor); assert_throws_js(TypeError, () => builder.gemm(a, b, options)); }, '[gemm] throw if c option is from another builder'); + +const tests = [ + { + name: '[gemm] Test building gemm with default option.', + a: {dataType: 'float32', dimensions: [2, 3]}, + b: {dataType: 'float32', dimensions: [3, 4]}, + output: {dataType: 'float32', dimensions: [2, 4]} + }, + { + name: + '[gemm] Throw if inputShapeA[1] is not equal to inputShapeB[0] default options.', + a: {dataType: 'float32', dimensions: [2, 3]}, + b: {dataType: 'float32', dimensions: [2, 4]}, + }, + { + name: '[gemm] Test building gemm with aTranspose=true.', + a: {dataType: 'float32', dimensions: [2, 3]}, + b: {dataType: 'float32', dimensions: [2, 4]}, + options: { + aTranspose: true, + }, + output: {dataType: 'float32', dimensions: [3, 4]} + }, + { + name: + '[gemm] Throw if inputShapeA[0] is not equal to inputShapeB[0] with aTranspose=true.', + a: {dataType: 'float32', dimensions: [2, 3]}, + b: {dataType: 'float32', dimensions: [3, 4]}, + options: { + aTranspose: true, + }, + }, + { + name: '[gemm] Test building gemm with bTranspose=true.', + a: {dataType: 'float32', dimensions: [2, 3]}, + b: {dataType: 'float32', dimensions: [4, 3]}, + options: { + bTranspose: true, + }, + output: {dataType: 'float32', dimensions: [2, 4]} + }, + { + name: + '[gemm] Throw if inputShapeA[0] is not equal to inputShapeB[0] with bTranspose=true.', + a: {dataType: 'float32', dimensions: [2, 3]}, + b: {dataType: 'float32', dimensions: [3, 4]}, + options: { + bTranspose: true, + }, + }, + { + name: '[gemm] Throw if the rank of inputA is not 2.', + a: {dataType: 'float32', dimensions: [2, 3, 1]}, + b: {dataType: 'float32', dimensions: [2, 4]}, + }, + { + name: '[gemm] Throw if the rank of inputB is not 2.', + a: {dataType: 'float32', dimensions: [2, 4]}, + b: {dataType: 'float32', dimensions: [2, 3, 1]}, + }, + { + name: '[gemm] Throw if data types of two inputs do not match.', + a: {dataType: 'float32', dimensions: [2, 3]}, + b: {dataType: 'float16', dimensions: [3, 4]}, + }, + { + name: '[gemm] Test building gemm with inputC.', + a: {dataType: 'float32', dimensions: [2, 3]}, + b: {dataType: 'float32', dimensions: [3, 4]}, + options: { + c: {dataType: 'float32', dimensions: [4]}, + }, + output: {dataType: 'float32', dimensions: [2, 4]} + }, + { + name: '[gemm] Test building gemm with scalar inputC.', + a: {dataType: 'float32', dimensions: [2, 3]}, + b: {dataType: 'float32', dimensions: [3, 4]}, + options: { + c: {dataType: 'float32', dimensions: []}, + }, + output: {dataType: 'float32', dimensions: [2, 4]} + }, + { + name: + '[gemm] Throw if inputShapeC is not unidirectionally broadcastable to the output shape [inputShapeA[0], inputShapeB[1]].', + a: {dataType: 'float32', dimensions: [2, 3]}, + b: {dataType: 'float32', dimensions: [3, 4]}, + options: { + c: {dataType: 'float32', dimensions: [2, 3]}, + }, + }, + { + name: '[gemm] Throw if the input data type is not floating point.', + a: {dataType: 'int32', dimensions: [2, 3]}, + b: {dataType: 'int32', dimensions: [3, 4]} + }, + { + name: + '[gemm] Throw if data type of inputC does not match ones of inputA and inputB.', + a: {dataType: 'float32', dimensions: [3, 2]}, + b: {dataType: 'float32', dimensions: [4, 3]}, + options: { + c: {dataType: 'float16', dimensions: [2, 4]}, + aTranspose: true, + bTranspose: true, + }, + }, + { + name: '[gemm] Throw if the rank of inputC is 3.', + a: {dataType: 'float32', dimensions: [3, 2]}, + b: {dataType: 'float32', dimensions: [4, 3]}, + options: { + c: {dataType: 'float32', dimensions: [2, 3, 4]}, + aTranspose: true, + bTranspose: true, + }, + }, +]; + +tests.forEach( + test => promise_test(async t => { + const a = builder.input( + 'a', {dataType: test.a.dataType, dimensions: test.a.dimensions}); + const b = builder.input( + 'b', {dataType: test.b.dataType, dimensions: test.b.dimensions}); + if (test.options && test.options.c) { + test.options.c = builder.input('c', { + dataType: test.options.c.dataType, + dimensions: test.options.c.dimensions + }); + } + if (test.output) { + const output = builder.gemm(a, b, test.options); + assert_equals(output.dataType(), test.output.dataType); + assert_array_equals(output.shape(), test.output.dimensions); + } else { + assert_throws_js(TypeError, () => builder.gemm(a, b, test.options)); + } + }, test.name)); diff --git a/testing/web-platform/tests/webnn/validation_tests/hardSigmoid.https.any.js b/testing/web-platform/tests/webnn/validation_tests/hardSigmoid.https.any.js index 01b24dbc7c..2c55d0eb9d 100644 --- a/testing/web-platform/tests/webnn/validation_tests/hardSigmoid.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/hardSigmoid.https.any.js @@ -5,3 +5,31 @@ 'use strict'; validateInputFromAnotherBuilder('hardSigmoid'); + +validateUnaryOperation( + 'hardSigmoid', floatingPointTypes, /*alsoBuildActivation=*/ true); + +promise_test(async t => { + const options = {alpha: 0.5, beta: 1.0}; + const input = + builder.input('input', {dataType: 'float16', dimensions: [1, 2, 3]}); + const output = builder.hardSigmoid(input, options); + assert_equals(output.dataType(), 'float16'); + assert_array_equals(output.shape(), [1, 2, 3]); +}, '[hardSigmoid] Test building an operator with options'); + +promise_test(async t => { + const options = {alpha: 0.2}; + builder.hardSigmoid(options); +}, '[hardSigmoid] Test building an activation with options'); + +promise_test(async t => { + const options = {beta: NaN}; + const input = builder.input('input', {dataType: 'float32', dimensions: []}); + assert_throws_js(TypeError, () => builder.hardSigmoid(input, options)); +}, '[hardSigmoid] Throw if options.beta is NaN when building an operator'); + +promise_test(async t => { + const options = {alpha: Infinity}; + assert_throws_js(TypeError, () => builder.hardSigmoid(options)); +}, '[hardSigmoid] Throw if options.alpha is Infinity when building an activation'); diff --git a/testing/web-platform/tests/webnn/validation_tests/instanceNormalization.https.any.js b/testing/web-platform/tests/webnn/validation_tests/instanceNormalization.https.any.js index bdd338588f..4fc26ec5ae 100644 --- a/testing/web-platform/tests/webnn/validation_tests/instanceNormalization.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/instanceNormalization.https.any.js @@ -41,3 +41,152 @@ multi_builder_test(async (t, builder, otherBuilder) => { assert_throws_js( TypeError, () => builder.instanceNormalization(input, options)); }, '[instanceNormalization] throw if bias option is from another builder'); + +const tests = [ + { + name: '[instanceNormalization] Test with default options for 4-D input.', + input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + output: {dataType: 'float32', dimensions: [1, 2, 3, 4]} + }, + { + name: + '[instanceNormalization] Test with scale, bias and default epsilon value.', + input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + options: { + scale: {dataType: 'float32', dimensions: [2]}, + bias: {dataType: 'float32', dimensions: [2]}, + epsilon: 1e-5, + }, + output: {dataType: 'float32', dimensions: [1, 2, 3, 4]} + }, + { + name: '[instanceNormalization] Test with a non-default epsilon value.', + input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + options: { + epsilon: 1e-4, + }, + output: {dataType: 'float32', dimensions: [1, 2, 3, 4]} + }, + { + name: '[instanceNormalization] Test with layout=nhwc.', + input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + options: { + layout: 'nhwc', + scale: {dataType: 'float32', dimensions: [4]}, + bias: {dataType: 'float32', dimensions: [4]}, + }, + output: {dataType: 'float32', dimensions: [1, 2, 3, 4]} + }, + { + name: '[instanceNormalization] Test when the input data type is float16.', + input: {dataType: 'float16', dimensions: [1, 2, 3, 4]}, + output: {dataType: 'float16', dimensions: [1, 2, 3, 4]} + }, + { + name: '[instanceNormalization] Throw if the input is not a 4-D tensor.', + input: {dataType: 'float32', dimensions: [1, 2, 5, 5, 2]}, + }, + { + name: + '[instanceNormalization] Throw if the input data type is not one of floating point types.', + input: {dataType: 'int32', dimensions: [1, 2, 5, 5]}, + }, + { + name: + '[instanceNormalization] Throw if the scale data type is not the same as the input data type.', + input: {dataType: 'float16', dimensions: [1, 2, 5, 5]}, + options: { + scale: {dataType: 'float32', dimensions: [2]}, + }, + }, + { + name: + '[instanceNormalization] Throw if the scale operand is not a 1-D tensor.', + input: {dataType: 'float32', dimensions: [1, 2, 5, 5]}, + options: { + scale: {dataType: 'float32', dimensions: [2, 1]}, + }, + }, + { + name: + '[instanceNormalization] Throw if the size of scale operand is not equal to the size of the feature dimension of the input with layout=nhwc.', + input: {dataType: 'float32', dimensions: [1, 2, 5, 5]}, + options: { + layout: 'nhwc', + scale: {dataType: 'float32', dimensions: [2]}, + }, + }, + { + name: + '[instanceNormalization] Throw if the size of scale operand is not equal to the size of the feature dimension of the input with layout=nchw.', + input: {dataType: 'float32', dimensions: [1, 5, 5, 2]}, + options: { + layout: 'nchw', + scale: {dataType: 'float32', dimensions: [2]}, + }, + }, + { + name: + '[instanceNormalization] Throw if the bias data type is not the same as the input data type.', + input: {dataType: 'float16', dimensions: [1, 2, 5, 5]}, + options: { + bias: {dataType: 'float32', dimensions: [2]}, + }, + }, + { + name: + '[instanceNormalization] Throw if the bias operand is not a 1-D tensor.', + input: {dataType: 'float32', dimensions: [1, 2, 5, 5]}, + options: { + scale: {dataType: 'float32', dimensions: [2, 1]}, + }, + }, + { + name: + '[instanceNormalization] Throw if the size of bias operand is not equal to the size of the feature dimension of the input with layout=nhwc.', + input: {dataType: 'float32', dimensions: [1, 2, 5, 5]}, + options: { + layout: 'nhwc', + bias: {dataType: 'float32', dimensions: [2]}, + }, + }, + { + name: + '[instanceNormalization] Throw if the size of bias operand is not equal to the size of the feature dimension of the input with layout=nchw.', + input: {dataType: 'float32', dimensions: [1, 5, 5, 2]}, + options: { + layout: 'nchw', + bias: {dataType: 'float32', dimensions: [2]}, + }, + }, +]; + +tests.forEach( + test => promise_test(async t => { + const input = builder.input( + 'input', + {dataType: test.input.dataType, dimensions: test.input.dimensions}); + + if (test.options && test.options.bias) { + test.options.bias = builder.input('bias', { + dataType: test.options.bias.dataType, + dimensions: test.options.bias.dimensions + }); + } + if (test.options && test.options.scale) { + test.options.scale = builder.input('scale', { + dataType: test.options.scale.dataType, + dimensions: test.options.scale.dimensions + }); + } + + if (test.output) { + const output = builder.instanceNormalization(input, test.options); + assert_equals(output.dataType(), test.output.dataType); + assert_array_equals(output.shape(), test.output.dimensions); + } else { + assert_throws_js( + TypeError, + () => builder.instanceNormalization(input, test.options)); + } + }, test.name)); diff --git a/testing/web-platform/tests/webnn/validation_tests/layerNormalization.https.any.js b/testing/web-platform/tests/webnn/validation_tests/layerNormalization.https.any.js index e9e9141aa6..63f9c0dbc5 100644 --- a/testing/web-platform/tests/webnn/validation_tests/layerNormalization.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/layerNormalization.https.any.js @@ -9,8 +9,6 @@ const kExampleInputDescriptor = { dimensions: [2, 2] }; -validateOptionsAxes('layerNormalization', 4); - validateInputFromAnotherBuilder('layerNormalization'); multi_builder_test(async (t, builder, otherBuilder) => { @@ -30,3 +28,181 @@ multi_builder_test(async (t, builder, otherBuilder) => { const input = builder.input('input', kExampleInputDescriptor); assert_throws_js(TypeError, () => builder.layerNormalization(input, options)); }, '[layerNormalization] throw if bias option is from another builder'); + +const tests = [ + { + name: '[layerNormalization] Test with default options for scalar input.', + input: {dataType: 'float32', dimensions: []}, + output: {dataType: 'float32', dimensions: []}, + }, + { + name: '[layerNormalization] Test when the input data type is float16.', + input: {dataType: 'float16', dimensions: []}, + output: {dataType: 'float16', dimensions: []}, + }, + { + name: '[layerNormalization] Test with given axes.', + input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + options: { + axes: [3], + }, + output: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + }, + { + name: '[layerNormalization] Test with given scale.', + input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + options: { + scale: {dataType: 'float32', dimensions: [2, 3, 4]}, + }, + output: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + }, + { + name: '[layerNormalization] Test with a non-default epsilon value.', + input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + options: { + epsilon: 1e-4, // default epsilon=1e-5 + }, + output: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + }, + { + name: '[layerNormalization] Test with given axes, scale and bias.', + input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + options: { + scale: {dataType: 'float32', dimensions: [3, 4]}, + bias: {dataType: 'float32', dimensions: [3, 4]}, + axes: [2, 3], + }, + output: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + }, + { + name: '[layerNormalization] Test with nonconsecutive axes.', + input: {dataType: 'float32', dimensions: [1, 2, 3, 4, 5, 6]}, + options: { + scale: {dataType: 'float32', dimensions: [2, 4, 6]}, + bias: {dataType: 'float32', dimensions: [2, 4, 6]}, + axes: [1, 3, 5], + }, + output: {dataType: 'float32', dimensions: [1, 2, 3, 4, 5, 6]}, + }, + { + name: '[layerNormalization] Test with axes in descending order.', + input: {dataType: 'float32', dimensions: [1, 2, 3, 4, 5, 6]}, + options: { + scale: {dataType: 'float32', dimensions: [6, 5, 4, 3, 2]}, + bias: {dataType: 'float32', dimensions: [6, 5, 4, 3, 2]}, + axes: [5, 4, 3, 2, 1] + }, + output: {dataType: 'float32', dimensions: [1, 2, 3, 4, 5, 6]}, + }, + { + name: + '[layerNormalization] Throw if the input data type is not one of the floating point types.', + input: {dataType: 'uint32', dimensions: [1, 2, 3, 4]}, + }, + { + name: + '[layerNormalization] Throw if the axis is greater than the input rank.', + input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + options: { + axes: [1, 2, 4], + }, + }, + { + name: '[layerNormalization] Throw if the axes have duplications.', + input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + options: {axes: [3, 3]}, + }, + { + name: + '[layerNormalization] Throw if the bias data type doesn\'t match input data type', + input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + options: { + scale: {dataType: 'float32', dimensions: [3, 4]}, + bias: {dataType: 'float16', dimensions: [3, 4]}, + axes: [2, 3], + }, + }, + { + name: + '[layerNormalization] Throw if the scale data type doesn\'t match input data type', + input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + options: { + scale: {dataType: 'float16', dimensions: [3, 4]}, + bias: {dataType: 'float32', dimensions: [3, 4]}, + axes: [2, 3], + }, + }, + { + name: + '[layerNormalization] Throw if the bias dimensions doesn\'t match axis dimensions.', + input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + options: { + bias: { + dataType: 'float32', + dimensions: [3, 3, 4] + }, // for 4D input, default axes = [1,2,3] + }, + }, + { + name: + '[layerNormalization] Throw if the scale dimensions doesn\'t match axis dimensions.', + input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + options: { + scale: { + dataType: 'float32', + dimensions: [3, 3, 4] + }, // for 4D input, default axes = [1,2,3] + }, + }, + { + name: + '[layerNormalization] Throw if the bias rank doesn\'t match axis rank.', + input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + options: { + bias: { + dataType: 'float32', + dimensions: [1, 2, 3, 4] + }, // for 4D input, default axes = [1,2,3] + }, + }, + { + name: + '[layerNormalization] Throw if the scale rank doesn\'t match axis rank.', + input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + options: { + scale: { + dataType: 'float32', + dimensions: [1, 2, 3, 4] + }, // for 4D input, default axes = [1,2,3] + }, + }, +]; + +tests.forEach( + test => promise_test(async t => { + const input = builder.input( + 'input', + {dataType: test.input.dataType, dimensions: test.input.dimensions}); + + if (test.options && test.options.bias) { + test.options.bias = builder.input('bias', { + dataType: test.options.bias.dataType, + dimensions: test.options.bias.dimensions + }); + } + if (test.options && test.options.scale) { + test.options.scale = builder.input('scale', { + dataType: test.options.scale.dataType, + dimensions: test.options.scale.dimensions + }); + } + + if (test.output) { + const output = builder.layerNormalization(input, test.options); + assert_equals(output.dataType(), test.output.dataType); + assert_array_equals(output.shape(), test.output.dimensions); + } else { + assert_throws_js( + TypeError, () => builder.layerNormalization(input, test.options)); + } + }, test.name)); diff --git a/testing/web-platform/tests/webnn/validation_tests/leakyRelu.https.any.js b/testing/web-platform/tests/webnn/validation_tests/leakyRelu.https.any.js index 6fc19b1f0d..f250b0eda6 100644 --- a/testing/web-platform/tests/webnn/validation_tests/leakyRelu.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/leakyRelu.https.any.js @@ -5,3 +5,31 @@ 'use strict'; validateInputFromAnotherBuilder('leakyRelu'); + +validateUnaryOperation( + 'leakyRelu', floatingPointTypes, /*alsoBuildActivation=*/ true); + +promise_test(async t => { + const options = {alpha: 0.02}; + const input = + builder.input('input', {dataType: 'float32', dimensions: [1, 2, 3]}); + const output = builder.leakyRelu(input, options); + assert_equals(output.dataType(), 'float32'); + assert_array_equals(output.shape(), [1, 2, 3]); +}, '[leakyRelu] Test building an operator with options'); + +promise_test(async t => { + const options = {alpha: 0.03}; + builder.leakyRelu(options); +}, '[leakyRelu] Test building an activation with options'); + +promise_test(async t => { + const options = {alpha: Infinity}; + const input = builder.input('input', {dataType: 'float16', dimensions: []}); + assert_throws_js(TypeError, () => builder.leakyRelu(input, options)); +}, '[leakyRelu] Throw if options.alpha is Infinity when building an operator'); + +promise_test(async t => { + const options = {alpha: -NaN}; + assert_throws_js(TypeError, () => builder.leakyRelu(options)); +}, '[leakyRelu] Throw if options.alpha is -NaN when building an activation'); diff --git a/testing/web-platform/tests/webnn/validation_tests/linear.https.any.js b/testing/web-platform/tests/webnn/validation_tests/linear.https.any.js index 99c1daad3f..6ec0389fc3 100644 --- a/testing/web-platform/tests/webnn/validation_tests/linear.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/linear.https.any.js @@ -5,3 +5,31 @@ 'use strict'; validateInputFromAnotherBuilder('linear'); + +validateUnaryOperation( + 'linear', floatingPointTypes, /*alsoBuildActivation=*/ true); + +promise_test(async t => { + const options = {alpha: 1.5, beta: 0.3}; + const input = + builder.input('input', {dataType: 'float32', dimensions: [1, 2, 3]}); + const output = builder.linear(input, options); + assert_equals(output.dataType(), 'float32'); + assert_array_equals(output.shape(), [1, 2, 3]); +}, '[linear] Test building an operator with options'); + +promise_test(async t => { + const options = {beta: 1.5}; + builder.linear(options); +}, '[linear] Test building an activation with options'); + +promise_test(async t => { + const options = {beta: -Infinity}; + const input = builder.input('input', {dataType: 'float16', dimensions: []}); + assert_throws_js(TypeError, () => builder.linear(input, options)); +}, '[linear] Throw if options.beta is -Infinity when building an operator'); + +promise_test(async t => { + const options = {alpha: NaN}; + assert_throws_js(TypeError, () => builder.linear(options)); +}, '[linear] Throw if options.alpha is NaN when building an activation'); diff --git a/testing/web-platform/tests/webnn/validation_tests/matmul.https.any.js b/testing/web-platform/tests/webnn/validation_tests/matmul.https.any.js index 03616ddb01..8db16242c9 100644 --- a/testing/web-platform/tests/webnn/validation_tests/matmul.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/matmul.https.any.js @@ -5,3 +5,116 @@ 'use strict'; validateTwoInputsFromMultipleBuilders('matmul'); + +const tests = [ + { + name: '[matmul] Throw if first input\'s rank is less than 2', + inputs: { + a: {dataType: 'float32', dimensions: [2]}, + b: {dataType: 'float32', dimensions: [2, 2]} + } + }, + { + name: '[matmul] Throw if second input\'s rank is less than 2', + inputs: { + a: {dataType: 'float32', dimensions: [2, 2]}, + b: {dataType: 'float32', dimensions: [2]} + } + }, + { + name: '[matmul] Test with 2-D input and 4-D input', + inputs: { + a: {dataType: 'float32', dimensions: [1, 4]}, + b: {dataType: 'float32', dimensions: [2, 2, 4, 2]} + }, + output: {dataType: 'float32', dimensions: [2, 2, 1, 2]} + }, + { + name: '[matmul] Test with 2-D input and 2-D input', + inputs: { + a: {dataType: 'float32', dimensions: [4, 2]}, + b: {dataType: 'float32', dimensions: [2, 3]} + }, + output: {dataType: 'float32', dimensions: [4, 3]} + }, + { + // batchShape is a clone of inputShape with the spatial dimensions + // (last 2 items) removed. + name: + '[matmul] Test with 3-D input and 3-D input of broadcastable batchShape', + inputs: { + a: {dataType: 'float32', dimensions: [2, 3, 4]}, + b: {dataType: 'float32', dimensions: [1, 4, 1]} + }, + output: {dataType: 'float32', dimensions: [2, 3, 1]} + }, + { + // batchShape is a clone of inputShape with the spatial dimensions + // (last 2 items) removed. + name: + '[matmul] Test with 4-D input and 3-D input of broadcastable batchShape', + inputs: { + a: {dataType: 'float32', dimensions: [2, 2, 3, 4]}, + b: {dataType: 'float32', dimensions: [1, 4, 5]} + }, + output: {dataType: 'float32', dimensions: [2, 2, 3, 5]} + }, + { + name: '[matmul] Test with 3-D input and 3-D input', + inputs: { + a: {dataType: 'float32', dimensions: [2, 3, 4]}, + b: {dataType: 'float32', dimensions: [2, 4, 5]} + }, + output: {dataType: 'float32', dimensions: [2, 3, 5]} + }, + { + name: '[matmul] Throw if the input data type is not floating point', + inputs: { + a: {dataType: 'uint32', dimensions: [2, 3, 4]}, + b: {dataType: 'uint32', dimensions: [2, 4, 5]} + } + }, + { + name: '[matmul] Throw if data type of two inputs don\'t match', + inputs: { + a: {dataType: 'float32', dimensions: [2, 3, 4]}, + b: {dataType: 'float16', dimensions: [2, 4, 5]} + } + }, + { + name: + '[matmul] Throw if columns of first input\'s shape doesn\'t match the rows of second input\'s shape', + inputs: { + a: {dataType: 'float32', dimensions: /* [rows, columns] */[2, 3]}, + b: {dataType: 'float32', dimensions: /* [rows, columns] */[2, 4]} + }, + }, + { + // batchShape is a clone of inputShape with the spatial dimensions + // (last 2 items) removed. + name: '[matmul] Throw if batchShapes aren\'t bidirectionally broadcastable', + inputs: { + a: {dataType: 'float32', dimensions: [3, 3, 4]}, + b: {dataType: 'float32', dimensions: [2, 4, 1]} + }, + }, +]; + +tests.forEach(test => promise_test(async t => { + const inputA = builder.input('a', { + dataType: test.inputs.a.dataType, + dimensions: test.inputs.a.dimensions + }); + const inputB = builder.input('b', { + dataType: test.inputs.b.dataType, + dimensions: test.inputs.b.dimensions + }); + if (test.output) { + const output = builder.matmul(inputA, inputB); + assert_equals(output.dataType(), test.output.dataType); + assert_array_equals(output.shape(), test.output.dimensions); + } else { + assert_throws_js( + TypeError, () => builder.matmul(inputA, inputB)); + } + }, test.name)); diff --git a/testing/web-platform/tests/webnn/validation_tests/pad.https.any.js b/testing/web-platform/tests/webnn/validation_tests/pad.https.any.js index 11c6a8f7ef..cc39bee4c0 100644 --- a/testing/web-platform/tests/webnn/validation_tests/pad.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/pad.https.any.js @@ -15,3 +15,73 @@ multi_builder_test(async (t, builder, otherBuilder) => { () => builder.pad(inputFromOtherBuilder, beginningPadding, endingPadding)); }, '[pad] throw if input is from another builder'); + +const tests = [ + { + name: + '[pad] Test with default options, beginningPadding=[1, 2] and endingPadding=[1, 2].', + input: {dataType: 'float32', dimensions: [2, 3]}, + beginningPadding: [1, 2], + endingPadding: [1, 2], + options: { + mode: 'constant', + value: 0, + }, + output: {dataType: 'float32', dimensions: [4, 7]} + }, + { + name: '[pad] Throw if building pad for scalar input.', + input: {dataType: 'float32', dimensions: []}, + beginningPadding: [], + endingPadding: [], + }, + { + name: + '[pad] Throw if the length of beginningPadding is not equal to the input rank.', + input: {dataType: 'float32', dimensions: [2, 3]}, + beginningPadding: [1], + endingPadding: [1, 2], + options: { + mode: 'edge', + value: 0, + }, + }, + { + name: + '[pad] Throw if the length of endingPadding is not equal to the input rank.', + input: {dataType: 'float32', dimensions: [2, 3]}, + beginningPadding: [1, 0], + endingPadding: [1, 2, 0], + options: { + mode: 'reflection', + }, + }, + { + name: '[pad] Throw if the padding of one dimension is too large.', + input: {dataType: 'float32', dimensions: [2, 3]}, + beginningPadding: [2294967295, 0], + endingPadding: [3294967295, 2], + options: { + mode: 'reflection', + }, + }, +]; + +tests.forEach( + test => promise_test(async t => { + const input = builder.input( + 'input', + {dataType: test.input.dataType, dimensions: test.input.dimensions}); + if (test.output) { + const output = builder.pad( + input, test.beginningPadding, test.endingPadding, test.options); + assert_equals(output.dataType(), test.output.dataType); + assert_array_equals(output.shape(), test.output.dimensions); + } else { + assert_throws_js( + TypeError, + () => builder.pad( + input, test.beginningPadding, test.endingPadding, + test.options)); + } + }, test.name)); diff --git a/testing/web-platform/tests/webnn/validation_tests/pooling-and-reduction-keep-dims.https.any.js b/testing/web-platform/tests/webnn/validation_tests/pooling-and-reduction-keep-dims.https.any.js new file mode 100644 index 0000000000..9f6b9fb338 --- /dev/null +++ b/testing/web-platform/tests/webnn/validation_tests/pooling-and-reduction-keep-dims.https.any.js @@ -0,0 +1,94 @@ +// META: title=validation tests for pooling and reduction operators keep dimensions +// META: global=window,dedicatedworker +// META: script=../resources/utils.js +// META: script=../resources/utils_validation.js +// META: timeout=long + +'use strict'; + +// This is used to reproduce an issue(crbug.com/331841268) of averagePool2d in +// ResNetV2 50 model. +// [input] +// | +// [globalAveragePool] +// | +// [conv2d] +// | +// [reshape] +// | +// [output] +promise_test(async t => { + const avgPool2dInputShape = [1, 7, 7, 2048]; + const avgPool2dInput = builder.input( + `avgPool2dInput`, {dataType: 'float32', dimensions: avgPool2dInputShape}); + const avgPool2dOutput = + builder.averagePool2d(avgPool2dInput, {layout: 'nhwc'}); + const conv2dFilterShape = [1001, 1, 1, 2048]; + const conv2dFilter = builder.constant( + {dataType: 'float32', dimensions: conv2dFilterShape}, + new Float32Array(sizeOfShape(conv2dFilterShape)).fill(1)); + const conv2dBias = builder.constant( + {dataType: 'float32', dimensions: [1001]}, + new Float32Array(1001).fill(0.01)); + const conv2dOutput = builder.conv2d(avgPool2dOutput, conv2dFilter, { + inputLayout: 'nhwc', + filterLayout: 'ohwi', + padding: [0, 0, 0, 0], + bias: conv2dBias + }); + const newShape = [1, 1001]; + const reshapeOutput = builder.reshape(conv2dOutput, newShape); + assert_equals(reshapeOutput.dataType(), avgPool2dInput.dataType()); + assert_array_equals(reshapeOutput.shape(), newShape); + const graph = await builder.build({reshapeOutput}); + const result = await context.compute( + graph, { + 'avgPool2dInput': + new Float32Array(sizeOfShape(avgPool2dInputShape)).fill(0.1) + }, + {'reshapeOutput': new Float32Array(1001)}); +}, 'Test global average pool operator\'s output shape for ResNetV2 50 model.'); + +// This is used to reproduce an issue(crbug.com/331841268) of reduceMean in +// ResNetV2 50 model. +// [input] +// | +// [reduceMean] +// | +// [conv2d] +// | +// [reshape] +// | +// [output] +promise_test(async t => { + const reduceMeanInputShape = [1, 7, 7, 2048]; + const reduceMeanInput = builder.input( + `reduceMeanInput`, + {dataType: 'float32', dimensions: reduceMeanInputShape}); + const reduceMeanOutput = + builder.reduceMean(reduceMeanInput, {axes: [1, 2], keepDimensions: true}); + const conv2dFilterShape = [1001, 1, 1, 2048]; + const conv2dFilter = builder.constant( + {dataType: 'float32', dimensions: conv2dFilterShape}, + new Float32Array(sizeOfShape(conv2dFilterShape)).fill(1)); + const conv2dBias = builder.constant( + {dataType: 'float32', dimensions: [1001]}, + new Float32Array(1001).fill(0.01)); + const conv2dOutput = builder.conv2d(reduceMeanOutput, conv2dFilter, { + inputLayout: 'nhwc', + filterLayout: 'ohwi', + padding: [0, 0, 0, 0], + bias: conv2dBias + }); + const newShape = [1, 1001]; + const reshapeOutput = builder.reshape(conv2dOutput, newShape); + assert_equals(reshapeOutput.dataType(), reduceMeanInput.dataType()); + assert_array_equals(reshapeOutput.shape(), newShape); + const graph = await builder.build({reshapeOutput}); + const result = await context.compute( + graph, { + 'reduceMeanInput': + new Float32Array(sizeOfShape(reduceMeanInputShape)).fill(0.1) + }, + {'reshapeOutput': new Float32Array(1001)}); +}, 'Test reduceMean operator\'s output shape for ResNetV2 50 model.'); diff --git a/testing/web-platform/tests/webnn/validation_tests/reshape.https.any.js b/testing/web-platform/tests/webnn/validation_tests/reshape.https.any.js index 435551b716..67491fbc16 100644 --- a/testing/web-platform/tests/webnn/validation_tests/reshape.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/reshape.https.any.js @@ -12,3 +12,68 @@ multi_builder_test(async (t, builder, otherBuilder) => { assert_throws_js( TypeError, () => builder.reshape(inputFromOtherBuilder, newShape)); }, '[reshape] throw if input is from another builder'); + +const tests = [ + { + name: '[reshape] Test with new shape=[3, 8].', + input: {dataType: 'float32', dimensions: [2, 3, 4]}, + newShape: [3, 8], + output: {dataType: 'float32', dimensions: [3, 8]} + }, + { + name: '[reshape] Test with new shape=[24], src shape=[2, 3, 4].', + input: {dataType: 'float32', dimensions: [2, 3, 4]}, + newShape: [24], + output: {dataType: 'float32', dimensions: [24]} + }, + { + name: '[reshape] Test with new shape=[1], src shape=[1].', + input: {dataType: 'float32', dimensions: [1]}, + newShape: [1], + output: {dataType: 'float32', dimensions: [1]} + }, + { + name: '[reshape] Test reshaping a 1-D 1-element tensor to scalar.', + input: {dataType: 'float32', dimensions: [1]}, + newShape: [], + output: {dataType: 'float32', dimensions: []} + }, + { + name: '[reshape] Test reshaping a scalar to 1-D 1-element tensor.', + input: {dataType: 'float32', dimensions: []}, + newShape: [1], + output: {dataType: 'float32', dimensions: [1]} + }, + { + name: '[reshape] Throw if one value of new shape is 0.', + input: {dataType: 'float32', dimensions: [2, 4]}, + newShape: [2, 4, 0], + }, + { + name: + '[reshape] Throw if the number of elements implied by new shape is not equal to the number of elements in the input tensor when new shape=[].', + input: {dataType: 'float32', dimensions: [2, 3, 4]}, + newShape: [], + }, + { + name: + '[reshape] Throw if the number of elements implied by new shape is not equal to the number of elements in the input tensor.', + input: {dataType: 'float32', dimensions: [2, 3, 4]}, + newShape: [3, 9], + }, +]; + +tests.forEach( + test => promise_test(async t => { + const input = builder.input( + 'input', + {dataType: test.input.dataType, dimensions: test.input.dimensions}); + if (test.output) { + const output = builder.reshape(input, test.newShape); + assert_equals(output.dataType(), test.output.dataType); + assert_array_equals(output.shape(), test.output.dimensions); + } else { + assert_throws_js( + TypeError, () => builder.reshape(input, test.newShape)); + } + }, test.name)); diff --git a/testing/web-platform/tests/webnn/validation_tests/slice.https.any.js b/testing/web-platform/tests/webnn/validation_tests/slice.https.any.js index a45ecd3fcb..de42621610 100644 --- a/testing/web-platform/tests/webnn/validation_tests/slice.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/slice.https.any.js @@ -13,3 +13,69 @@ multi_builder_test(async (t, builder, otherBuilder) => { assert_throws_js( TypeError, () => builder.slice(inputFromOtherBuilder, starts, sizes)); }, '[slice] throw if input is from another builder'); + +const tests = [ + { + name: '[slice] Test with starts=[0, 1, 2] and sizes=[1, 2, 3].', + input: {dataType: 'float32', dimensions: [3, 4, 5]}, + starts: [0, 1, 2], + sizes: [1, 2, 3], + output: {dataType: 'float32', dimensions: [1, 2, 3]} + }, + { + name: '[slice] Throw if input is a scalar.', + input: {dataType: 'float32', dimensions: []}, + starts: [0], + sizes: [1] + }, + { + name: + '[slice] Throw if the length of sizes is not equal to the rank of the input tensor.', + input: {dataType: 'float32', dimensions: [3, 4, 5]}, + starts: [1, 2, 3], + sizes: [1, 1] + }, + { + name: + '[slice] Throw if the length of starts is not equal to the rank of the input tensor.', + input: {dataType: 'float32', dimensions: [3, 4, 5]}, + starts: [1, 2, 1, 3], + sizes: [1, 1, 1] + }, + { + name: + '[slice] Throw if the starting index is equal to or greater than input size in the same dimension.', + input: {dataType: 'float32', dimensions: [3, 4, 5]}, + starts: [0, 4, 4], + sizes: [1, 1, 1] + }, + { + name: '[slice] Throw if the number of elements to slice is equal to 0.', + input: {dataType: 'float32', dimensions: [3, 4, 5]}, + starts: [1, 2, 3], + sizes: [1, 0, 1] + }, + { + name: + '[slice] Throw if the ending index to slice is greater than input size in the same dimension.', + input: {dataType: 'float32', dimensions: [3, 4, 5]}, + starts: [0, 1, 2], + sizes: [3, 4, 1] + }, +]; + +tests.forEach( + test => promise_test(async t => { + const input = builder.input( + 'input', + {dataType: test.input.dataType, dimensions: test.input.dimensions}); + + if (test.output) { + const output = builder.slice(input, test.starts, test.sizes); + assert_equals(output.dataType(), test.output.dataType); + assert_array_equals(output.shape(), test.output.dimensions); + } else { + assert_throws_js( + TypeError, () => builder.slice(input, test.starts, test.sizes)); + } + }, test.name)); diff --git a/testing/web-platform/tests/webnn/validation_tests/softplus.https.any.js b/testing/web-platform/tests/webnn/validation_tests/softplus.https.any.js index 347dfcd938..3cf91d26ec 100644 --- a/testing/web-platform/tests/webnn/validation_tests/softplus.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/softplus.https.any.js @@ -5,3 +5,6 @@ 'use strict'; validateInputFromAnotherBuilder('softplus'); + +validateUnaryOperation( + 'softplus', floatingPointTypes, /*alsoBuildActivation=*/ true); diff --git a/testing/web-platform/tests/webnn/validation_tests/split.https.any.js b/testing/web-platform/tests/webnn/validation_tests/split.https.any.js index 38f3126603..6f7809744a 100644 --- a/testing/web-platform/tests/webnn/validation_tests/split.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/split.https.any.js @@ -12,3 +12,83 @@ multi_builder_test(async (t, builder, otherBuilder) => { assert_throws_js( TypeError, () => builder.split(inputFromOtherBuilder, splits)); }, '[split] throw if input is from another builder'); + +const tests = [ + { + name: '[split] Test with default options.', + input: {dataType: 'float32', dimensions: [2, 6]}, + splits: [2], + outputs: [ + {dataType: 'float32', dimensions: [2, 6]}, + ] + }, + { + name: + '[split] Test with a sequence of unsigned long splits and with options.axis = 1.', + input: {dataType: 'float32', dimensions: [2, 6]}, + splits: [1, 2, 3], + options: {axis: 1}, + outputs: [ + {dataType: 'float32', dimensions: [2, 1]}, + {dataType: 'float32', dimensions: [2, 2]}, + {dataType: 'float32', dimensions: [2, 3]}, + ] + }, + { + name: '[split] Throw if splitting a scalar.', + input: {dataType: 'float32', dimensions: []}, + splits: [2], + }, + { + name: '[split] Throw if axis is larger than input rank.', + input: {dataType: 'float32', dimensions: [2, 6]}, + splits: [2], + options: { + axis: 2, + } + }, + { + name: '[split] Throw if splits is equal to 0.', + input: {dataType: 'float32', dimensions: [2, 6]}, + splits: [0], + options: { + axis: 2, + } + }, + { + name: + '[split] Throw if the splits can not evenly divide the dimension size of input along options.axis.', + input: {dataType: 'float32', dimensions: [2, 5]}, + splits: [2], + options: { + axis: 1, + } + }, + { + name: + '[split] Throw if the sum of splits sizes not equal to the dimension size of input along options.axis.', + input: {dataType: 'float32', dimensions: [2, 6]}, + splits: [2, 2, 3], + options: { + axis: 1, + } + }, +]; + +tests.forEach( + test => promise_test(async t => { + const input = builder.input( + 'input', + {dataType: test.input.dataType, dimensions: test.input.dimensions}); + if (test.outputs) { + const outputs = builder.split(input, test.splits, test.options); + assert_equals(outputs.length, test.outputs.length); + for (let i = 0; i < outputs.length; ++i) { + assert_equals(outputs[i].dataType(), test.outputs[i].dataType); + assert_array_equals(outputs[i].shape(), test.outputs[i].dimensions); + } + } else { + assert_throws_js( + TypeError, () => builder.split(input, test.splits, test.options)); + } + }, test.name)); diff --git a/testing/web-platform/tests/webnn/validation_tests/transpose.https.any.js b/testing/web-platform/tests/webnn/validation_tests/transpose.https.any.js index 9ea5a5dcf8..3475a427d7 100644 --- a/testing/web-platform/tests/webnn/validation_tests/transpose.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/transpose.https.any.js @@ -5,3 +5,54 @@ 'use strict'; validateInputFromAnotherBuilder('transpose'); + +const tests = [ + { + name: '[transpose] Test building transpose with default options.', + input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + output: {dataType: 'float32', dimensions: [4, 3, 2, 1]} + }, + { + name: '[transpose] Test building transpose with permutation=[0, 2, 3, 1].', + input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + options: {permutation: [0, 2, 3, 1]}, + output: {dataType: 'float32', dimensions: [1, 3, 4, 2]} + }, + { + name: + '[transpose] Throw if permutation\'s size is not the same as input\'s rank.', + input: {dataType: 'int32', dimensions: [1, 2, 4]}, + options: {permutation: [0, 2, 3, 1]}, + }, + { + name: '[transpose] Throw if two values in permutation are same.', + input: {dataType: 'int32', dimensions: [1, 2, 3, 4]}, + options: {permutation: [0, 2, 3, 2]}, + }, + { + name: + '[transpose] Throw if any value in permutation is not in the range [0,input\'s rank).', + input: {dataType: 'int32', dimensions: [1, 2, 3, 4]}, + options: {permutation: [0, 1, 2, 4]}, + }, + { + name: '[transpose] Throw if any value in permutation is negative.', + input: {dataType: 'int32', dimensions: [1, 2, 3, 4]}, + options: {permutation: [0, -1, 2, 3]}, + } +]; + +tests.forEach( + test => promise_test(async t => { + const input = builder.input( + 'input', + {dataType: test.input.dataType, dimensions: test.input.dimensions}); + if (test.output) { + const output = builder.transpose(input, test.options); + assert_equals(output.dataType(), test.output.dataType); + assert_array_equals(output.shape(), test.output.dimensions); + } else { + assert_throws_js( + TypeError, () => builder.transpose(input, test.options)); + } + }, test.name)); |