From e59ae4b68abffe2cd1d757e1b1575e35f526b048 Mon Sep 17 00:00:00 2001 From: Shiyi Zou Date: Fri, 1 Nov 2024 12:40:04 +0800 Subject: [PATCH 1/3] strided slice --- js/web/docs/webnn-operators.md | 2 +- js/web/test/suite-test-list.jsonc | 16 +++++++------- .../webnn/builders/impl/slice_op_builder.cc | 21 ++++++++++++------- 3 files changed, 22 insertions(+), 17 deletions(-) diff --git a/js/web/docs/webnn-operators.md b/js/web/docs/webnn-operators.md index 2293de8d55d98..801d0d5f110a5 100644 --- a/js/web/docs/webnn-operators.md +++ b/js/web/docs/webnn-operators.md @@ -90,7 +90,7 @@ operators and the supported opset domain/versions in **WebNN EP** by ONNX Runtim | Softplus | ai.onnx(7+) | softplus | ✓ | ✓ | | | Softsign | ai.onnx(7+) | softsign | ✓ | ✓ | | | Sin | ai.onnx(7+) | sin | ✓ | ✓ | | -| Slice | ai.onnx(7-9, 10, 11-12, 13+) | slice | ✓ | ✓ | Input 'starts', 'ends', 'axes', and 'steps' if present must be a constant, only supports 'steps' value 1 | +| Slice | ai.onnx(7-9, 10, 11-12, 13+) | slice | ✓ | ✓ | Input 'starts', 'ends', 'axes', and 'steps' if present must be a constant, only supports 'steps' value >= 1 | | Softmax | ai.onnx(7-10, 11-12, 13+) | softmax | ✓ | ✓ | | | Split | ai.onnx(7-10, 11-12, 13-17, 18+) | split | ✓ | ✓ | Input 'split' if present should be a constant | | Sqrt | ai.onnx(7-12, 13+) | sqrt | ✓ | ✓ | | diff --git a/js/web/test/suite-test-list.jsonc b/js/web/test/suite-test-list.jsonc index fc1dbd1f2083c..966a1ddef3424 100644 --- a/js/web/test/suite-test-list.jsonc +++ b/js/web/test/suite-test-list.jsonc @@ -2362,14 +2362,14 @@ // "test_sinh", // // "test_size_example", // // "test_size", - // "test_slice_default_axes", - // "test_slice_default_steps", - // "test_slice_end_out_of_bounds", - // "test_slice_neg_steps", - // "test_slice_neg", - // "test_slice_negative_axes", - // "test_slice_start_out_of_bounds", - // "test_slice", + "test_slice_default_axes", + "test_slice_default_steps", + "test_slice_end_out_of_bounds", + "test_slice_neg_steps", + "test_slice_neg", + "test_slice_negative_axes", + "test_slice_start_out_of_bounds", + "test_slice", // "test_softmax_axis_0_expanded", "test_softmax_axis_0", // "test_softmax_axis_1_expanded", diff --git a/onnxruntime/core/providers/webnn/builders/impl/slice_op_builder.cc b/onnxruntime/core/providers/webnn/builders/impl/slice_op_builder.cc index 3f0d633ac888b..33550f3c87885 100644 --- a/onnxruntime/core/providers/webnn/builders/impl/slice_op_builder.cc +++ b/onnxruntime/core/providers/webnn/builders/impl/slice_op_builder.cc @@ -52,6 +52,7 @@ Status SliceOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, emscripten::val inputs = model_builder.GetOperand(input_defs[0]->Name()); std::vector starts(rank); std::vector sizes(rank); + std::vector steps(rank); // Copy the data from the starts/ends/axes/steps initializers. std::vector input_starts; @@ -94,8 +95,11 @@ Status SliceOpBuilder::AddToModelBuilderImpl(ModelBuilder& model_builder, std::transform(compute_metadata.ends_.cbegin(), compute_metadata.ends_.cend(), compute_metadata.starts_.cbegin(), sizes.begin(), [](int64_t i, int64_t j) { return SafeInt(i - j); }); + std::transform(compute_metadata.steps_.cbegin(), compute_metadata.steps_.cend(), steps.begin(), + [](int64_t i) { return SafeInt(i); }); emscripten::val options = emscripten::val::object(); + options.set("strides", emscripten::val::array(steps)); options.set("label", node.Name()); emscripten::val output = model_builder.GetBuilder().call("slice", inputs, emscripten::val::array(starts), @@ -144,18 +148,19 @@ bool SliceOpBuilder::IsOpSupportedImpl(const InitializedTensorSet& initializers, return false; } const auto data_type = steps_tensor.data_type(); - // WebNN doesn't support steps other than 1. + // WebNN doesn't support steps less than 1. if (data_type == ONNX_NAMESPACE::TensorProto_DataType_INT64) { - if (!std::all_of(reinterpret_cast(unpacked_tensor.data()), - reinterpret_cast(unpacked_tensor.data() + unpacked_tensor.size()), - [](int64_t i) { return i == 1; })) { + if (std::any_of(reinterpret_cast(unpacked_tensor.data()), + reinterpret_cast(unpacked_tensor.data() + unpacked_tensor.size()), + [](int64_t i) { return i < 1; })) { + LOGS(logger, VERBOSE) << "WebNN slice doesn's support steps less than 1"; return false; } } else if (data_type == ONNX_NAMESPACE::TensorProto_DataType_INT32) { - if (!std::all_of(reinterpret_cast(unpacked_tensor.data()), - reinterpret_cast(unpacked_tensor.data()) + - unpacked_tensor.size() / sizeof(int32_t), - [](int32_t i) { return i == 1; })) { + if (std::any_of(reinterpret_cast(unpacked_tensor.data()), + reinterpret_cast(unpacked_tensor.data()) + unpacked_tensor.size() / sizeof(int32_t), + [](int32_t i) { return i < 1; })) { + LOGS(logger, VERBOSE) << "WebNN slice doesn's support steps less than 1"; return false; } } From c0dbc784fe395a2af5fe04451d1d7b862b51f1b6 Mon Sep 17 00:00:00 2001 From: shiyi Date: Fri, 8 Nov 2024 08:54:41 +0800 Subject: [PATCH 2/3] Update onnxruntime/core/providers/webnn/builders/impl/slice_op_builder.cc Co-authored-by: Wanming Lin --- .../core/providers/webnn/builders/impl/slice_op_builder.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onnxruntime/core/providers/webnn/builders/impl/slice_op_builder.cc b/onnxruntime/core/providers/webnn/builders/impl/slice_op_builder.cc index 33550f3c87885..0321b55cecdc5 100644 --- a/onnxruntime/core/providers/webnn/builders/impl/slice_op_builder.cc +++ b/onnxruntime/core/providers/webnn/builders/impl/slice_op_builder.cc @@ -160,7 +160,7 @@ bool SliceOpBuilder::IsOpSupportedImpl(const InitializedTensorSet& initializers, if (std::any_of(reinterpret_cast(unpacked_tensor.data()), reinterpret_cast(unpacked_tensor.data()) + unpacked_tensor.size() / sizeof(int32_t), [](int32_t i) { return i < 1; })) { - LOGS(logger, VERBOSE) << "WebNN slice doesn's support steps less than 1"; + LOGS(logger, VERBOSE) << "WebNN slice doesn't support steps less than 1"; return false; } } From b795f9a59ddbe6b6c0418e2324857532f41522cb Mon Sep 17 00:00:00 2001 From: shiyi Date: Fri, 8 Nov 2024 08:54:48 +0800 Subject: [PATCH 3/3] Update onnxruntime/core/providers/webnn/builders/impl/slice_op_builder.cc Co-authored-by: Wanming Lin --- .../core/providers/webnn/builders/impl/slice_op_builder.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onnxruntime/core/providers/webnn/builders/impl/slice_op_builder.cc b/onnxruntime/core/providers/webnn/builders/impl/slice_op_builder.cc index 0321b55cecdc5..78ec0acdfbd9f 100644 --- a/onnxruntime/core/providers/webnn/builders/impl/slice_op_builder.cc +++ b/onnxruntime/core/providers/webnn/builders/impl/slice_op_builder.cc @@ -153,7 +153,7 @@ bool SliceOpBuilder::IsOpSupportedImpl(const InitializedTensorSet& initializers, if (std::any_of(reinterpret_cast(unpacked_tensor.data()), reinterpret_cast(unpacked_tensor.data() + unpacked_tensor.size()), [](int64_t i) { return i < 1; })) { - LOGS(logger, VERBOSE) << "WebNN slice doesn's support steps less than 1"; + LOGS(logger, VERBOSE) << "WebNN slice doesn't support steps less than 1"; return false; } } else if (data_type == ONNX_NAMESPACE::TensorProto_DataType_INT32) {