From 77536499b10fe62088cb38026940f59c09b2fac0 Mon Sep 17 00:00:00 2001 From: Miao Bin Date: Tue, 23 Jul 2024 21:40:10 +0000 Subject: [PATCH] Bug 1909288 [wpt PR 47235] - WebNN: Change argMin/argMax to take scalar axis, a=testonly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Automatic update from web-platform-tests WebNN: Change argMin/argMax to take scalar axis This CL changes argMin/argMax to take scalar axis to align with the spec change [1]. The changes include the definition of IDL and mojo, the implementation of DirectML, TfLite and CoreML backend and the related unit tests and WPT tests. [1] https://github.com/webmachinelearning/webnn/pull/724 Bug: 352359898 Change-Id: Iee68b568331570a6ea51fd17b2195c602d4cff59 Cq-Include-Trybots: luci.chromium.try​:win11-blink-rel,mac14.arm64-blink-rel,mac14-blink-rel Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5721028 Reviewed-by: Alex Gough Reviewed-by: Phillis Tang Commit-Queue: Bin Miao Reviewed-by: ningxin hu Cr-Commit-Position: refs/heads/main@{#1331567} -- wpt-commits: acd785862cc0cd8a52e83ac6db95403e0e6e5450 wpt-pr: 47235 --- .../arg_min_max.https.any.js | 2 +- .../webnn/resources/test_data/arg_max.json | 430 +++------------ .../webnn/resources/test_data/arg_min.json | 520 +++++------------- .../tests/webnn/resources/utils.js | 10 + .../validation_tests/argMinMax.https.any.js | 126 ++--- 5 files changed, 249 insertions(+), 839 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 dd6cd6d9181abe..f309cdca4cf347 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 @@ -10,4 +10,4 @@ // https://webmachinelearning.github.io/webnn/#api-mlgraphbuilder-argminmax -runWebNNConformanceTests(['argMin', 'argMax'], buildOperationWithSingleInput); +runWebNNConformanceTests(['argMin', 'argMax'], buildArgMinMax); 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 d65939d0477b7c..a3995e4dd40f65 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 @@ -1,7 +1,7 @@ { "tests": [ { - "name": "argMax float32 1D constant tensor default options", + "name": "argMax float32 1D constant tensor, axis=0, default options", "inputs": { "input": { "shape": [24], @@ -35,6 +35,7 @@ "constant": true } }, + "axis": 0, "expected": { "name": "output", "shape": [], @@ -45,7 +46,7 @@ } }, { - "name": "argMax float32 1D tensor default options", + "name": "argMax float32 1D tensor, axis=0, default options", "inputs": { "input": { "shape": [24], @@ -78,6 +79,7 @@ "type": "float32" } }, + "axis": 0, "expected": { "name": "output", "shape": [], @@ -88,7 +90,7 @@ } }, { - "name": "argMax float32 2D tensor default options", + "name": "argMax float32 2D tensor, axis=0, default options", "inputs": { "input": { "shape": [4, 6], @@ -121,200 +123,26 @@ "type": "float32" } }, + "axis": 0, "expected": { "name": "output", - "shape": [], - "data": [ - 3 - ], - "type": "int32" - } - }, - { - "name": "argMax float32 3D tensor default options", - "inputs": { - "input": { - "shape": [2, 3, 4], - "data": [ - -51.0936194154457, - -6.5397018645619625, - 73.81338015899149, - 88.46114630531724, - -5.294266751122791, - -79.20668057325759, - -41.70176598864654, - 73.81338015899149, - 88.46114630531724, - -84.939998758247, - -61.488942502520906, - -98.33874402761955, - -51.0936194154457, - -6.5397018645619625, - 73.81338015899149, - 88.46114630531724, - -5.294266751122791, - -79.20668057325759, - -41.70176598864654, - 73.81338015899149, - 88.46114630531724, - -84.939998758247, - -61.488942502520906, - -98.33874402761955 - ], - "type": "float32" - } - }, - "expected": { - "name": "output", - "shape": [], - "data": [ - 3 - ], - "type": "int32" - } - }, - { - "name": "argMax float32 4D tensor default options", - "inputs": { - "input": { - "shape": [2, 1, 4, 3], - "data": [ - -51.0936194154457, - -6.5397018645619625, - 73.81338015899149, - 88.46114630531724, - -5.294266751122791, - -79.20668057325759, - -41.70176598864654, - 73.81338015899149, - 88.46114630531724, - -84.939998758247, - -61.488942502520906, - -98.33874402761955, - -51.0936194154457, - -6.5397018645619625, - 73.81338015899149, - 88.46114630531724, - -5.294266751122791, - -79.20668057325759, - -41.70176598864654, - 73.81338015899149, - 88.46114630531724, - -84.939998758247, - -61.488942502520906, - -98.33874402761955 - ], - "type": "float32" - } - }, - "expected": { - "name": "output", - "shape": [], - "data": [ - 3 - ], - "type": "int32" - } - }, - { - "name": "argMax float32 5D tensor default options", - "inputs": { - "input": { - "shape": [2, 1, 4, 1, 3], - "data": [ - -51.0936194154457, - -6.5397018645619625, - 73.81338015899149, - 88.46114630531724, - -5.294266751122791, - -79.20668057325759, - -41.70176598864654, - 73.81338015899149, - 88.46114630531724, - -84.939998758247, - -61.488942502520906, - -98.33874402761955, - -51.0936194154457, - -6.5397018645619625, - 73.81338015899149, - 88.46114630531724, - -5.294266751122791, - -79.20668057325759, - -41.70176598864654, - 73.81338015899149, - 88.46114630531724, - -84.939998758247, - -61.488942502520906, - -98.33874402761955 - ], - "type": "float32" - } - }, - "expected": { - "name": "output", - "shape": [], - "data": [ - 3 - ], - "type": "int32" - } - }, - { - "name": "argMax float32 4D tensor options.axes=[2]", - "inputs": { - "input": { - "shape": [2, 1, 4, 3], - "data": [ - -51.0936194154457, - -6.5397018645619625, - 73.81338015899149, - 88.46114630531724, - -5.294266751122791, - -79.20668057325759, - -41.70176598864654, - 73.81338015899149, - 88.46114630531724, - -84.939998758247, - -61.488942502520906, - -98.33874402761955, - -51.0936194154457, - -6.5397018645619625, - 73.81338015899149, - 88.46114630531724, - -5.294266751122791, - -79.20668057325759, - -41.70176598864654, - 73.81338015899149, - 88.46114630531724, - -84.939998758247, - -61.488942502520906, - -98.33874402761955 - ], - "type": "float32" - } - }, - "options": { - "axes": [2] - }, - "expected": { - "name": "output", - "shape": [2, 1, 3], + "shape": [6], "data": [ 1, - 2, - 2, 1, - 2, - 2 + 1, + 0, + 0, + 0 ], "type": "int32" } }, { - "name": "argMax float32 4D tensor options.axes=[]", + "name": "argMax float32 3D tensor, axis=0, default options", "inputs": { "input": { - "shape": [2, 1, 4, 3], + "shape": [2, 3, 4], "data": [ -51.0936194154457, -6.5397018645619625, @@ -344,25 +172,11 @@ "type": "float32" } }, - "options": { - "axes": [] - }, + "axis": 0, "expected": { "name": "output", - "shape": [2, 1, 4, 3], + "shape": [3, 4], "data": [ - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, 0, 0, 0, @@ -380,7 +194,7 @@ } }, { - "name": "argMax float32 4D tensor options.keepDimensions=true", + "name": "argMax float32 4D tensor, axis=0, default options", "inputs": { "input": { "shape": [2, 1, 4, 3], @@ -413,23 +227,32 @@ "type": "float32" } }, - "options": { - "keepDimensions": true - }, + "axis": 0, "expected": { "name": "output", - "shape": [1, 1, 1, 1], + "shape": [1, 4, 3], "data": [ - 3 + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 ], "type": "int32" } }, { - "name": "argMax float32 4D tensor options.keepDimensions=false", + "name": "argMax float32 5D tensor, axis=0, default options", "inputs": { "input": { - "shape": [2, 1, 4, 3], + "shape": [2, 1, 4, 1, 3], "data": [ -51.0936194154457, -6.5397018645619625, @@ -459,20 +282,29 @@ "type": "float32" } }, - "options": { - "keepDimensions": false - }, + "axis": 0, "expected": { "name": "output", - "shape": [], + "shape": [1, 4, 1, 3], "data": [ - 3 + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0, + 0 ], "type": "int32" } }, { - "name": "argMax float32 4D tensor options.axes=[0, 2] options.keepDimensions=false", + "name": "argMax float32 4D tensor axis=2", "inputs": { "input": { "shape": [2, 1, 4, 3], @@ -505,14 +337,14 @@ "type": "float32" } }, - "options": { - "axes": [0, 2], - "keepDimensions": false - }, + "axis": 2, "expected": { "name": "output", - "shape": [1, 3], + "shape": [2, 1, 3], "data": [ + 1, + 2, + 2, 1, 2, 2 @@ -521,7 +353,7 @@ } }, { - "name": "argMax float32 4D tensor options.axes=[3, 0, 1] options.keepDimensions=true", + "name": "argMax float32 4D tensor, axis=3, options.keepDimensions=true", "inputs": { "input": { "shape": [2, 1, 4, 3], @@ -554,111 +386,18 @@ "type": "float32" } }, + "axis": 3, "options": { - "axes": [3, 0, 1], "keepDimensions": true }, "expected": { "name": "output", - "shape": [1, 1, 4, 1], + "shape": [2, 1, 4, 1], "data": [ 2, 0, 2, - 1 - ], - "type": "int32" - } - }, - { - "name": "argMax float32 4D tensor options.axes=[0, 2]", - "inputs": { - "input": { - "shape": [2, 1, 4, 3], - "data": [ - -51.0936194154457, - -6.5397018645619625, - 73.81338015899149, - 88.46114630531724, - -5.294266751122791, - -79.20668057325759, - -41.70176598864654, - 73.81338015899149, - 88.46114630531724, - -84.939998758247, - -61.488942502520906, - -98.33874402761955, - -51.0936194154457, - -6.5397018645619625, - 73.81338015899149, - 88.46114630531724, - -5.294266751122791, - -79.20668057325759, - -41.70176598864654, - 73.81338015899149, - 88.46114630531724, - -84.939998758247, - -61.488942502520906, - -98.33874402761955 - ], - "type": "float32" - } - }, - "options": { - "axes": [0, 2] - }, - "expected": { - "name": "output", - "shape": [1, 3], - "data": [ 1, - 2, - 2 - ], - "type": "int32" - } - }, - { - "name": "argMax float32 4D tensor options.axes=[3, 0, 1]", - "inputs": { - "input": { - "shape": [2, 1, 4, 3], - "data": [ - -51.0936194154457, - -6.5397018645619625, - 73.81338015899149, - 88.46114630531724, - -5.294266751122791, - -79.20668057325759, - -41.70176598864654, - 73.81338015899149, - 88.46114630531724, - -84.939998758247, - -61.488942502520906, - -98.33874402761955, - -51.0936194154457, - -6.5397018645619625, - 73.81338015899149, - 88.46114630531724, - -5.294266751122791, - -79.20668057325759, - -41.70176598864654, - 73.81338015899149, - 88.46114630531724, - -84.939998758247, - -61.488942502520906, - -98.33874402761955 - ], - "type": "float32" - } - }, - "options": { - "axes": [3, 0, 1] - }, - "expected": { - "name": "output", - "shape": [4], - "data": [ 2, 0, 2, @@ -668,7 +407,7 @@ } }, { - "name": "argMax float32 4D tensor all options", + "name": "argMax float32 4D tensor, axis=3, options.keepDimensions=false", "inputs": { "input": { "shape": [2, 1, 4, 3], @@ -701,14 +440,18 @@ "type": "float32" } }, + "axis": 3, "options": { - "axes": [3, 0], - "keepDimensions": true + "keepDimensions": false }, "expected": { "name": "output", - "shape": [1, 1, 4, 1], + "shape": [2, 1, 4], "data": [ + 2, + 0, + 2, + 1, 2, 0, 2, @@ -716,53 +459,6 @@ ], "type": "int32" } - }, - { - "name": "argMax float32 0D scalar options.axes=[]", - "inputs": { - "input": { - "shape": [], - "data": [ - -51.0936194154457 - ], - "type": "float32" - } - }, - "options": { - "axes": [] - }, - "expected": { - "name": "output", - "shape": [], - "data": [ - 0 - ], - "type": "int32" - } - }, - { - "name": "argMax float32 0D scalar options.axes=[] no effect by keepDimensions being true", - "inputs": { - "input": { - "shape": [], - "data": [ - -51.0936194154457 - ], - "type": "float32" - } - }, - "options": { - "axes": [], - "keepDimensions": true - }, - "expected": { - "name": "output", - "shape": [], - "data": [ - 0 - ], - "type": "int32" - } } ] } \ No newline at end of file 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 f7b3f6d10d6239..a065873f5aa11e 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 @@ -1,10 +1,12 @@ { "tests": [ { - "name": "argMin float32 1D constant tensor default options", + "name": "argMin float32 1D constant tensor, axis 0, default options", "inputs": { "input": { - "shape": [24], + "shape": [ + 24 + ], "data": [ 3.830124090690262, -24.986487937638074, @@ -35,6 +37,7 @@ "constant": true } }, + "axis": 0, "expected": { "name": "output", "shape": [], @@ -45,10 +48,12 @@ } }, { - "name": "argMin float32 1D tensor default options", + "name": "argMin float32 1D tensor, axis 0, default options", "inputs": { "input": { - "shape": [24], + "shape": [ + 24 + ], "data": [ 3.830124090690262, -24.986487937638074, @@ -78,6 +83,7 @@ "type": "float32" } }, + "axis": 0, "expected": { "name": "output", "shape": [], @@ -88,10 +94,13 @@ } }, { - "name": "argMin float32 2D tensor default options", + "name": "argMin float32 2D tensor, axis 0, default options", "inputs": { "input": { - "shape": [4, 6], + "shape": [ + 4, + 6 + ], "data": [ 3.830124090690262, -24.986487937638074, @@ -121,20 +130,32 @@ "type": "float32" } }, + "axis": 0, "expected": { "name": "output", - "shape": [], + "shape": [ + 6 + ], "data": [ - 7 + 1, + 1, + 2, + 0, + 1, + 1 ], "type": "int32" } }, { - "name": "argMin float32 3D tensor default options", + "name": "argMin float32 3D tensor, axis 0, default options", "inputs": { "input": { - "shape": [2, 3, 4], + "shape": [ + 2, + 3, + 4 + ], "data": [ 3.830124090690262, -24.986487937638074, @@ -164,11 +185,26 @@ "type": "float32" } }, + "axis": 0, "expected": { "name": "output", - "shape": [], + "shape": [ + 3, + 4 + ], "data": [ - 7 + 1, + 1, + 1, + 0, + 0, + 0, + 0, + 0, + 1, + 0, + 0, + 0 ], "type": "int32" } @@ -177,50 +213,12 @@ "name": "argMin float32 4D tensor default options", "inputs": { "input": { - "shape": [2, 1, 4, 3], - "data": [ - 3.830124090690262, - -24.986487937638074, - 5.299982630691289, - -48.5486590218902, - 40.30886781808215, - 60.184293919409726, - -82.78385618759043, - -96.50904103637833, - 71.87028201591897, - 38.866394268784035, - -39.143725517854435, - 31.444366685561903, - -82.78385618759043, - -96.50904103637833, - -25.53388886326502, - -16.142265850469343, - 66.63677406472371, - 82.5119815304117, - -82.78385618759043, - -96.50904103637833, - 39.7687246127592, - 42.15040238450999, - 82.66863662444459, - 85.4526923278379 + "shape": [ + 2, + 1, + 4, + 3 ], - "type": "float32" - } - }, - "expected": { - "name": "output", - "shape": [], - "data": [ - 7 - ], - "type": "int32" - } - }, - { - "name": "argMin float32 5D tensor default options", - "inputs": { - "input": { - "shape": [2, 1, 4, 1, 3], "data": [ 3.830124090690262, -24.986487937638074, @@ -250,71 +248,42 @@ "type": "float32" } }, + "axis": 0, "expected": { "name": "output", - "shape": [], - "data": [ - 7 + "shape": [ + 1, + 4, + 3 ], - "type": "int32" - } - }, - { - "name": "argMin float32 4D tensor options.axes=[2]", - "inputs": { - "input": { - "shape": [2, 1, 4, 3], - "data": [ - 3.830124090690262, - -24.986487937638074, - 5.299982630691289, - -48.5486590218902, - 40.30886781808215, - 60.184293919409726, - -82.78385618759043, - -96.50904103637833, - 71.87028201591897, - 38.866394268784035, - -39.143725517854435, - 31.444366685561903, - -82.78385618759043, - -96.50904103637833, - -25.53388886326502, - -16.142265850469343, - 66.63677406472371, - 82.5119815304117, - -82.78385618759043, - -96.50904103637833, - 39.7687246127592, - 42.15040238450999, - 82.66863662444459, - 85.4526923278379 - ], - "type": "float32" - } - }, - "options": { - "axes": [2] - }, - "expected": { - "name": "output", - "shape": [2, 1, 3], "data": [ - 2, - 2, + 1, + 1, + 1, + 0, 0, 0, 0, + 0, + 1, + 0, + 0, 0 ], "type": "int32" } }, { - "name": "argMin float32 4D tensor options.axes=[]", + "name": "argMin float32 5D tensor default options", "inputs": { "input": { - "shape": [2, 1, 4, 3], + "shape": [ + 2, + 1, + 4, + 1, + 3 + ], "data": [ 3.830124090690262, -24.986487937638074, @@ -344,34 +313,25 @@ "type": "float32" } }, - "options": { - "axes": [] - }, + "axis": 0, "expected": { "name": "output", - "shape": [2, 1, 4, 3], + "shape": [ + 1, + 4, + 1, + 3 + ], "data": [ + 1, + 1, + 1, 0, 0, 0, 0, 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, - 0, + 1, 0, 0, 0 @@ -380,56 +340,15 @@ } }, { - "name": "argMin float32 4D tensor options.keepDimensions=true", + "name": "argMin float32 4D tensor, axis=2", "inputs": { "input": { - "shape": [2, 1, 4, 3], - "data": [ - 3.830124090690262, - -24.986487937638074, - 5.299982630691289, - -48.5486590218902, - 40.30886781808215, - 60.184293919409726, - -82.78385618759043, - -96.50904103637833, - 71.87028201591897, - 38.866394268784035, - -39.143725517854435, - 31.444366685561903, - -82.78385618759043, - -96.50904103637833, - -25.53388886326502, - -16.142265850469343, - 66.63677406472371, - 82.5119815304117, - -82.78385618759043, - -96.50904103637833, - 39.7687246127592, - 42.15040238450999, - 82.66863662444459, - 85.4526923278379 + "shape": [ + 2, + 1, + 4, + 3 ], - "type": "float32" - } - }, - "options": { - "keepDimensions": true - }, - "expected": { - "name": "output", - "shape": [1, 1, 1, 1], - "data": [ - 7 - ], - "type": "int32" - } - }, - { - "name": "argMin float32 4D tensor options.keepDimensions=false", - "inputs": { - "input": { - "shape": [2, 1, 4, 3], "data": [ 3.830124090690262, -24.986487937638074, @@ -459,72 +378,35 @@ "type": "float32" } }, - "options": { - "keepDimensions": false - }, + "axis": 2, "expected": { "name": "output", - "shape": [], - "data": [ - 7 + "shape": [ + 2, + 1, + 3 ], - "type": "int32" - } - }, - { - "name": "argMin float32 4D tensor options.axes=[0, 2] options.keepDimensions=false", - "inputs": { - "input": { - "shape": [2, 1, 4, 3], - "data": [ - 3.830124090690262, - -24.986487937638074, - 5.299982630691289, - -48.5486590218902, - 40.30886781808215, - 60.184293919409726, - -82.78385618759043, - -96.50904103637833, - 71.87028201591897, - 38.866394268784035, - -39.143725517854435, - 31.444366685561903, - -82.78385618759043, - -96.50904103637833, - -25.53388886326502, - -16.142265850469343, - 66.63677406472371, - 82.5119815304117, - -82.78385618759043, - -96.50904103637833, - 39.7687246127592, - 42.15040238450999, - 82.66863662444459, - 85.4526923278379 - ], - "type": "float32" - } - }, - "options": { - "axes": [0, 2], - "keepDimensions": false - }, - "expected": { - "name": "output", - "shape": [1, 3], "data": [ 2, 2, - 4 + 0, + 0, + 0, + 0 ], "type": "int32" } }, { - "name": "argMin float32 4D tensor options.axes=[3, 0, 1] options.keepDimensions=true", + "name": "argMin float32 4D tensor, axis=0, options.keepDimensions=true", "inputs": { "input": { - "shape": [2, 1, 4, 3], + "shape": [ + 2, + 1, + 4, + 3 + ], "data": [ 3.830124090690262, -24.986487937638074, @@ -554,75 +436,45 @@ "type": "float32" } }, + "axis": 0, "options": { - "axes": [3, 0, 1], "keepDimensions": true }, "expected": { "name": "output", - "shape": [1, 1, 4, 1], - "data": [ + "shape": [ + 1, + 1, 4, + 3 + ], + "data": [ + 1, + 1, + 1, + 0, + 0, + 0, + 0, 0, 1, - 1 + 0, + 0, + 0 ], "type": "int32" } }, { - "name": "argMin float32 4D tensor options.axes=[0, 2]", + "name": "argMin float32 4D tensor, axis=0, options.keepDimensions=false", "inputs": { "input": { - "shape": [2, 1, 4, 3], - "data": [ - 3.830124090690262, - -24.986487937638074, - 5.299982630691289, - -48.5486590218902, - 40.30886781808215, - 60.184293919409726, - -82.78385618759043, - -96.50904103637833, - 71.87028201591897, - 38.866394268784035, - -39.143725517854435, - 31.444366685561903, - -82.78385618759043, - -96.50904103637833, - -25.53388886326502, - -16.142265850469343, - 66.63677406472371, - 82.5119815304117, - -82.78385618759043, - -96.50904103637833, - 39.7687246127592, - 42.15040238450999, - 82.66863662444459, - 85.4526923278379 + "shape": [ + 2, + 1, + 4, + 3 ], - "type": "float32" - } - }, - "options": { - "axes": [0, 2] - }, - "expected": { - "name": "output", - "shape": [1, 3], - "data": [ - 2, - 2, - 4 - ], - "type": "int32" - } - }, - { - "name": "argMin float32 4D tensor options.axes=[3, 0, 1]", - "inputs": { - "input": { - "shape": [2, 1, 4, 3], "data": [ 3.830124090690262, -24.986487937638074, @@ -652,113 +504,29 @@ "type": "float32" } }, + "axis": 0, "options": { - "axes": [3, 0, 1] + "keepDimensions": false }, "expected": { "name": "output", - "shape": [4], - "data": [ - 4, - 0, + "shape": [ 1, - 1 + 4, + 3 ], - "type": "int32" - } - }, - { - "name": "argMin float32 4D tensor all options", - "inputs": { - "input": { - "shape": [2, 1, 4, 3], - "data": [ - 3.830124090690262, - -24.986487937638074, - 5.299982630691289, - -48.5486590218902, - 40.30886781808215, - 60.184293919409726, - -82.78385618759043, - -96.50904103637833, - 71.87028201591897, - 38.866394268784035, - -39.143725517854435, - 31.444366685561903, - -82.78385618759043, - -96.50904103637833, - -25.53388886326502, - -16.142265850469343, - 66.63677406472371, - 82.5119815304117, - -82.78385618759043, - -96.50904103637833, - 39.7687246127592, - 42.15040238450999, - 82.66863662444459, - 85.4526923278379 - ], - "type": "float32" - } - }, - "options": { - "axes": [3, 0], - "keepDimensions": true - }, - "expected": { - "name": "output", - "shape": [1, 1, 4, 1], "data": [ - 4, + 1, + 1, + 1, + 0, + 0, + 0, + 0, 0, 1, - 1 - ], - "type": "int32" - } - }, - { - "name": "argMin float32 0D scalar options.axes=[]", - "inputs": { - "input": { - "shape": [], - "data": [ - 3.830124090690262 - ], - "type": "float32" - } - }, - "options": { - "axes": [] - }, - "expected": { - "name": "output", - "shape": [], - "data": [ - 0 - ], - "type": "int32" - } - }, - { - "name": "argMin float32 0D scalar options.axes=[] no effect by keepDimensions being true", - "inputs": { - "input": { - "shape": [], - "data": [ - 3.830124090690262 - ], - "type": "float32" - } - }, - "options": { - "axes": [], - "keepDimensions": true - }, - "expected": { - "name": "output", - "shape": [], - "data": [ + 0, + 0, 0 ], "type": "int32" diff --git a/testing/web-platform/tests/webnn/resources/utils.js b/testing/web-platform/tests/webnn/resources/utils.js index 7f99e3e1593b39..8f5cb298d81d0b 100644 --- a/testing/web-platform/tests/webnn/resources/utils.js +++ b/testing/web-platform/tests/webnn/resources/utils.js @@ -800,6 +800,16 @@ const buildCast = (operationName, context, builder, resources) => { return namedOutputOperand; }; +const buildArgMinMax = (operationName, context, builder, resources) => { + // MLOperand argMin/argMax(MLOperand input, unsigned long axis, optional MLArgMinMaxOptions options = {}); + const namedOutputOperand = {}; + const inputOperand = createSingleInputOperand(context, builder, resources); + let argMinMaxOptions = {...resources.options}; + // invoke builder.argMin/argMax() + namedOutputOperand[resources.expected.name] = builder[operationName](inputOperand, resources.axis, argMinMaxOptions); + return namedOutputOperand; +}; + const buildConcat = (operationName, context, builder, resources) => { // MLOperand concat(sequence inputs, unsigned long axis); const namedOutputOperand = {}; diff --git a/testing/web-platform/tests/webnn/validation_tests/argMinMax.https.any.js b/testing/web-platform/tests/webnn/validation_tests/argMinMax.https.any.js index 2d7b286c8711c4..f6c568b95c7dd1 100644 --- a/testing/web-platform/tests/webnn/validation_tests/argMinMax.https.any.js +++ b/testing/web-platform/tests/webnn/validation_tests/argMinMax.https.any.js @@ -12,109 +12,44 @@ const kArgMinMaxOperators = [ const tests = [ { name: '[argMin/Max] Test with default options.', - input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, - output: {dimensions: []} + input: { dataType: 'float32', dimensions: [1, 2, 3, 4] }, + axis: 0, + output: { dimensions: [2, 3, 4] } }, { - name: '[argMin/Max] Test with axes=[].', - input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, - options: { - axes: [], - }, - output: {dimensions: [1, 2, 3, 4]} - }, - { - name: '[argMin/Max] Test scalar input with empty axes.', - input: {dataType: 'float32', dimensions: []}, - options: { - axes: [], - }, - output: {dimensions: []} - }, - { - name: '[argMin/Max] Test with axes=[1].', - input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, - options: { - axes: [1], - }, - output: {dimensions: [1, 3, 4]} - }, - { - name: '[argMin/Max] Test with axes=[1, 3] and keepDimensions=true.', - input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, - options: { - axes: [1, 3], - keepDimensions: true, - }, - output: {dimensions: [1, 1, 3, 1]} - }, - { - name: '[argMin/Max] Test with axes=[1, 3] and keepDimensions=false.', - input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, - options: { - axes: [1, 3], - keepDimensions: false, - }, - output: {dimensions: [1, 3]} - }, - { - name: '[argMin/Max] Test with axes=[1] and selectLastIndex=true.', - input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, - options: { - axes: [1], - selectLastIndex: true, - }, - output: {dimensions: [1, 3, 4]} + name: '[argMin/Max] Test with axes=1.', + input: { dataType: 'float32', dimensions: [1, 2, 3, 4] }, + axis: 1, + output: { dimensions: [1, 3, 4] } }, { - name: '[argMin/Max] Test with axes=[1] and selectLastIndex=false.', - input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + name: '[argMin/Max] Test with outputDataType=int32', + input: { dataType: 'float32', dimensions: [1, 2, 3, 4] }, + axis: 1, options: { - axes: [1], - selectLastIndex: false, + outputDataType: 'int32', }, - output: {dimensions: [1, 3, 4]} + output: { dimensions: [1, 3, 4] } }, { - name: - '[argMin/Max] Throw if the value in axes is greater than or equal to input rank.', - input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, + name: '[argMin/Max] Test with outputDataType=int64', + input: { dataType: 'float32', dimensions: [1, 2, 3, 4] }, + axis: 1, options: { - axes: [4], + outputDataType: 'int64', }, + output: { dimensions: [1, 3, 4] } }, { name: - '[argMin/Max] Throw if two or more values are same in the axes sequence.', - input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, - options: { - axes: [1, 1], - }, - }, - { - name: '[argMin/Max] Throw if input is a scalar and axes is non-empty.', - input: {dataType: 'float32', dimensions: []}, - options: { - axes: [1], - }, + '[argMin/Max] Throw if the value in axis is greater than or equal to input rank.', + input: { dataType: 'float32', dimensions: [1, 2, 3, 4] }, + axis: 4, }, { - name: '[argMin/Max] Test with outputDataType=int32', - input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, - options: { - axes: [1], - outputDataType: 'int32', - }, - output: {dimensions: [1, 3, 4]} - }, - { - name: '[argMin/Max] Test with outputDataType=int64', - input: {dataType: 'float32', dimensions: [1, 2, 3, 4]}, - options: { - axes: [1], - outputDataType: 'int64', - }, - output: {dimensions: [1, 3, 4]} + name: '[argMin/Max] Throw if input is a scalar and axis=0.', + input: { dataType: 'float32', dimensions: [] }, + axis: 0, }, ]; @@ -122,27 +57,28 @@ function runTests(operatorName, tests) { tests.forEach(test => { promise_test(async t => { const input = builder.input( - 'input', - {dataType: test.input.dataType, dimensions: test.input.dimensions}); + 'input', + { dataType: test.input.dataType, dimensions: test.input.dimensions }); + const axis = test.axis; if (test.options && test.options.outputDataType !== undefined) { if (context.opSupportLimits()[operatorName].output.dataTypes.includes( - test.options.outputDataType)) { - const output = builder[operatorName](input, test.options); + test.options.outputDataType)) { + const output = builder[operatorName](input, axis, test.options); assert_equals(output.dataType(), test.options.outputDataType); assert_array_equals(output.shape(), test.output.dimensions); } else { assert_throws_js( - TypeError, () => builder[operatorName](input, test.options)); + TypeError, () => builder[operatorName](input, axis, test.options)); } return; } if (test.output) { - const output = builder[operatorName](input, test.options); + const output = builder[operatorName](input, axis, test.options); assert_equals(output.dataType(), 'int32'); assert_array_equals(output.shape(), test.output.dimensions); } else { assert_throws_js( - TypeError, () => builder[operatorName](input, test.options)); + TypeError, () => builder[operatorName](input, axis, test.options)); } }, test.name.replace('[argMin/Max]', `[${operatorName}]`)); });