diff --git a/onnxruntime/core/providers/webgpu/tensor/scatter_nd.cc b/onnxruntime/core/providers/webgpu/tensor/scatter_nd.cc index f13e86c185928..9f07e2d2a3988 100644 --- a/onnxruntime/core/providers/webgpu/tensor/scatter_nd.cc +++ b/onnxruntime/core/providers/webgpu/tensor/scatter_nd.cc @@ -146,24 +146,24 @@ Status ScatterND::ComputeInternal(ComputeContext& context) const { const auto* updates = context.Input(2); const auto& input_shape = input->Shape(); const auto& indices_shape = indices->Shape(); - auto indices_rank = indices_shape.NumDimensions(); - auto last_index_dimension = static_cast(indices_shape[indices_rank - 1]); - auto num_updates_elements = static_cast(input_shape.SizeFromDimension(last_index_dimension)); - // TODO: support bool with components 4. - const size_t components = 1; - auto output_size = static_cast((indices_shape.SizeToDimension(indices_rank - 1) + components - 1) / components); auto* output = context.Output(0, input_shape); - if (output_size == 0) { - // If the output tensor is empty, we can return early. - return Status::OK(); - } - MLDataType data_type = input->DataType(); const void* source = input->DataRaw(); void* target = output->MutableDataRaw(); // If source and target pointers are not equal (non-inplace operation), we need to copy the data. if (target != source) { ORT_RETURN_IF_ERROR(Info().GetDataTransferManager().CopyTensor(*input, *output)); } + if (indices_shape.Size() == 0) { + // If the indices are empty, we can return early. + return Status::OK(); + } + auto indices_rank = indices_shape.NumDimensions(); + auto last_index_dimension = static_cast(indices_shape[indices_rank - 1]); + auto num_updates_elements = static_cast(input_shape.SizeFromDimension(last_index_dimension)); + // TODO: support bool with components 4. + const size_t components = 1; + auto output_size = static_cast((indices_shape.SizeToDimension(indices_rank - 1) + components - 1) / components); + MLDataType data_type = input->DataType(); ScatterNDProgram program(reduction_, data_type); program .CacheHint(static_cast(reduction_)) diff --git a/onnxruntime/test/providers/cpu/tensor/scatter_nd_op_test.cc b/onnxruntime/test/providers/cpu/tensor/scatter_nd_op_test.cc index 895c8ab3e53e4..e6d113e1e4dca 100644 --- a/onnxruntime/test/providers/cpu/tensor/scatter_nd_op_test.cc +++ b/onnxruntime/test/providers/cpu/tensor/scatter_nd_op_test.cc @@ -235,5 +235,16 @@ TEST(ScatterNDOpTest, ScatterND_18_max) { test1.Run(OpTester::ExpectResult::kExpectSuccess, "", {kTensorrtExecutionProvider, kOpenVINOExecutionProvider}); } +// Test for ScatterND with empty indices - output should be same as input +TEST(ScatterNDOpTest, ScatterND_empty_indices) { + // Test with float data type and minimal empty case + OpTester test1("ScatterND", 11); + test1.AddInput("data", {2, 3}, {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}); + test1.AddInput("indices", {0, 1}, {}); // Empty indices tensor - no indices to process + test1.AddInput("updates", {0, 3}, {}); // Empty updates tensor + test1.AddOutput("output", {2, 3}, {1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f}); // Same as input + test1.Run(OpTester::ExpectResult::kExpectSuccess, "", {kDmlExecutionProvider}); +} + } // namespace test } // namespace onnxruntime