From d584e9246e5cf3e7c4a4d011ba46a3dc51ea9c5b Mon Sep 17 00:00:00 2001 From: Shiyi Zou Date: Tue, 5 Nov 2024 21:45:41 -0800 Subject: [PATCH] webnn: support strides for slice operator To fix the spec issue: https://github.com/webmachinelearning/webnn/issues/772 Bug: 376071284 Change-Id: I51dec37ce9a606941be3810ef0fd7b9e66edfef2 Cq-Include-Trybots: luci.chromium.try:win11-blink-rel, mac14.arm64-blink-rel, mac14-blink-rel, mac15.arm64-blink-rel, mac15-blink-rel, linux-blink-rel Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/5975313 Commit-Queue: Shiyi Zou Reviewed-by: ningxin hu Auto-Submit: Shiyi Zou Reviewed-by: Alex Gough Cr-Commit-Position: refs/heads/main@{#1378794} --- webnn/conformance_tests/slice.https.any.js | 108 +++++++++++++++++++++ webnn/validation_tests/slice.https.any.js | 21 +++- 2 files changed, 128 insertions(+), 1 deletion(-) diff --git a/webnn/conformance_tests/slice.https.any.js b/webnn/conformance_tests/slice.https.any.js index 58604d2b8ebf92..27ac1c265729ca 100644 --- a/webnn/conformance_tests/slice.https.any.js +++ b/webnn/conformance_tests/slice.https.any.js @@ -238,6 +238,114 @@ const sliceTests = [ } } } + }, + { + 'name': 'slice float32 2D tensor with strides', + 'graph': { + 'inputs': { + 'sliceInput': { + 'data': [ + 28.846250534057617, 97.95414733886719, -68.15961456298828, + 14.978987693786621, 90.23090362548828, 76.59095764160156, + -24.556316375732422, 79.58749389648438, 65.21376037597656, + 57.4397087097168, 74.41775512695312, -4.513182163238525, + 0.5424534678459167, 80.44634246826172, 28.32765007019043, + 74.02619171142578, -74.54559326171875, -27.306041717529297, + -70.42774200439453, 59.82632064819336, -58.46095275878906, + 79.80570983886719, -70.42774200439453, 42.665199279785156 + ], + 'descriptor': {shape: [2, 12], dataType: 'float32'} + } + }, + 'operators': [{ + 'name': 'slice', + 'arguments': [ + {'input': 'sliceInput'}, {'starts': [0, 2]}, {'sizes': [2, 10]}, + {'options': {'strides': [1, 4]}} + ], + 'outputs': 'sliceOutput' + }], + 'expectedOutputs': { + 'sliceOutput': { + 'data': [ + -68.15961456298828, -24.556316375732422, 74.41775512695312, + 28.32765007019043, -70.42774200439453, -70.42774200439453 + ], + 'descriptor': {shape: [2, 3], dataType: 'float32'} + } + } + } + }, + { + 'name': 'slice float32 3D tensor with strides', + 'graph': { + 'inputs': { + 'sliceInput': { + 'data': [ + 28.846250534057617, 97.95414733886719, -68.15961456298828, + 14.978987693786621, 90.23090362548828, 76.59095764160156, + -24.556316375732422, 79.58749389648438, 65.21376037597656, + 57.4397087097168, 74.41775512695312, -4.513182163238525, + 0.5424534678459167, 80.44634246826172, 28.32765007019043, + 74.02619171142578, -74.54559326171875, -27.306041717529297, + -70.42774200439453, 59.82632064819336, -58.46095275878906, + 79.80570983886719, -9.857853889465332, 42.665199279785156 + ], + 'descriptor': {shape: [4, 3, 2], dataType: 'float32'} + } + }, + 'operators': [{ + 'name': 'slice', + 'arguments': [ + {'input': 'sliceInput'}, {'starts': [0, 0, 1]}, {'sizes': [4, 3, 1]}, + {'options': {'strides': [3, 2, 1]}} + ], + 'outputs': 'sliceOutput' + }], + 'expectedOutputs': { + 'sliceOutput': { + 'data': [ + 97.95414733886719, 76.59095764160156, 59.82632064819336, + 42.665199279785156 + ], + 'descriptor': {shape: [2, 2, 1], dataType: 'float32'} + } + } + } + }, + { + 'name': 'slice float32 4D tensor with strides', + 'graph': { + 'inputs': { + 'sliceInput': { + 'data': [ + 28.846250534057617, 97.95414733886719, -68.15961456298828, + 14.978987693786621, 90.23090362548828, 76.59095764160156, + -24.556316375732422, 79.58749389648438, 65.21376037597656, + 57.4397087097168, 74.41775512695312, -4.513182163238525, + 0.5424534678459167, 80.44634246826172, 28.32765007019043, + 74.02619171142578, -74.54559326171875, -27.306041717529297, + -70.42774200439453, 59.82632064819336, -58.46095275878906, + 79.80570983886719, -9.857853889465332, 42.665199279785156 + ], + 'descriptor': {shape: [2, 2, 3, 2], dataType: 'float32'} + } + }, + 'operators': [{ + 'name': 'slice', + 'arguments': [ + {'input': 'sliceInput'}, {'starts': [1, 1, 1, 1]}, + {'sizes': [1, 1, 1, 1]}, {'options': {'strides': [2, 2, 2, 2]}} + ], + 'outputs': 'sliceOutput' + }], + 'expectedOutputs': { + 'sliceOutput': { + 'data': [79.80570983886719], + 'descriptor': {shape: [1, 1, 1, 1], dataType: 'float32'} + } + } + } } ]; diff --git a/webnn/validation_tests/slice.https.any.js b/webnn/validation_tests/slice.https.any.js index cc442d3d2b1958..321ebd9cbaffd9 100644 --- a/webnn/validation_tests/slice.https.any.js +++ b/webnn/validation_tests/slice.https.any.js @@ -65,12 +65,31 @@ const tests = [ starts: [0, 1, 2], sizes: [3, 4, 1] }, + { + name: + '[slice] Throw if the length of strides is not equal to the rank of the input tensor.', + input: {dataType: 'float32', shape: [3, 4, 5]}, + starts: [1, 2, 3], + sizes: [1, 1, 1], + strides: [1, 1, 1, 1] + }, + { + name: '[slice] Throw if the strides are less than 1.', + input: {dataType: 'float32', shape: [3, 4, 5]}, + starts: [1, 2, 3], + sizes: [1, 1, 1], + strides: [0, 0, 0] + } ]; tests.forEach( test => promise_test(async t => { const builder = new MLGraphBuilder(context); const input = builder.input('input', test.input); + const options = {}; + if (test.strides) { + options.strides = test.strides; + } if (test.output) { const output = builder.slice(input, test.starts, test.sizes); @@ -78,7 +97,7 @@ tests.forEach( assert_array_equals(output.shape, test.output.shape); } else { const label = 'slice_xxx'; - const options = {label}; + options.label = label; const regrexp = new RegExp('\\[' + label + '\\]'); assert_throws_with_label( () => builder.slice(input, test.starts, test.sizes, options),