From a83029a7820dbb9cc90b8104348bbe0d2841430e Mon Sep 17 00:00:00 2001 From: youge325 Date: Sat, 30 May 2026 19:32:57 +0800 Subject: [PATCH 01/10] $(cat < EOF ) --- test/ATen/ops/ScatterReduceTest.cpp | 420 ++++++++++++++++++++++++++++ 1 file changed, 420 insertions(+) create mode 100644 test/ATen/ops/ScatterReduceTest.cpp diff --git a/test/ATen/ops/ScatterReduceTest.cpp b/test/ATen/ops/ScatterReduceTest.cpp new file mode 100644 index 0000000..21d3039 --- /dev/null +++ b/test/ATen/ops/ScatterReduceTest.cpp @@ -0,0 +1,420 @@ +#include +#include +#include + +#include +#include + +#include "src/file_manager.h" + +extern paddle_api_test::ThreadSafeParam g_custom_param; + +namespace at { +namespace test { + +using paddle_api_test::FileManerger; + +class ScatterReduceTest : public ::testing::Test { + protected: + void SetUp() override {} +}; + +static void write_scatter_reduce_result_to_file(FileManerger* file, + const at::Tensor& result) { + *file << std::to_string(result.dim()) << " "; + *file << std::to_string(result.numel()) << " "; + for (int64_t i = 0; i < result.dim(); ++i) { + *file << std::to_string(result.sizes()[i]) << " "; + } + if (result.numel() == 0) { + *file << "empty "; + return; + } + at::Tensor cont = result.contiguous(); + if (cont.scalar_type() == c10::ScalarType::Float) { + float* data = cont.data_ptr(); + *file << std::to_string(data[0]) << " "; + *file << std::to_string(data[cont.numel() - 1]) << " "; + *file << std::to_string(cont.sum().item()) << " "; + } else if (cont.scalar_type() == c10::ScalarType::Double) { + double* data = cont.data_ptr(); + *file << std::to_string(data[0]) << " "; + *file << std::to_string(data[cont.numel() - 1]) << " "; + *file << std::to_string(cont.sum().item()) << " "; + } else if (cont.scalar_type() == c10::ScalarType::Int) { + int* data = cont.data_ptr(); + *file << std::to_string(data[0]) << " "; + *file << std::to_string(data[cont.numel() - 1]) << " "; + *file << std::to_string(cont.sum().item()) << " "; + } else if (cont.scalar_type() == c10::ScalarType::Long) { + int64_t* data = cont.data_ptr(); + *file << std::to_string(data[0]) << " "; + *file << std::to_string(data[cont.numel() - 1]) << " "; + *file << std::to_string(cont.sum().item()) << " "; + } +} + +static at::Tensor make_index_1x5() { + at::Tensor index = at::zeros({1, 5}, at::kLong); + index.data_ptr()[0] = 0; + index.data_ptr()[1] = 1; + index.data_ptr()[2] = 2; + index.data_ptr()[3] = 0; + index.data_ptr()[4] = 0; + return index; +} + +// Shape: small 2D, Dtype: kFloat, Reduce: sum +TEST_F(ScatterReduceTest, ScatterReduceSumFloatSmall) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.createFile(); + file << "ScatterReduceSumFloatSmall "; + + at::Tensor self = at::zeros({3, 5}, at::kFloat); + at::Tensor index = make_index_1x5(); + at::Tensor src = at::full({1, 5}, 1.0f, at::kFloat); + src.data_ptr()[0] = 1.0f; + src.data_ptr()[1] = 2.0f; + src.data_ptr()[2] = 3.0f; + src.data_ptr()[3] = 4.0f; + src.data_ptr()[4] = 5.0f; + at::Tensor result = self.scatter_reduce(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + +// Shape: small 2D, Dtype: kDouble, Reduce: sum +TEST_F(ScatterReduceTest, ScatterReduceSumDoubleSmall) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceSumDoubleSmall "; + + at::Tensor self = at::zeros({3, 5}, at::kDouble); + at::Tensor index = make_index_1x5(); + at::Tensor src = at::full({1, 5}, 1.0, at::kDouble); + src.data_ptr()[0] = 1.0; + src.data_ptr()[1] = 2.0; + src.data_ptr()[2] = 3.0; + src.data_ptr()[3] = 4.0; + src.data_ptr()[4] = 5.0; + at::Tensor result = self.scatter_reduce(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + +// Shape: small 2D, Dtype: kInt, Reduce: sum +TEST_F(ScatterReduceTest, ScatterReduceSumIntSmall) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceSumIntSmall "; + + at::Tensor self = at::zeros({3, 5}, at::kInt); + at::Tensor index = make_index_1x5(); + at::Tensor src = at::full({1, 5}, 1, at::kInt); + src.data_ptr()[0] = 1; + src.data_ptr()[1] = 2; + src.data_ptr()[2] = 3; + src.data_ptr()[3] = 4; + src.data_ptr()[4] = 5; + at::Tensor result = self.scatter_reduce(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + +// Shape: small 2D, Dtype: kLong, Reduce: sum +TEST_F(ScatterReduceTest, ScatterReduceSumLongSmall) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceSumLongSmall "; + + at::Tensor self = at::zeros({3, 5}, at::kLong); + at::Tensor index = make_index_1x5(); + at::Tensor src = at::full({1, 5}, 1, at::kLong); + src.data_ptr()[0] = 1; + src.data_ptr()[1] = 2; + src.data_ptr()[2] = 3; + src.data_ptr()[3] = 4; + src.data_ptr()[4] = 5; + at::Tensor result = self.scatter_reduce(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + +// Shape: medium 2D, Dtype: kFloat, Reduce: sum +TEST_F(ScatterReduceTest, ScatterReduceSumFloatMedium) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceSumFloatMedium "; + + at::Tensor self = at::zeros({6, 10}, at::kFloat); + at::Tensor index = at::zeros({2, 10}, at::kLong); + for (int64_t j = 0; j < 10; ++j) { + index.data_ptr()[j] = j % 6; + index.data_ptr()[10 + j] = (j + 3) % 6; + } + at::Tensor src = at::ones({2, 10}, at::kFloat); + at::Tensor result = self.scatter_reduce(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + +// Shape: large 2D, Dtype: kFloat, Reduce: sum +TEST_F(ScatterReduceTest, ScatterReduceSumFloatLarge) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceSumFloatLarge "; + + at::Tensor self = at::zeros({10, 20}, at::kFloat); + at::Tensor index = at::zeros({4, 20}, at::kLong); + for (int64_t j = 0; j < 20; ++j) { + index.data_ptr()[j] = j % 10; + index.data_ptr()[20 + j] = (j + 2) % 10; + index.data_ptr()[40 + j] = (j + 5) % 10; + index.data_ptr()[60 + j] = (j + 7) % 10; + } + at::Tensor src = at::ones({4, 20}, at::kFloat); + at::Tensor result = self.scatter_reduce(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + +// Shape: small 2D, Dtype: kFloat, Reduce: replace +// NOTE: Torch scatter_reduce "replace" mode has a segfault on this libtorch +// version. Output "exception" on both sides for consistent comparison. +TEST_F(ScatterReduceTest, ScatterReduceReplaceFloatSmall) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceReplaceFloatSmall exception "; + file << "\n"; + file.saveFile(); +} + +// Shape: small 2D, Dtype: kFloat, Reduce: amax +TEST_F(ScatterReduceTest, ScatterReduceAmaxFloatSmall) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceAmaxFloatSmall "; + + at::Tensor self = at::zeros({3, 5}, at::kFloat); + at::Tensor index = make_index_1x5(); + at::Tensor src = at::full({1, 5}, 1.0f, at::kFloat); + src.data_ptr()[0] = 10.0f; + src.data_ptr()[1] = 20.0f; + src.data_ptr()[2] = 30.0f; + src.data_ptr()[3] = 40.0f; + src.data_ptr()[4] = 50.0f; + at::Tensor result = self.scatter_reduce(0, index, src, "amax"); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + +// Shape: small 2D, Dtype: kFloat, Reduce: amin +TEST_F(ScatterReduceTest, ScatterReduceAminFloatSmall) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceAminFloatSmall "; + + at::Tensor self = at::full({3, 5}, 100.0f, at::kFloat); + at::Tensor index = make_index_1x5(); + at::Tensor src = at::full({1, 5}, 1.0f, at::kFloat); + src.data_ptr()[0] = 10.0f; + src.data_ptr()[1] = 20.0f; + src.data_ptr()[2] = 30.0f; + src.data_ptr()[3] = 40.0f; + src.data_ptr()[4] = 50.0f; + at::Tensor result = self.scatter_reduce(0, index, src, "amin"); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + +// Shape: small 2D, Dtype: kFloat, Reduce: mean +TEST_F(ScatterReduceTest, ScatterReduceMeanFloatSmall) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceMeanFloatSmall "; + + at::Tensor self = at::zeros({3, 5}, at::kFloat); + at::Tensor index = make_index_1x5(); + at::Tensor src = at::full({1, 5}, 1.0f, at::kFloat); + src.data_ptr()[0] = 10.0f; + src.data_ptr()[1] = 20.0f; + src.data_ptr()[2] = 30.0f; + src.data_ptr()[3] = 40.0f; + src.data_ptr()[4] = 50.0f; + at::Tensor result = self.scatter_reduce(0, index, src, "mean"); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + +// Shape: small 2D, Dtype: kFloat, Reduce: prod +TEST_F(ScatterReduceTest, ScatterReduceProdFloatSmall) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceProdFloatSmall "; + + at::Tensor self = at::ones({3, 5}, at::kFloat); + at::Tensor index = make_index_1x5(); + at::Tensor src = at::full({1, 5}, 1.0f, at::kFloat); + src.data_ptr()[0] = 2.0f; + src.data_ptr()[1] = 3.0f; + src.data_ptr()[2] = 4.0f; + src.data_ptr()[3] = 5.0f; + src.data_ptr()[4] = 6.0f; + at::Tensor result = self.scatter_reduce(0, index, src, "prod"); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + +// Shape: small 2D, Dtype: kFloat, Reduce: sum, dim=1 +TEST_F(ScatterReduceTest, ScatterReduceSumFloatDim1) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceSumFloatDim1 "; + + at::Tensor self = at::zeros({2, 4}, at::kFloat); + at::Tensor index = at::zeros({2, 4}, at::kLong); + index.data_ptr()[0] = 0; + index.data_ptr()[1] = 1; + index.data_ptr()[2] = 2; + index.data_ptr()[3] = 1; + index.data_ptr()[4] = 3; + index.data_ptr()[5] = 0; + index.data_ptr()[6] = 1; + index.data_ptr()[7] = 2; + at::Tensor src = at::full({2, 4}, 1.0f, at::kFloat); + src.data_ptr()[0] = 1.0f; + src.data_ptr()[1] = 2.0f; + src.data_ptr()[2] = 3.0f; + src.data_ptr()[3] = 4.0f; + src.data_ptr()[4] = 5.0f; + src.data_ptr()[5] = 6.0f; + src.data_ptr()[6] = 7.0f; + src.data_ptr()[7] = 8.0f; + at::Tensor result = self.scatter_reduce(1, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + +// Shape: small 2D, Dtype: kFloat, Reduce: sum, include_self=false +TEST_F(ScatterReduceTest, ScatterReduceSumFloatNoIncludeSelf) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceSumFloatNoIncludeSelf "; + + at::Tensor self = at::full({3, 5}, 5.0f, at::kFloat); + at::Tensor index = make_index_1x5(); + at::Tensor src = at::full({1, 5}, 1.0f, at::kFloat); + src.data_ptr()[0] = 1.0f; + src.data_ptr()[1] = 2.0f; + src.data_ptr()[2] = 3.0f; + src.data_ptr()[3] = 4.0f; + src.data_ptr()[4] = 5.0f; + at::Tensor result = self.scatter_reduce(0, index, src, "sum", false); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + +// Shape: small 2D, Dtype: kFloat, In-place scatter_reduce_ +TEST_F(ScatterReduceTest, ScatterReduceInplaceFloatSmall) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceInplaceFloatSmall "; + + at::Tensor self = at::zeros({3, 5}, at::kFloat); + at::Tensor index = make_index_1x5(); + at::Tensor src = at::full({1, 5}, 1.0f, at::kFloat); + src.data_ptr()[0] = 1.0f; + src.data_ptr()[1] = 2.0f; + src.data_ptr()[2] = 3.0f; + src.data_ptr()[3] = 4.0f; + src.data_ptr()[4] = 5.0f; + self.scatter_reduce_(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, self); + + file << "\n"; + file.saveFile(); +} + +// Boundary: empty tensor +TEST_F(ScatterReduceTest, ScatterReduceEmpty) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceEmpty "; + + at::Tensor self = at::zeros({0, 5}, at::kFloat); + at::Tensor index = at::empty({0, 5}, at::kLong); + at::Tensor src = at::empty({0, 5}, at::kFloat); + at::Tensor result = self.scatter_reduce(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + +// Exception: invalid reduce mode +TEST_F(ScatterReduceTest, ScatterReduceInvalidReduce) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceInvalidReduce "; + + try { + at::Tensor self = at::zeros({3, 5}, at::kFloat); + at::Tensor index = make_index_1x5(); + at::Tensor src = at::full({1, 5}, 1.0f, at::kFloat); + src.data_ptr()[0] = 1.0f; + src.data_ptr()[1] = 2.0f; + src.data_ptr()[2] = 3.0f; + src.data_ptr()[3] = 4.0f; + src.data_ptr()[4] = 5.0f; + at::Tensor result = self.scatter_reduce(0, index, src, "invalid"); + write_scatter_reduce_result_to_file(&file, result); + } catch (const std::exception&) { + file << "exception "; + } + + file << "\n"; + file.saveFile(); +} + +} // namespace test +} // namespace at From 319b3bc610b9a1a0972c77de87c457b7f61b87a4 Mon Sep 17 00:00:00 2001 From: youge325 Date: Wed, 3 Jun 2026 19:39:54 +0800 Subject: [PATCH 02/10] test(scatter_reduce): add align tests for prod + no include_self and inplace prod Add cross-framework comparison tests: - ScatterReduceProdFloatNoIncludeSelf - ScatterReduceInplaceProdFloatSmall Co-Authored-By: Claude Opus 4.7 --- test/ATen/ops/ScatterReduceTest.cpp | 44 +++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/test/ATen/ops/ScatterReduceTest.cpp b/test/ATen/ops/ScatterReduceTest.cpp index 21d3039..430d551 100644 --- a/test/ATen/ops/ScatterReduceTest.cpp +++ b/test/ATen/ops/ScatterReduceTest.cpp @@ -390,6 +390,50 @@ TEST_F(ScatterReduceTest, ScatterReduceEmpty) { file.saveFile(); } +// Shape: small 2D, Dtype: kFloat, Reduce: prod, include_self=false +TEST_F(ScatterReduceTest, ScatterReduceProdFloatNoIncludeSelf) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceProdFloatNoIncludeSelf "; + + at::Tensor self = at::full({3, 5}, 5.0f, at::kFloat); + at::Tensor index = make_index_1x5(); + at::Tensor src = at::full({1, 5}, 1.0f, at::kFloat); + src.data_ptr()[0] = 2.0f; + src.data_ptr()[1] = 3.0f; + src.data_ptr()[2] = 4.0f; + src.data_ptr()[3] = 5.0f; + src.data_ptr()[4] = 6.0f; + at::Tensor result = self.scatter_reduce(0, index, src, "prod", false); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + +// Shape: small 2D, Dtype: kFloat, In-place scatter_reduce_, Reduce: prod +TEST_F(ScatterReduceTest, ScatterReduceInplaceProdFloatSmall) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceInplaceProdFloatSmall "; + + at::Tensor self = at::ones({3, 5}, at::kFloat); + at::Tensor index = make_index_1x5(); + at::Tensor src = at::full({1, 5}, 1.0f, at::kFloat); + src.data_ptr()[0] = 2.0f; + src.data_ptr()[1] = 3.0f; + src.data_ptr()[2] = 4.0f; + src.data_ptr()[3] = 5.0f; + src.data_ptr()[4] = 6.0f; + self.scatter_reduce_(0, index, src, "prod"); + write_scatter_reduce_result_to_file(&file, self); + + file << "\n"; + file.saveFile(); +} + // Exception: invalid reduce mode TEST_F(ScatterReduceTest, ScatterReduceInvalidReduce) { auto file_name = g_custom_param.get(); From 315bd205bf6a99305c72a41a4d90fe82ef1e9d35 Mon Sep 17 00:00:00 2001 From: youge325 Date: Fri, 5 Jun 2026 16:05:01 +0800 Subject: [PATCH 03/10] test(scatter_reduce): add align tests for amax/amin/mean + include_self=false Add cross-framework comparison tests: - ScatterReduceAmaxFloatNoIncludeSelf - ScatterReduceAminFloatNoIncludeSelf - ScatterReduceMeanFloatNoIncludeSelf Co-Authored-By: Claude Opus 4.7 --- test/ATen/ops/ScatterReduceTest.cpp | 66 +++++++++++++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/test/ATen/ops/ScatterReduceTest.cpp b/test/ATen/ops/ScatterReduceTest.cpp index 430d551..5f40d2d 100644 --- a/test/ATen/ops/ScatterReduceTest.cpp +++ b/test/ATen/ops/ScatterReduceTest.cpp @@ -434,6 +434,72 @@ TEST_F(ScatterReduceTest, ScatterReduceInplaceProdFloatSmall) { file.saveFile(); } +// Shape: small 2D, Dtype: kFloat, Reduce: amax, include_self=false +TEST_F(ScatterReduceTest, ScatterReduceAmaxFloatNoIncludeSelf) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceAmaxFloatNoIncludeSelf "; + + at::Tensor self = at::full({3, 5}, 5.0f, at::kFloat); + at::Tensor index = make_index_1x5(); + at::Tensor src = at::full({1, 5}, 1.0f, at::kFloat); + src.data_ptr()[0] = 10.0f; + src.data_ptr()[1] = 20.0f; + src.data_ptr()[2] = 30.0f; + src.data_ptr()[3] = 40.0f; + src.data_ptr()[4] = 50.0f; + at::Tensor result = self.scatter_reduce(0, index, src, "amax", false); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + +// Shape: small 2D, Dtype: kFloat, Reduce: amin, include_self=false +TEST_F(ScatterReduceTest, ScatterReduceAminFloatNoIncludeSelf) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceAminFloatNoIncludeSelf "; + + at::Tensor self = at::full({3, 5}, 5.0f, at::kFloat); + at::Tensor index = make_index_1x5(); + at::Tensor src = at::full({1, 5}, 1.0f, at::kFloat); + src.data_ptr()[0] = 10.0f; + src.data_ptr()[1] = 20.0f; + src.data_ptr()[2] = 30.0f; + src.data_ptr()[3] = 40.0f; + src.data_ptr()[4] = 50.0f; + at::Tensor result = self.scatter_reduce(0, index, src, "amin", false); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + +// Shape: small 2D, Dtype: kFloat, Reduce: mean, include_self=false +TEST_F(ScatterReduceTest, ScatterReduceMeanFloatNoIncludeSelf) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceMeanFloatNoIncludeSelf "; + + at::Tensor self = at::full({3, 5}, 5.0f, at::kFloat); + at::Tensor index = make_index_1x5(); + at::Tensor src = at::full({1, 5}, 1.0f, at::kFloat); + src.data_ptr()[0] = 10.0f; + src.data_ptr()[1] = 20.0f; + src.data_ptr()[2] = 30.0f; + src.data_ptr()[3] = 40.0f; + src.data_ptr()[4] = 50.0f; + at::Tensor result = self.scatter_reduce(0, index, src, "mean", false); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + // Exception: invalid reduce mode TEST_F(ScatterReduceTest, ScatterReduceInvalidReduce) { auto file_name = g_custom_param.get(); From e669b9fc77474289229c62f298875370e4421e9b Mon Sep 17 00:00:00 2001 From: youge325 Date: Fri, 5 Jun 2026 16:28:10 +0800 Subject: [PATCH 04/10] test(scatter_reduce): fix AmaxFloatNoIncludeSelf self value Change self from 5.0f to 25.0f so some src values are below self and some are above, ensuring the test can distinguish include_self=true vs false behavior. Co-Authored-By: Claude Opus 4.7 --- test/ATen/ops/ScatterReduceTest.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/ATen/ops/ScatterReduceTest.cpp b/test/ATen/ops/ScatterReduceTest.cpp index 5f40d2d..bf17f69 100644 --- a/test/ATen/ops/ScatterReduceTest.cpp +++ b/test/ATen/ops/ScatterReduceTest.cpp @@ -441,7 +441,9 @@ TEST_F(ScatterReduceTest, ScatterReduceAmaxFloatNoIncludeSelf) { file.openAppend(); file << "ScatterReduceAmaxFloatNoIncludeSelf "; - at::Tensor self = at::full({3, 5}, 5.0f, at::kFloat); + // Use self=25.0f so some src values are below self (10, 20) and some above + // (30, 40, 50). This ensures amax with include_self=false differs from true. + at::Tensor self = at::full({3, 5}, 25.0f, at::kFloat); at::Tensor index = make_index_1x5(); at::Tensor src = at::full({1, 5}, 1.0f, at::kFloat); src.data_ptr()[0] = 10.0f; From 988445168e4bc806c4dc74b88352c330ce6fd84c Mon Sep 17 00:00:00 2001 From: youge325 Date: Fri, 5 Jun 2026 20:13:10 +0800 Subject: [PATCH 05/10] test(scatter_reduce): add dim out of range align test Add ScatterReduceDimOutOfRange cross-framework comparison test for int64_t dim exceeding int range. Co-Authored-By: Claude Opus 4.7 --- test/ATen/ops/ScatterReduceTest.cpp | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/test/ATen/ops/ScatterReduceTest.cpp b/test/ATen/ops/ScatterReduceTest.cpp index bf17f69..7007096 100644 --- a/test/ATen/ops/ScatterReduceTest.cpp +++ b/test/ATen/ops/ScatterReduceTest.cpp @@ -528,5 +528,27 @@ TEST_F(ScatterReduceTest, ScatterReduceInvalidReduce) { file.saveFile(); } +// Exception: dim out of int range +TEST_F(ScatterReduceTest, ScatterReduceDimOutOfRange) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceDimOutOfRange "; + + try { + at::Tensor self = at::zeros({2, 2}, at::kFloat); + at::Tensor index = make_index_1x5(); + at::Tensor src = at::ones({1, 5}, at::kFloat); + at::Tensor result = self.scatter_reduce( + static_cast(INT_MAX) + 1, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + } catch (const std::exception&) { + file << "exception "; + } + + file << "\n"; + file.saveFile(); +} + } // namespace test } // namespace at From d3ce2a705accf2d57658c900d0255c5024316af6 Mon Sep 17 00:00:00 2001 From: youge325 Date: Sun, 14 Jun 2026 16:20:22 +0800 Subject: [PATCH 06/10] [Compat Test] Add scatter_reduce edge alignment cases --- test/ATen/ops/ScatterReduceTest.cpp | 146 +++++++++++++++++++++++++++- 1 file changed, 142 insertions(+), 4 deletions(-) diff --git a/test/ATen/ops/ScatterReduceTest.cpp b/test/ATen/ops/ScatterReduceTest.cpp index 7007096..c1c8788 100644 --- a/test/ATen/ops/ScatterReduceTest.cpp +++ b/test/ATen/ops/ScatterReduceTest.cpp @@ -196,14 +196,28 @@ TEST_F(ScatterReduceTest, ScatterReduceSumFloatLarge) { file.saveFile(); } -// Shape: small 2D, Dtype: kFloat, Reduce: replace -// NOTE: Torch scatter_reduce "replace" mode has a segfault on this libtorch -// version. Output "exception" on both sides for consistent comparison. +// Exception: PyTorch scatter_reduce does not support replace mode. TEST_F(ScatterReduceTest, ScatterReduceReplaceFloatSmall) { auto file_name = g_custom_param.get(); FileManerger file(file_name); file.openAppend(); - file << "ScatterReduceReplaceFloatSmall exception "; + file << "ScatterReduceReplaceFloatSmall "; + + try { + at::Tensor self = at::zeros({3, 5}, at::kFloat); + at::Tensor index = make_index_1x5(); + at::Tensor src = at::full({1, 5}, 1.0f, at::kFloat); + src.data_ptr()[0] = 1.0f; + src.data_ptr()[1] = 2.0f; + src.data_ptr()[2] = 3.0f; + src.data_ptr()[3] = 4.0f; + src.data_ptr()[4] = 5.0f; + at::Tensor result = self.scatter_reduce(0, index, src, "replace"); + write_scatter_reduce_result_to_file(&file, result); + } catch (const std::exception&) { + file << "exception "; + } + file << "\n"; file.saveFile(); } @@ -329,6 +343,72 @@ TEST_F(ScatterReduceTest, ScatterReduceSumFloatDim1) { file.saveFile(); } +// Shape: small 2D, Dtype: kFloat, Reduce: sum, dim=-1 +TEST_F(ScatterReduceTest, ScatterReduceSumFloatNegativeDim) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceSumFloatNegativeDim "; + + at::Tensor self = at::zeros({2, 4}, at::kFloat); + at::Tensor index = at::zeros({2, 4}, at::kLong); + index.data_ptr()[0] = 0; + index.data_ptr()[1] = 1; + index.data_ptr()[2] = 2; + index.data_ptr()[3] = 1; + index.data_ptr()[4] = 3; + index.data_ptr()[5] = 0; + index.data_ptr()[6] = 1; + index.data_ptr()[7] = 2; + at::Tensor src = at::full({2, 4}, 1.0f, at::kFloat); + src.data_ptr()[0] = 1.0f; + src.data_ptr()[1] = 2.0f; + src.data_ptr()[2] = 3.0f; + src.data_ptr()[3] = 4.0f; + src.data_ptr()[4] = 5.0f; + src.data_ptr()[5] = 6.0f; + src.data_ptr()[6] = 7.0f; + src.data_ptr()[7] = 8.0f; + at::Tensor result = self.scatter_reduce(-1, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + +// Shape: small 2D, Dtype: kFloat, In-place scatter_reduce_, dim=-1 +TEST_F(ScatterReduceTest, ScatterReduceInplaceFloatNegativeDim) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceInplaceFloatNegativeDim "; + + at::Tensor self = at::zeros({2, 4}, at::kFloat); + at::Tensor index = at::zeros({2, 4}, at::kLong); + index.data_ptr()[0] = 0; + index.data_ptr()[1] = 1; + index.data_ptr()[2] = 2; + index.data_ptr()[3] = 1; + index.data_ptr()[4] = 3; + index.data_ptr()[5] = 0; + index.data_ptr()[6] = 1; + index.data_ptr()[7] = 2; + at::Tensor src = at::full({2, 4}, 1.0f, at::kFloat); + src.data_ptr()[0] = 1.0f; + src.data_ptr()[1] = 2.0f; + src.data_ptr()[2] = 3.0f; + src.data_ptr()[3] = 4.0f; + src.data_ptr()[4] = 5.0f; + src.data_ptr()[5] = 6.0f; + src.data_ptr()[6] = 7.0f; + src.data_ptr()[7] = 8.0f; + self.scatter_reduce_(-1, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, self); + + file << "\n"; + file.saveFile(); +} + // Shape: small 2D, Dtype: kFloat, Reduce: sum, include_self=false TEST_F(ScatterReduceTest, ScatterReduceSumFloatNoIncludeSelf) { auto file_name = g_custom_param.get(); @@ -351,6 +431,64 @@ TEST_F(ScatterReduceTest, ScatterReduceSumFloatNoIncludeSelf) { file.saveFile(); } +// Exception: PyTorch scatter_reduce rejects negative indices. +TEST_F(ScatterReduceTest, ScatterReduceNegativeIndex) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceNegativeIndex "; + + try { + at::Tensor self = at::zeros({2, 4}, at::kFloat); + at::Tensor index = at::zeros({2, 4}, at::kLong); + index.data_ptr()[0] = 0; + index.data_ptr()[1] = -1; + index.data_ptr()[2] = 2; + index.data_ptr()[3] = 1; + index.data_ptr()[4] = 3; + index.data_ptr()[5] = 0; + index.data_ptr()[6] = 1; + index.data_ptr()[7] = 2; + at::Tensor src = at::ones({2, 4}, at::kFloat); + at::Tensor result = self.scatter_reduce(1, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + } catch (const std::exception&) { + file << "exception "; + } + + file << "\n"; + file.saveFile(); +} + +// Exception: PyTorch scatter_reduce_ rejects negative indices. +TEST_F(ScatterReduceTest, ScatterReduceInplaceNegativeIndex) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceInplaceNegativeIndex "; + + try { + at::Tensor self = at::zeros({2, 4}, at::kFloat); + at::Tensor index = at::zeros({2, 4}, at::kLong); + index.data_ptr()[0] = 0; + index.data_ptr()[1] = -1; + index.data_ptr()[2] = 2; + index.data_ptr()[3] = 1; + index.data_ptr()[4] = 3; + index.data_ptr()[5] = 0; + index.data_ptr()[6] = 1; + index.data_ptr()[7] = 2; + at::Tensor src = at::ones({2, 4}, at::kFloat); + self.scatter_reduce_(1, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, self); + } catch (const std::exception&) { + file << "exception "; + } + + file << "\n"; + file.saveFile(); +} + // Shape: small 2D, Dtype: kFloat, In-place scatter_reduce_ TEST_F(ScatterReduceTest, ScatterReduceInplaceFloatSmall) { auto file_name = g_custom_param.get(); From 588c696db91a4fde32389f127457d4db1a7403fb Mon Sep 17 00:00:00 2001 From: youge325 Date: Sun, 14 Jun 2026 17:43:41 +0800 Subject: [PATCH 07/10] test(ATen): add scatter_reduce shape alignment cases --- test/ATen/ops/ScatterReduceTest.cpp | 80 +++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/test/ATen/ops/ScatterReduceTest.cpp b/test/ATen/ops/ScatterReduceTest.cpp index c1c8788..3f7c803 100644 --- a/test/ATen/ops/ScatterReduceTest.cpp +++ b/test/ATen/ops/ScatterReduceTest.cpp @@ -640,6 +640,86 @@ TEST_F(ScatterReduceTest, ScatterReduceMeanFloatNoIncludeSelf) { file.saveFile(); } +TEST_F(ScatterReduceTest, ScatterReduceRankMismatch) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceRankMismatch "; + + try { + at::Tensor self = at::zeros({2, 2}, at::kFloat); + at::Tensor index = at::zeros({2}, at::kLong); + at::Tensor src = at::ones({2, 2}, at::kFloat); + at::Tensor result = self.scatter_reduce(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + } catch (const std::exception&) { + file << "exception "; + } + + file << "\n"; + file.saveFile(); +} + +TEST_F(ScatterReduceTest, ScatterReduceIndexLargerThanSrc) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceIndexLargerThanSrc "; + + try { + at::Tensor self = at::zeros({3, 2}, at::kFloat); + at::Tensor index = at::zeros({3, 2}, at::kLong); + at::Tensor src = at::ones({2, 2}, at::kFloat); + at::Tensor result = self.scatter_reduce(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + } catch (const std::exception&) { + file << "exception "; + } + + file << "\n"; + file.saveFile(); +} + +TEST_F(ScatterReduceTest, ScatterReduceIndexLargerThanSelf) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceIndexLargerThanSelf "; + + try { + at::Tensor self = at::zeros({2, 2}, at::kFloat); + at::Tensor index = at::zeros({1, 3}, at::kLong); + at::Tensor src = at::ones({1, 3}, at::kFloat); + at::Tensor result = self.scatter_reduce(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + } catch (const std::exception&) { + file << "exception "; + } + + file << "\n"; + file.saveFile(); +} + +TEST_F(ScatterReduceTest, ScatterReduceInplaceShapeMismatch) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceInplaceShapeMismatch "; + + try { + at::Tensor self = at::zeros({2, 2}, at::kFloat); + at::Tensor index = at::zeros({1, 3}, at::kLong); + at::Tensor src = at::ones({1, 3}, at::kFloat); + at::Tensor result = self.scatter_reduce_(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + } catch (const std::exception&) { + file << "exception "; + } + + file << "\n"; + file.saveFile(); +} + // Exception: invalid reduce mode TEST_F(ScatterReduceTest, ScatterReduceInvalidReduce) { auto file_name = g_custom_param.get(); From 1bc23c099584217a6524afb402c3d1abf39c12dd Mon Sep 17 00:00:00 2001 From: youge325 Date: Sun, 14 Jun 2026 19:24:42 +0800 Subject: [PATCH 08/10] test(ATen): add scatter_reduce index dtype cases --- test/ATen/ops/ScatterReduceTest.cpp | 114 ++++++++++++++++++++++++++++ 1 file changed, 114 insertions(+) diff --git a/test/ATen/ops/ScatterReduceTest.cpp b/test/ATen/ops/ScatterReduceTest.cpp index 3f7c803..29c4f8b 100644 --- a/test/ATen/ops/ScatterReduceTest.cpp +++ b/test/ATen/ops/ScatterReduceTest.cpp @@ -1,5 +1,6 @@ #include #include +#include #include #include @@ -489,6 +490,102 @@ TEST_F(ScatterReduceTest, ScatterReduceInplaceNegativeIndex) { file.saveFile(); } +// PyTorch C++ scatter_reduce accepts int32 index tensors. +TEST_F(ScatterReduceTest, ScatterReduceIntIndex) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceIntIndex "; + + at::Tensor self = at::zeros({3, 5}, at::kFloat); + at::Tensor index = at::zeros({1, 5}, at::kInt); + index.data_ptr()[0] = 0; + index.data_ptr()[1] = 1; + index.data_ptr()[2] = 2; + index.data_ptr()[3] = 0; + index.data_ptr()[4] = 0; + at::Tensor src = at::full({1, 5}, 1.0f, at::kFloat); + src.data_ptr()[0] = 1.0f; + src.data_ptr()[1] = 2.0f; + src.data_ptr()[2] = 3.0f; + src.data_ptr()[3] = 4.0f; + src.data_ptr()[4] = 5.0f; + at::Tensor result = self.scatter_reduce(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + +// PyTorch C++ scatter_reduce_ accepts int32 index tensors. +TEST_F(ScatterReduceTest, ScatterReduceInplaceIntIndex) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceInplaceIntIndex "; + + at::Tensor self = at::zeros({3, 5}, at::kFloat); + at::Tensor index = at::zeros({1, 5}, at::kInt); + index.data_ptr()[0] = 0; + index.data_ptr()[1] = 1; + index.data_ptr()[2] = 2; + index.data_ptr()[3] = 0; + index.data_ptr()[4] = 0; + at::Tensor src = at::full({1, 5}, 1.0f, at::kFloat); + src.data_ptr()[0] = 1.0f; + src.data_ptr()[1] = 2.0f; + src.data_ptr()[2] = 3.0f; + src.data_ptr()[3] = 4.0f; + src.data_ptr()[4] = 5.0f; + self.scatter_reduce_(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, self); + + file << "\n"; + file.saveFile(); +} + +// PyTorch C++ scatter_reduce rejects non-empty floating index tensors. +TEST_F(ScatterReduceTest, ScatterReduceFloatIndex) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceFloatIndex "; + + try { + at::Tensor self = at::zeros({2, 2}, at::kFloat); + at::Tensor index = at::zeros({1, 2}, at::kFloat); + at::Tensor src = at::ones({1, 2}, at::kFloat); + at::Tensor result = self.scatter_reduce(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + } catch (const std::exception&) { + file << "exception "; + } + + file << "\n"; + file.saveFile(); +} + +// PyTorch C++ scatter_reduce_ rejects non-empty floating index tensors. +TEST_F(ScatterReduceTest, ScatterReduceInplaceFloatIndex) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceInplaceFloatIndex "; + + try { + at::Tensor self = at::zeros({2, 2}, at::kFloat); + at::Tensor index = at::zeros({1, 2}, at::kFloat); + at::Tensor src = at::ones({1, 2}, at::kFloat); + self.scatter_reduce_(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, self); + } catch (const std::exception&) { + file << "exception "; + } + + file << "\n"; + file.saveFile(); +} + // Shape: small 2D, Dtype: kFloat, In-place scatter_reduce_ TEST_F(ScatterReduceTest, ScatterReduceInplaceFloatSmall) { auto file_name = g_custom_param.get(); @@ -528,6 +625,23 @@ TEST_F(ScatterReduceTest, ScatterReduceEmpty) { file.saveFile(); } +// Boundary: empty floating index tensor is accepted by PyTorch C++. +TEST_F(ScatterReduceTest, ScatterReduceEmptyFloatIndex) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceEmptyFloatIndex "; + + at::Tensor self = at::zeros({0, 2}, at::kFloat); + at::Tensor index = at::empty({0, 2}, at::kFloat); + at::Tensor src = at::empty({0, 2}, at::kFloat); + at::Tensor result = self.scatter_reduce(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + // Shape: small 2D, Dtype: kFloat, Reduce: prod, include_self=false TEST_F(ScatterReduceTest, ScatterReduceProdFloatNoIncludeSelf) { auto file_name = g_custom_param.get(); From 6de8da965efc7efda143175020d188c727495702 Mon Sep 17 00:00:00 2001 From: youge325 Date: Mon, 29 Jun 2026 13:25:50 +0800 Subject: [PATCH 09/10] test(ATen): add scatter_reduce free function alignment cases --- test/ATen/ops/ScatterReduceTest.cpp | 80 +++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/test/ATen/ops/ScatterReduceTest.cpp b/test/ATen/ops/ScatterReduceTest.cpp index 29c4f8b..251107b 100644 --- a/test/ATen/ops/ScatterReduceTest.cpp +++ b/test/ATen/ops/ScatterReduceTest.cpp @@ -87,6 +87,28 @@ TEST_F(ScatterReduceTest, ScatterReduceSumFloatSmall) { file.saveFile(); } +// API variant: free function at::scatter_reduce. +TEST_F(ScatterReduceTest, ScatterReduceFreeFunctionSumFloatSmall) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceFreeFunctionSumFloatSmall "; + + at::Tensor self = at::zeros({3, 5}, at::kFloat); + at::Tensor index = make_index_1x5(); + at::Tensor src = at::full({1, 5}, 1.0f, at::kFloat); + src.data_ptr()[0] = 1.0f; + src.data_ptr()[1] = 2.0f; + src.data_ptr()[2] = 3.0f; + src.data_ptr()[3] = 4.0f; + src.data_ptr()[4] = 5.0f; + at::Tensor result = at::scatter_reduce(self, 0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + // Shape: small 2D, Dtype: kDouble, Reduce: sum TEST_F(ScatterReduceTest, ScatterReduceSumDoubleSmall) { auto file_name = g_custom_param.get(); @@ -490,6 +512,64 @@ TEST_F(ScatterReduceTest, ScatterReduceInplaceNegativeIndex) { file.saveFile(); } +// Exception: PyTorch scatter_reduce rejects index >= self.size(dim). +TEST_F(ScatterReduceTest, ScatterReduceIndexUpperBound) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceIndexUpperBound "; + + try { + at::Tensor self = at::zeros({2, 4}, at::kFloat); + at::Tensor index = at::zeros({2, 4}, at::kLong); + index.data_ptr()[0] = 0; + index.data_ptr()[1] = 4; + index.data_ptr()[2] = 2; + index.data_ptr()[3] = 1; + index.data_ptr()[4] = 3; + index.data_ptr()[5] = 0; + index.data_ptr()[6] = 1; + index.data_ptr()[7] = 2; + at::Tensor src = at::ones({2, 4}, at::kFloat); + at::Tensor result = self.scatter_reduce(1, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + } catch (const std::exception&) { + file << "exception "; + } + + file << "\n"; + file.saveFile(); +} + +// Exception: PyTorch scatter_reduce_ rejects index >= self.size(dim). +TEST_F(ScatterReduceTest, ScatterReduceInplaceIndexUpperBound) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceInplaceIndexUpperBound "; + + try { + at::Tensor self = at::zeros({2, 4}, at::kFloat); + at::Tensor index = at::zeros({2, 4}, at::kLong); + index.data_ptr()[0] = 0; + index.data_ptr()[1] = 4; + index.data_ptr()[2] = 2; + index.data_ptr()[3] = 1; + index.data_ptr()[4] = 3; + index.data_ptr()[5] = 0; + index.data_ptr()[6] = 1; + index.data_ptr()[7] = 2; + at::Tensor src = at::ones({2, 4}, at::kFloat); + self.scatter_reduce_(1, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, self); + } catch (const std::exception&) { + file << "exception "; + } + + file << "\n"; + file.saveFile(); +} + // PyTorch C++ scatter_reduce accepts int32 index tensors. TEST_F(ScatterReduceTest, ScatterReduceIntIndex) { auto file_name = g_custom_param.get(); From 8d84fd74df0d659af4857e3d02acd83e3a6c3e73 Mon Sep 17 00:00:00 2001 From: youge325 Date: Wed, 1 Jul 2026 23:03:20 +0800 Subject: [PATCH 10/10] [ATen] Add scatter_reduce empty index alignment tests --- test/ATen/ops/ScatterReduceTest.cpp | 82 +++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) diff --git a/test/ATen/ops/ScatterReduceTest.cpp b/test/ATen/ops/ScatterReduceTest.cpp index 251107b..cf3d6e4 100644 --- a/test/ATen/ops/ScatterReduceTest.cpp +++ b/test/ATen/ops/ScatterReduceTest.cpp @@ -722,6 +722,88 @@ TEST_F(ScatterReduceTest, ScatterReduceEmptyFloatIndex) { file.saveFile(); } +TEST_F(ScatterReduceTest, ScatterReduceEmptyIndexRankMismatch) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceEmptyIndexRankMismatch "; + + at::Tensor self = at::zeros({2, 2}, at::kFloat); + float* self_data = self.data_ptr(); + self_data[0] = 1.0f; + self_data[1] = 2.0f; + self_data[2] = 3.0f; + self_data[3] = 4.0f; + at::Tensor index = at::empty({0}, at::kLong); + at::Tensor src = at::empty({0}, at::kFloat); + at::Tensor result = self.scatter_reduce(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + + file << "\n"; + file.saveFile(); +} + +TEST_F(ScatterReduceTest, ScatterReduceInplaceEmptyIndexRankMismatch) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceInplaceEmptyIndexRankMismatch "; + + at::Tensor self = at::zeros({2, 2}, at::kFloat); + float* self_data = self.data_ptr(); + self_data[0] = 1.0f; + self_data[1] = 2.0f; + self_data[2] = 3.0f; + self_data[3] = 4.0f; + at::Tensor index = at::empty({0}, at::kLong); + at::Tensor src = at::empty({0}, at::kFloat); + self.scatter_reduce_(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, self); + + file << "\n"; + file.saveFile(); +} + +TEST_F(ScatterReduceTest, ScatterReduceEmptyIndexSrcDtypeMismatch) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceEmptyIndexSrcDtypeMismatch "; + + try { + at::Tensor self = at::zeros({2, 2}, at::kFloat); + at::Tensor index = at::empty({0}, at::kLong); + at::Tensor src = at::empty({0}, at::kInt); + at::Tensor result = self.scatter_reduce(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, result); + } catch (const std::exception&) { + file << "exception "; + } + + file << "\n"; + file.saveFile(); +} + +TEST_F(ScatterReduceTest, ScatterReduceInplaceEmptyIndexSrcDtypeMismatch) { + auto file_name = g_custom_param.get(); + FileManerger file(file_name); + file.openAppend(); + file << "ScatterReduceInplaceEmptyIndexSrcDtypeMismatch "; + + try { + at::Tensor self = at::zeros({2, 2}, at::kFloat); + at::Tensor index = at::empty({0}, at::kLong); + at::Tensor src = at::empty({0}, at::kInt); + self.scatter_reduce_(0, index, src, "sum"); + write_scatter_reduce_result_to_file(&file, self); + } catch (const std::exception&) { + file << "exception "; + } + + file << "\n"; + file.saveFile(); +} + // Shape: small 2D, Dtype: kFloat, Reduce: prod, include_self=false TEST_F(ScatterReduceTest, ScatterReduceProdFloatNoIncludeSelf) { auto file_name = g_custom_param.get();