From b12b4412aa8863677e04f29d545079f244ab2238 Mon Sep 17 00:00:00 2001 From: Marco Castelluccio Date: Tue, 15 Oct 2024 10:11:21 +0000 Subject: [PATCH] Bug 1923533 [wpt PR 48533] - WebNN: Add IDL and mojo definitions for `logical[And|Or|Xor]` operators, a=testonly Automatic update from web-platform-tests WebNN: Add IDL and mojo definitions for `logical[And|Or|Xor]` operators The `logicalAnd`, `logicalOr`, and `logicalXor` operators are proposed by the WebNN WG [1]. These operators are required to support models that are commonly used. [1]: https://github.com/webmachinelearning/webnn/issues/375#issuecomment-2292466613 Bug: 368085623 Change-Id: I765e4f6787d01907c09e9c067426174a8f0cd240 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5883679 Reviewed-by: Weizhong Xia Reviewed-by: ningxin hu Commit-Queue: Patrick To Reviewed-by: Alex Gough Cr-Commit-Position: refs/heads/main{#1365998} -- wpt-commits: ccc114e8bb2f3f60c869efcf6601beaeccfe3b81 wpt-pr: 48533 UltraBlame original commit: 368c2768d1529619602104370c0a66d1f8015732 --- .../logical_and.https.any.js | 422 ++++++++++++++++++ .../conformance_tests/logical_or.https.any.js | 422 ++++++++++++++++++ .../logical_xor.https.any.js | 422 ++++++++++++++++++ .../elementwise-logical.https.any.js | 3 + 4 files changed, 1269 insertions(+) create mode 100644 testing/web-platform/tests/webnn/conformance_tests/logical_and.https.any.js create mode 100644 testing/web-platform/tests/webnn/conformance_tests/logical_or.https.any.js create mode 100644 testing/web-platform/tests/webnn/conformance_tests/logical_xor.https.any.js diff --git a/testing/web-platform/tests/webnn/conformance_tests/logical_and.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/logical_and.https.any.js new file mode 100644 index 000000000000..f1ada5bc8b28 --- /dev/null +++ b/testing/web-platform/tests/webnn/conformance_tests/logical_and.https.any.js @@ -0,0 +1,422 @@ + + + + + + + + +'use strict'; + + + +const logicalAndTests = [ + { + 'name': 'logicalAnd uint8 0D scalar', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [1], + 'descriptor': {shape: [], dataType: 'uint8'} + }, + 'inputB': { + 'data': [1], + 'descriptor': {shape: [], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalAnd', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': {'data': [1], 'descriptor': {shape: [], dataType: 'uint8'}} + } + } + }, + { + 'name': 'logicalAnd uint8 1D constant tensors', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [24], dataType: 'uint8'}, + 'constant': true + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [24], dataType: 'uint8'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'logicalAnd', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 + ], + 'descriptor': {shape: [24], dataType: 'uint8'} + } + } + } + }, + { + 'name': 'logicalAnd uint8 1D tensors', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [24], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [24], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalAnd', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 + ], + 'descriptor': {shape: [24], dataType: 'uint8'} + } + } + } + }, + { + 'name': 'logicalAnd uint8 2D tensors', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [4, 6], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [4, 6], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalAnd', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 + ], + 'descriptor': {shape: [4, 6], dataType: 'uint8'} + } + } + } + }, + { + 'name': 'logicalAnd uint8 3D tensors', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [2, 3, 4], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [2, 3, 4], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalAnd', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 + ], + 'descriptor': {shape: [2, 3, 4], dataType: 'uint8'} + } + } + } + }, + { + 'name': 'logicalAnd uint8 4D tensors', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalAnd', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + } + } + }, + { + 'name': 'logicalAnd uint8 5D tensors', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [2, 2, 1, 2, 3], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [2, 2, 1, 2, 3], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalAnd', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 + ], + 'descriptor': {shape: [2, 2, 1, 2, 3], dataType: 'uint8'} + } + } + } + }, + { + 'name': 'logicalAnd uint8 broadcast 0D to 4D', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [1], + 'descriptor': {shape: [], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalAnd', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + } + } + }, + { + 'name': 'logicalAnd uint8 broadcast 1D to 4D', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [1], + 'descriptor': {shape: [1], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalAnd', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + } + } + }, + { + 'name': 'logicalAnd uint8 broadcast 2D to 4D', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 255, 255 + ], + 'descriptor': {shape: [2, 3], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalAnd', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1, 1 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + } + } + }, + { + 'name': 'logicalAnd uint8 broadcast 3D to 4D', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 255 + ], + 'descriptor': {shape: [2, 2, 1], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalAnd', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + } + } + }, + { + 'name': 'logicalAnd uint8 broadcast 4D to 4D', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [1], + 'descriptor': {shape: [1, 1, 1, 1], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalAnd', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, + 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + } + } + } +]; + +if (navigator.ml) { + logicalAndTests.forEach((test) => { + webnn_conformance_test( + buildGraphAndCompute, getPrecisionTolerance, test); + }); +} else { + test(() => assert_implements(navigator.ml, 'missing navigator.ml')); +} diff --git a/testing/web-platform/tests/webnn/conformance_tests/logical_or.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/logical_or.https.any.js new file mode 100644 index 000000000000..2cb255547592 --- /dev/null +++ b/testing/web-platform/tests/webnn/conformance_tests/logical_or.https.any.js @@ -0,0 +1,422 @@ + + + + + + + + +'use strict'; + + + +const logicalOrTests = [ + { + 'name': 'logicalOr uint8 0D scalar', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [1], + 'descriptor': {shape: [], dataType: 'uint8'} + }, + 'inputB': { + 'data': [1], + 'descriptor': {shape: [], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalOr', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': {'data': [1], 'descriptor': {shape: [], dataType: 'uint8'}} + } + } + }, + { + 'name': 'logicalOr uint8 1D constant tensors', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [24], dataType: 'uint8'}, + 'constant': true + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [24], dataType: 'uint8'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'logicalOr', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 + ], + 'descriptor': {shape: [24], dataType: 'uint8'} + } + } + } + }, + { + 'name': 'logicalOr uint8 1D tensors', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [24], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [24], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalOr', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 + ], + 'descriptor': {shape: [24], dataType: 'uint8'} + } + } + } + }, + { + 'name': 'logicalOr uint8 2D tensors', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [4, 6], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [4, 6], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalOr', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 + ], + 'descriptor': {shape: [4, 6], dataType: 'uint8'} + } + } + } + }, + { + 'name': 'logicalOr uint8 3D tensors', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [2, 3, 4], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [2, 3, 4], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalOr', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 + ], + 'descriptor': {shape: [2, 3, 4], dataType: 'uint8'} + } + } + } + }, + { + 'name': 'logicalOr uint8 4D tensors', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalOr', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + } + } + }, + { + 'name': 'logicalOr uint8 5D tensors', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [2, 2, 1, 2, 3], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [2, 2, 1, 2, 3], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalOr', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 + ], + 'descriptor': {shape: [2, 2, 1, 2, 3], dataType: 'uint8'} + } + } + } + }, + { + 'name': 'logicalOr uint8 broadcast 0D to 4D', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [1], + 'descriptor': {shape: [], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalOr', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + } + } + }, + { + 'name': 'logicalOr uint8 broadcast 1D to 4D', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [1], + 'descriptor': {shape: [1], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalOr', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + } + } + }, + { + 'name': 'logicalOr uint8 broadcast 2D to 4D', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 255, 255 + ], + 'descriptor': {shape: [2, 3], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalOr', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, + 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + } + } + }, + { + 'name': 'logicalOr uint8 broadcast 3D to 4D', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 255 + ], + 'descriptor': {shape: [2, 2, 1], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalOr', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, + 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + } + } + }, + { + 'name': 'logicalOr uint8 broadcast 4D to 4D', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [1], + 'descriptor': {shape: [1, 1, 1, 1], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalOr', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + } + } + } +]; + +if (navigator.ml) { + logicalOrTests.forEach((test) => { + webnn_conformance_test( + buildGraphAndCompute, getPrecisionTolerance, test); + }); +} else { + test(() => assert_implements(navigator.ml, 'missing navigator.ml')); +} diff --git a/testing/web-platform/tests/webnn/conformance_tests/logical_xor.https.any.js b/testing/web-platform/tests/webnn/conformance_tests/logical_xor.https.any.js new file mode 100644 index 000000000000..b2196a4a068d --- /dev/null +++ b/testing/web-platform/tests/webnn/conformance_tests/logical_xor.https.any.js @@ -0,0 +1,422 @@ + + + + + + + + +'use strict'; + + + +const logicalXorTests = [ +{ + 'name': 'logicalXor uint8 0D scalar', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [1], + 'descriptor': {shape: [], dataType: 'uint8'} + }, + 'inputB': { + 'data': [1], + 'descriptor': {shape: [], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalXor', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': {'data': [1], 'descriptor': {shape: [], dataType: 'uint8'}} + } + } +}, +{ + 'name': 'logicalXor uint8 1D constant tensors', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [24], dataType: 'uint8'}, + 'constant': true + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [24], dataType: 'uint8'}, + 'constant': true + } + }, + 'operators': [{ + 'name': 'logicalXor', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0 + ], + 'descriptor': {shape: [24], dataType: 'uint8'} + } + } + } +}, +{ + 'name': 'logicalXor uint8 1D tensors', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [24], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [24], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalXor', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0 + ], + 'descriptor': {shape: [24], dataType: 'uint8'} + } + } + } +}, +{ + 'name': 'logicalXor uint8 2D tensors', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [4, 6], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [4, 6], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalXor', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0 + ], + 'descriptor': {shape: [4, 6], dataType: 'uint8'} + } + } + } +}, +{ + 'name': 'logicalXor uint8 3D tensors', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [2, 3, 4], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [2, 3, 4], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalXor', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0 + ], + 'descriptor': {shape: [2, 3, 4], dataType: 'uint8'} + } + } + } +}, +{ + 'name': 'logicalXor uint8 4D tensors', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalXor', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + } + } +}, +{ + 'name': 'logicalXor uint8 5D tensors', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [2, 2, 1, 2, 3], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [2, 2, 1, 2, 3], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalXor', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0 + ], + 'descriptor': {shape: [2, 2, 1, 2, 3], dataType: 'uint8'} + } + } + } +}, +{ + 'name': 'logicalXor uint8 broadcast 0D to 4D', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [1], + 'descriptor': {shape: [], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalXor', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + } + } +}, +{ + 'name': 'logicalXor uint8 broadcast 1D to 4D', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [1], + 'descriptor': {shape: [1], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalXor', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + } + } +}, +{ + 'name': 'logicalXor uint8 broadcast 2D to 4D', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 255, 255 + ], + 'descriptor': {shape: [2, 3], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalXor', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0, + 0, 1, 1, 0, 1, 1, 1, 0, 0, 1, 0, 0 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + } + } +}, +{ + 'name': 'logicalXor uint8 broadcast 3D to 4D', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [ + 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 8, 8, + 0, 0, 8, 8, 0, 0, 255, 255, 0, 0, 255, 255 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 255 + ], + 'descriptor': {shape: [2, 2, 1], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalXor', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, + 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + } + } +}, +{ + 'name': 'logicalXor uint8 broadcast 4D to 4D', + 'graph': { + 'inputs': { + 'inputA': { + 'data': [1], + 'descriptor': {shape: [1, 1, 1, 1], dataType: 'uint8'} + }, + 'inputB': { + 'data': [ + 0, 1, 0, 1, 0, 2, 0, 2, 0, 8, 0, 8, + 0, 2, 0, 2, 0, 255, 0, 255, 0, 8, 0, 8 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + }, + 'operators': [{ + 'name': 'logicalXor', + 'arguments': [{'a': 'inputA'}, {'b': 'inputB'}], + 'outputs': 'output' + }], + 'expectedOutputs': { + 'output': { + 'data': [ + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, + 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0 + ], + 'descriptor': {shape: [2, 2, 2, 3], dataType: 'uint8'} + } + } + } +} +]; + +if (navigator.ml) { +logicalXorTests.forEach((test) => { + webnn_conformance_test( + buildGraphAndCompute, getPrecisionTolerance, test); +}); +} else { +test(() => assert_implements(navigator.ml, 'missing navigator.ml')); +} diff --git a/testing/web-platform/tests/webnn/validation_tests/elementwise-logical.https.any.js b/testing/web-platform/tests/webnn/validation_tests/elementwise-logical.https.any.js index 9a0255d6b351..515e1cb1ad31 100644 --- a/testing/web-platform/tests/webnn/validation_tests/elementwise-logical.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/elementwise-logical.https.any.js @@ -13,6 +13,9 @@ const kElementwiseLogicalBinaryOperators = [ 'greaterOrEqual', 'lesser', 'lesserOrEqual', + 'logicalAnd', + 'logicalOr', + 'logicalXor', ]; const label = 'elementwise_logic_op';