From 49bfbf46d8631b0cf18f2b847fcb01174410c619 Mon Sep 17 00:00:00 2001 From: mitruska Date: Tue, 5 Nov 2024 20:40:51 +0100 Subject: [PATCH 01/18] Fill CPU Reduce out tensor with 0 when input is empty --- src/plugins/intel_cpu/src/nodes/reduce.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/plugins/intel_cpu/src/nodes/reduce.cpp b/src/plugins/intel_cpu/src/nodes/reduce.cpp index 7c18421ad3d832..fdebb1bb581185 100644 --- a/src/plugins/intel_cpu/src/nodes/reduce.cpp +++ b/src/plugins/intel_cpu/src/nodes/reduce.cpp @@ -2089,7 +2089,7 @@ void Reduce::initSupportedPrimitiveDescriptors() { } bool Reduce::isExecutable() const { - return !isInputTensorAtPortEmpty(REDUCE_DATA); + return !isOutputTensorAtPortEmpty(0); } void Reduce::prepareParams() { @@ -2271,6 +2271,14 @@ void Reduce::execute(dnnl::stream strm) { auto dstMemPtr = getDstMemoryAtPort(0); auto srcMemPtr = getSrcMemoryAtPort(REDUCE_DATA); + const auto src_shape = getSrcMemoryAtPort(REDUCE_DATA)->getStaticDims(); + if ((shape_size(src_shape) == 0 || srcMemPtr->getSize() == 0) && dstMemPtr->getSize() > 0) { + // If input is empty fill ouptut with zero + auto dst_shape = getDstMemoryAtPort(0)->getStaticDims(); + std::fill_n(dstMemPtr->getDataAs(), shape_size(dst_shape), 0.f); + return; + } + const uint8_t *src_data = srcMemPtr->getDataAs(); uint8_t *dst_data = dstMemPtr->getDataAs(); From 4876eede7517a2a7f20b22dc132542820dcac90a Mon Sep 17 00:00:00 2001 From: mitruska Date: Tue, 5 Nov 2024 20:51:39 +0100 Subject: [PATCH 02/18] Add ref tests --- .../tests/functional/op_reference/reduce_l1.cpp | 10 ++++++++++ .../tests/functional/op_reference/reduce_l2.cpp | 10 ++++++++++ .../tests/functional/op_reference/reduce_max.cpp | 10 ++++++++++ .../tests/functional/op_reference/reduce_mean.cpp | 10 ++++++++++ .../tests/functional/op_reference/reduce_min.cpp | 10 ++++++++++ .../tests/functional/op_reference/reduce_prod.cpp | 10 ++++++++++ .../tests/functional/op_reference/reduce_sum.cpp | 10 ++++++++++ 7 files changed, 70 insertions(+) diff --git a/src/plugins/template/tests/functional/op_reference/reduce_l1.cpp b/src/plugins/template/tests/functional/op_reference/reduce_l1.cpp index 6e0c2fe2aa24e0..90663b539ed94b 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_l1.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_l1.cpp @@ -25,6 +25,16 @@ std::vector generateReductionParams(const bool keep_dims) { reference_tests::Tensor(reduce(Shape{3, 2, 2}, AxisSet{2}, keep_dims), element::Type(IN_ET), std::vector{3, 7, 11, 15, 19, 23}))}; + if (keep_dims == false) { + params.push_back(ReductionParams( + ReductionType::L1, + keep_dims, + std::vector{1, 2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), + reference_tests::Tensor(Shape{2}, + element::Type(IN_ET), + std::vector{0, 0}))); // Keep dims false, tensor filled with zero + } return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_l2.cpp b/src/plugins/template/tests/functional/op_reference/reduce_l2.cpp index 565f89d58f7238..3f73a2571546b9 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_l2.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_l2.cpp @@ -29,6 +29,16 @@ std::vector generateReductionParams(const bool keep_dims) { reference_tests::Tensor(reduce(Shape{3, 2, 2}, AxisSet{2}, keep_dims), element::Type(IN_ET), std::vector{2.23606798, 5.0, 7.81024968, 10.63014581, 13.45362405, 16.2788206}))}; + if (keep_dims == false) { + params.push_back(ReductionParams( + ReductionType::L2, + keep_dims, + std::vector{1, 2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), + reference_tests::Tensor(Shape{2}, + element::Type(IN_ET), + std::vector{0, 0}))); // Keep dims false, tensor filled with zero + } return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_max.cpp b/src/plugins/template/tests/functional/op_reference/reduce_max.cpp index 0674595de4ec43..e831c4089fdd2a 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_max.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_max.cpp @@ -79,6 +79,16 @@ std::vector generateReductionParams(const bool keep_dims) { reference_tests::Tensor(reduce(Shape{3, 3, 3}, AxisSet{0, 1, 2}, keep_dims), element::Type(IN_ET), std::vector{27}))}; + if (keep_dims == false) { + params.push_back(ReductionParams( + ReductionType::Max, + keep_dims, + std::vector{1, 2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), + reference_tests::Tensor(Shape{2}, + element::Type(IN_ET), + std::vector{0, 0}))); // Keep dims false, tensor filled with zero + } return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_mean.cpp b/src/plugins/template/tests/functional/op_reference/reduce_mean.cpp index def9d837b46df6..b369853ffbf7e8 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_mean.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_mean.cpp @@ -41,6 +41,16 @@ std::vector generateReductionParams(const bool keep_dims) { reference_tests::Tensor(reduce(Shape{3, 2}, AxisSet{1}, keep_dims), element::Type(IN_ET), std::vector{1.5, 3.5, 5.5}))}; + if (keep_dims == false) { + params.push_back(ReductionParams( + ReductionType::Mean, + keep_dims, + std::vector{1, 2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), + reference_tests::Tensor(Shape{2}, + element::Type(IN_ET), + std::vector{0, 0}))); // Keep dims false, tensor filled with zero + } return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_min.cpp b/src/plugins/template/tests/functional/op_reference/reduce_min.cpp index abc9dca157684b..45bd0ebe8656db 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_min.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_min.cpp @@ -79,6 +79,16 @@ std::vector generateReductionParams(const bool keep_dims) { reference_tests::Tensor(reduce(Shape{3, 3, 3}, AxisSet{0, 1, 2}, keep_dims), element::Type(IN_ET), std::vector{1}))}; + if (keep_dims == false) { + params.push_back(ReductionParams( + ReductionType::Min, + keep_dims, + std::vector{1, 2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), + reference_tests::Tensor(Shape{2}, + element::Type(IN_ET), + std::vector{0, 0}))); // Keep dims false, tensor filled with zero + } return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_prod.cpp b/src/plugins/template/tests/functional/op_reference/reduce_prod.cpp index d030633932fd73..de94fc58143da2 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_prod.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_prod.cpp @@ -74,6 +74,16 @@ std::vector generateReductionParams(const bool keep_dims) { 19 * 20 * 21, 22 * 23 * 24, 25 * 26 * 27}))}; + if (keep_dims == false) { + params.push_back(ReductionParams( + ReductionType::Prod, + keep_dims, + std::vector{1, 2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), + reference_tests::Tensor(Shape{2}, + element::Type(IN_ET), + std::vector{0, 0}))); // Keep dims false, tensor filled with zero + } return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_sum.cpp b/src/plugins/template/tests/functional/op_reference/reduce_sum.cpp index ab77acc3cf696a..89f76f110505bf 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_sum.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_sum.cpp @@ -121,6 +121,16 @@ std::vector generateReductionParams(const bool keep_dims) { reference_tests::Tensor(reduce(Shape{3, 3, 3, 3, 3}, AxisSet{0, 1, 2, 3, 4}, keep_dims), element::Type(IN_ET), std::vector{243}))}; + if (keep_dims == false) { + params.push_back(ReductionParams( + ReductionType::Sum, + keep_dims, + std::vector{1, 2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), + reference_tests::Tensor(Shape{2}, + element::Type(IN_ET), + std::vector{0, 0}))); // Keep dims false, tensor filled with zero + } return params; } From 1ae61b938d4c469504e119e49df4d3757aa11b3f Mon Sep 17 00:00:00 2001 From: mitruska Date: Tue, 5 Nov 2024 20:55:43 +0100 Subject: [PATCH 03/18] Add CPU tests --- .../instances/common/reduce.cpp | 27 +++++++++++++++++++ .../single_layer_tests/reduce_ops.cpp | 23 ++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/common/reduce.cpp b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/common/reduce.cpp index f962c20e1566f5..a6c522fc4e1cc1 100644 --- a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/common/reduce.cpp +++ b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/common/reduce.cpp @@ -41,6 +41,12 @@ std::vector> inputShapes_SingleBatch = { {{{}, {{1, 19, 2, 9}}}}, }; +std::vector> inputShapes_Dynmic_ZeroDim = { + {{{-1, -1, -1, -1}, {{2, 0, 3, 9}}}}, + {{{2, 0, -1, -1}, {{2, 0, 3, 9}}}}, + {{{2, 0, -1, -1}, {{2, 0, 3, 0}}}} +}; + std::vector cpuParams_4D = { CPUSpecificParams({nchw}, {nchw}, {}, {}), CPUSpecificParams({nhwc}, {nhwc}, {}, {}), @@ -103,6 +109,20 @@ const auto params_MultiAxis_4D_dynamic = testing::Combine( testing::Values(emptyFusingSpec), testing::ValuesIn(additionalConfig())); +const auto params_MultiAxis_4D_dynamic_with_zero = testing::Combine( + testing::Combine( + testing::Values(std::vector{0, 1}), + testing::Values(ov::test::utils::OpType::VECTOR), + testing::ValuesIn(keepDims()), + testing::ValuesIn(reductionTypes()), + testing::ValuesIn(inpOutPrc()), + testing::Values(ElementType::undefined), + testing::Values(ElementType::undefined), + testing::ValuesIn(inputShapes_Dynmic_ZeroDim)), + testing::Values(emptyCPUSpec), + testing::Values(emptyFusingSpec), + testing::ValuesIn(additionalConfig())); + const auto params_Int32 = testing::Combine( testing::Combine( testing::ValuesIn(axes()), @@ -145,6 +165,13 @@ INSTANTIATE_TEST_SUITE_P( ReduceCPULayerTest::getTestCaseName ); +INSTANTIATE_TEST_SUITE_P( + smoke_Reduce_MultiAxis_4D_dynamic_with_zero_CPU, + ReduceCPULayerTest, + params_MultiAxis_4D_dynamic_with_zero, + ReduceCPULayerTest::getTestCaseName +); + INSTANTIATE_TEST_SUITE_P( smoke_Reduce_Int32_CPU, ReduceCPULayerTest, diff --git a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/reduce_ops.cpp b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/reduce_ops.cpp index 297d973a796dd0..9b7ae687e9c81d 100644 --- a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/reduce_ops.cpp +++ b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/single_layer_tests/reduce_ops.cpp @@ -29,6 +29,12 @@ const std::vector> input_shapes = { std::vector{3, 5, 7, 9}, }; +const std::vector> input_shapes_0_dim = { + std::vector{2, 0, 4, 1}, + std::vector{8, 0, 4, 0}, + std::vector{0, 0, 0, 0}, +}; + const std::vector> input_shapes_one_axis = { std::vector{10, 20, 30, 40}, std::vector{3, 5, 7, 9}, @@ -167,6 +173,16 @@ const auto params_reduction_types = testing::Combine( testing::Values(ov::test::utils::DEVICE_CPU) ); +const auto params_empty_input = testing::Combine( + testing::ValuesIn(axes), + testing::Values(op_types[1]), + testing::ValuesIn(keep_dims), + testing::ValuesIn(reduction_types), + testing::Values(model_types[0]), + testing::ValuesIn(input_shapes_0_dim), + testing::Values(ov::test::utils::DEVICE_CPU) +); + const auto params_reduction_types_logical = testing::Combine( testing::Values(std::vector{0, 1, 3}), testing::Values(op_types[1]), @@ -250,6 +266,13 @@ INSTANTIATE_TEST_SUITE_P( ReduceOpsLayerTest::getTestCaseName ); +INSTANTIATE_TEST_SUITE_P( + smoke_Reduce_ReductionTypes_EmptyTensor, + ReduceOpsLayerTest, + params_empty_input, + ReduceOpsLayerTest::getTestCaseName +); + INSTANTIATE_TEST_SUITE_P( smoke_ReduceLogical_ReductionTypes, ReduceOpsLayerTest, From 3aff3e82c19df1e9c772943e2eaa715aca3090cd Mon Sep 17 00:00:00 2001 From: mitruska Date: Tue, 5 Nov 2024 20:58:33 +0100 Subject: [PATCH 04/18] Update Reduce ref impls --- .../reference/include/openvino/reference/reduce_l1.hpp | 3 +++ .../reference/include/openvino/reference/reduce_l2.hpp | 3 +++ .../reference/include/openvino/reference/reduce_max.hpp | 6 ++++++ .../reference/include/openvino/reference/reduce_mean.hpp | 4 ++++ .../reference/include/openvino/reference/reduce_min.hpp | 6 ++++++ .../reference/include/openvino/reference/reduce_prod.hpp | 7 ++++++- .../reference/include/openvino/reference/reduce_sum.hpp | 3 +++ 7 files changed, 31 insertions(+), 1 deletion(-) diff --git a/src/core/reference/include/openvino/reference/reduce_l1.hpp b/src/core/reference/include/openvino/reference/reduce_l1.hpp index cfde6337cf1c70..1f3ee5e47c30ee 100644 --- a/src/core/reference/include/openvino/reference/reduce_l1.hpp +++ b/src/core/reference/include/openvino/reference/reduce_l1.hpp @@ -31,6 +31,9 @@ void reduce_l1(InputIt in, OutputIt out, const Shape& in_shape, const AxisSet& r const auto out_shape = ov::util::reduce(in_shape, reduction_axes); std::fill(out, std::next(out, shape_size(out_shape)), T(0)); + if (shape_size(in_shape) == 0) { + return; + } const auto in_strides = row_major_strides(in_shape); const auto out_strides = row_major_strides(out_shape); diff --git a/src/core/reference/include/openvino/reference/reduce_l2.hpp b/src/core/reference/include/openvino/reference/reduce_l2.hpp index d5c9308903a8e4..162e8448c53cc2 100644 --- a/src/core/reference/include/openvino/reference/reduce_l2.hpp +++ b/src/core/reference/include/openvino/reference/reduce_l2.hpp @@ -31,6 +31,9 @@ void reduce_l2(InputIt in, OutputIt out, const Shape& in_shape, const AxisSet& r const auto out_shape = ov::util::reduce(in_shape, reduction_axes); const auto out_last = std::next(out, shape_size(out_shape)); std::fill(out, out_last, T(0)); + if (shape_size(in_shape) == 0) { + return; + } const auto in_strides = row_major_strides(in_shape); const auto out_strides = row_major_strides(out_shape); diff --git a/src/core/reference/include/openvino/reference/reduce_max.hpp b/src/core/reference/include/openvino/reference/reduce_max.hpp index 8fb0f9caa0dd31..bfea88e3e7d16a 100644 --- a/src/core/reference/include/openvino/reference/reduce_max.hpp +++ b/src/core/reference/include/openvino/reference/reduce_max.hpp @@ -28,6 +28,12 @@ void reduce_max(const T* in, T* out, const Shape& in_shape, const AxisSet& reduc constexpr auto min_value = std::numeric_limits::lowest(); const auto out_shape = util::reduce(in_shape, reduction_axes); + + if (shape_size(in_shape) == 0) { + std::fill_n(out, shape_size(out_shape), T{0}); + return; + } + std::fill(out, std::next(out, shape_size(out_shape)), min_value); const auto in_strides = row_major_strides(in_shape); diff --git a/src/core/reference/include/openvino/reference/reduce_mean.hpp b/src/core/reference/include/openvino/reference/reduce_mean.hpp index 4c46d4ca786d09..f046f4f96197bb 100644 --- a/src/core/reference/include/openvino/reference/reduce_mean.hpp +++ b/src/core/reference/include/openvino/reference/reduce_mean.hpp @@ -26,6 +26,10 @@ void reduce_mean(const T* in, T* out, const Shape& in_shape, const AxisSet& redu reduce_sum(in, out, in_shape, reduction_axes); const auto out_shape = util::reduce(in_shape, reduction_axes); + if (shape_size(in_shape) == 0) { + return; + } + const auto out_size = shape_size(out_shape); const auto count = static_cast(shape_size(in_shape) / out_size); std::transform(out, std::next(out, out_size), out, [count](const T value) { diff --git a/src/core/reference/include/openvino/reference/reduce_min.hpp b/src/core/reference/include/openvino/reference/reduce_min.hpp index 795894789d39a2..10284a14725b33 100644 --- a/src/core/reference/include/openvino/reference/reduce_min.hpp +++ b/src/core/reference/include/openvino/reference/reduce_min.hpp @@ -28,6 +28,12 @@ void reduce_min(const T* in, T* out, const Shape& in_shape, const AxisSet& reduc std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : std::numeric_limits::max(); const auto out_shape = util::reduce(in_shape, reduction_axes); + + if (shape_size(in_shape) == 0) { + std::fill_n(out, shape_size(out_shape), 0); + return; + } + std::fill(out, out + shape_size(out_shape), max_value); const auto in_strides = row_major_strides(in_shape); diff --git a/src/core/reference/include/openvino/reference/reduce_prod.hpp b/src/core/reference/include/openvino/reference/reduce_prod.hpp index cf274eb182730d..91754ae9167101 100644 --- a/src/core/reference/include/openvino/reference/reduce_prod.hpp +++ b/src/core/reference/include/openvino/reference/reduce_prod.hpp @@ -24,8 +24,13 @@ namespace reference { template void reduce_prod(const T* arg, T* out, const Shape& in_shape, const AxisSet& reduction_axes) { const auto out_shape = util::reduce(in_shape, reduction_axes); - std::fill(out, out + shape_size(out_shape), T(1)); + if (shape_size(in_shape) == 0) { + std::fill(out, out + shape_size(out_shape), T(0)); + return; + } + + std::fill(out, out + shape_size(out_shape), T(1)); const auto in_strides = row_major_strides(in_shape); const auto out_strides = row_major_strides(out_shape); diff --git a/src/core/reference/include/openvino/reference/reduce_sum.hpp b/src/core/reference/include/openvino/reference/reduce_sum.hpp index 213527262f9920..551c56827cd48d 100644 --- a/src/core/reference/include/openvino/reference/reduce_sum.hpp +++ b/src/core/reference/include/openvino/reference/reduce_sum.hpp @@ -77,6 +77,9 @@ void reduce_sum(const T* in, T* out, const Shape& in_shape, const AxisSet& reduc const auto out_size = shape_size(out_shape); std::vector cs(out_size, T{0}); std::fill(out, std::next(out, out_size), T{0}); + if (shape_size(in_shape) == 0) { + return; + } const auto in_strides = row_major_strides(in_shape); const auto out_strides = row_major_strides(out_shape); From 510549e23f898c00ec94b84db84228e9b3da428f Mon Sep 17 00:00:00 2001 From: mitruska Date: Tue, 5 Nov 2024 20:59:28 +0100 Subject: [PATCH 05/18] Update convert_reduce_to_pooling transform to skip empty input case --- .../op_conversions/convert_reduce_to_pooling.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/transformations/include/transformations/op_conversions/convert_reduce_to_pooling.hpp b/src/common/transformations/include/transformations/op_conversions/convert_reduce_to_pooling.hpp index b74a0ff538e011..662660b926aa52 100644 --- a/src/common/transformations/include/transformations/op_conversions/convert_reduce_to_pooling.hpp +++ b/src/common/transformations/include/transformations/op_conversions/convert_reduce_to_pooling.hpp @@ -72,7 +72,7 @@ ov::matcher_pass_callback ConvertReduceBase::convert_reduce_to_pooling() { return [&](ov::pass::pattern::Matcher& m) { auto reduce = std::dynamic_pointer_cast(m.get_match_root()); - if (!reduce || transformation_callback(reduce)) { + if (!reduce || transformation_callback(reduce) || ov::shape_size(reduce->input_value(0).get_shape()) == 0) { return false; } From 4e4c3b659fcd0b67497c3a2daf5b0620780be06a Mon Sep 17 00:00:00 2001 From: mitruska Date: Wed, 6 Nov 2024 10:34:00 +0100 Subject: [PATCH 06/18] Fix type warning for 0 --- src/core/reference/include/openvino/reference/reduce_min.hpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/reference/include/openvino/reference/reduce_min.hpp b/src/core/reference/include/openvino/reference/reduce_min.hpp index 10284a14725b33..38d68207bbd16a 100644 --- a/src/core/reference/include/openvino/reference/reduce_min.hpp +++ b/src/core/reference/include/openvino/reference/reduce_min.hpp @@ -30,7 +30,7 @@ void reduce_min(const T* in, T* out, const Shape& in_shape, const AxisSet& reduc const auto out_shape = util::reduce(in_shape, reduction_axes); if (shape_size(in_shape) == 0) { - std::fill_n(out, shape_size(out_shape), 0); + std::fill_n(out, shape_size(out_shape), T{0}); return; } From b67219c1136db74eed53b8beaa834d511c871c98 Mon Sep 17 00:00:00 2001 From: mitruska Date: Wed, 6 Nov 2024 15:15:36 +0100 Subject: [PATCH 07/18] Make filling output type generic --- src/plugins/intel_cpu/src/nodes/reduce.cpp | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/plugins/intel_cpu/src/nodes/reduce.cpp b/src/plugins/intel_cpu/src/nodes/reduce.cpp index fdebb1bb581185..078b4195fc2220 100644 --- a/src/plugins/intel_cpu/src/nodes/reduce.cpp +++ b/src/plugins/intel_cpu/src/nodes/reduce.cpp @@ -2271,17 +2271,16 @@ void Reduce::execute(dnnl::stream strm) { auto dstMemPtr = getDstMemoryAtPort(0); auto srcMemPtr = getSrcMemoryAtPort(REDUCE_DATA); - const auto src_shape = getSrcMemoryAtPort(REDUCE_DATA)->getStaticDims(); + const uint8_t *src_data = srcMemPtr->getDataAs(); + uint8_t *dst_data = dstMemPtr->getDataAs(); + + const auto& src_shape = getSrcMemoryAtPort(REDUCE_DATA)->getStaticDims(); if ((shape_size(src_shape) == 0 || srcMemPtr->getSize() == 0) && dstMemPtr->getSize() > 0) { // If input is empty fill ouptut with zero - auto dst_shape = getDstMemoryAtPort(0)->getStaticDims(); - std::fill_n(dstMemPtr->getDataAs(), shape_size(dst_shape), 0.f); + std::fill_n(dst_data, dstMemPtr->getSize(), uint8_t{0}); return; } - const uint8_t *src_data = srcMemPtr->getDataAs(); - uint8_t *dst_data = dstMemPtr->getDataAs(); - if (jit_mode) { if (is_hybrid_layout) { dst_data = reinterpret_cast(prc_mem.get_data_handle()); From 50888453e16dce0281f4d008994ca5acfd6dca2f Mon Sep 17 00:00:00 2001 From: mitruska Date: Wed, 6 Nov 2024 15:20:38 +0100 Subject: [PATCH 08/18] Align default values for ReduceProd/Min/Max --- .../reference/include/openvino/reference/reduce_max.hpp | 5 +---- .../reference/include/openvino/reference/reduce_min.hpp | 5 +---- .../reference/include/openvino/reference/reduce_prod.hpp | 4 +--- src/plugins/intel_cpu/src/nodes/reduce.cpp | 3 +-- .../template/tests/functional/op_reference/reduce_max.cpp | 8 +++++--- .../template/tests/functional/op_reference/reduce_min.cpp | 4 +++- .../tests/functional/op_reference/reduce_prod.cpp | 8 +++++--- 7 files changed, 17 insertions(+), 20 deletions(-) diff --git a/src/core/reference/include/openvino/reference/reduce_max.hpp b/src/core/reference/include/openvino/reference/reduce_max.hpp index bfea88e3e7d16a..6ed7818538bcd8 100644 --- a/src/core/reference/include/openvino/reference/reduce_max.hpp +++ b/src/core/reference/include/openvino/reference/reduce_max.hpp @@ -28,14 +28,11 @@ void reduce_max(const T* in, T* out, const Shape& in_shape, const AxisSet& reduc constexpr auto min_value = std::numeric_limits::lowest(); const auto out_shape = util::reduce(in_shape, reduction_axes); - + std::fill(out, std::next(out, shape_size(out_shape)), min_value); if (shape_size(in_shape) == 0) { - std::fill_n(out, shape_size(out_shape), T{0}); return; } - std::fill(out, std::next(out, shape_size(out_shape)), min_value); - const auto in_strides = row_major_strides(in_shape); const auto out_strides = row_major_strides(out_shape); diff --git a/src/core/reference/include/openvino/reference/reduce_min.hpp b/src/core/reference/include/openvino/reference/reduce_min.hpp index 38d68207bbd16a..bc4f687abfb336 100644 --- a/src/core/reference/include/openvino/reference/reduce_min.hpp +++ b/src/core/reference/include/openvino/reference/reduce_min.hpp @@ -28,14 +28,11 @@ void reduce_min(const T* in, T* out, const Shape& in_shape, const AxisSet& reduc std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : std::numeric_limits::max(); const auto out_shape = util::reduce(in_shape, reduction_axes); - + std::fill(out, out + shape_size(out_shape), max_value); if (shape_size(in_shape) == 0) { - std::fill_n(out, shape_size(out_shape), T{0}); return; } - std::fill(out, out + shape_size(out_shape), max_value); - const auto in_strides = row_major_strides(in_shape); const auto out_strides = row_major_strides(out_shape); diff --git a/src/core/reference/include/openvino/reference/reduce_prod.hpp b/src/core/reference/include/openvino/reference/reduce_prod.hpp index 91754ae9167101..c53d26f6545fb7 100644 --- a/src/core/reference/include/openvino/reference/reduce_prod.hpp +++ b/src/core/reference/include/openvino/reference/reduce_prod.hpp @@ -24,13 +24,11 @@ namespace reference { template void reduce_prod(const T* arg, T* out, const Shape& in_shape, const AxisSet& reduction_axes) { const auto out_shape = util::reduce(in_shape, reduction_axes); - + std::fill(out, out + shape_size(out_shape), T(1)); if (shape_size(in_shape) == 0) { - std::fill(out, out + shape_size(out_shape), T(0)); return; } - std::fill(out, out + shape_size(out_shape), T(1)); const auto in_strides = row_major_strides(in_shape); const auto out_strides = row_major_strides(out_shape); diff --git a/src/plugins/intel_cpu/src/nodes/reduce.cpp b/src/plugins/intel_cpu/src/nodes/reduce.cpp index 078b4195fc2220..8bc4d9b4615dc9 100644 --- a/src/plugins/intel_cpu/src/nodes/reduce.cpp +++ b/src/plugins/intel_cpu/src/nodes/reduce.cpp @@ -2276,8 +2276,7 @@ void Reduce::execute(dnnl::stream strm) { const auto& src_shape = getSrcMemoryAtPort(REDUCE_DATA)->getStaticDims(); if ((shape_size(src_shape) == 0 || srcMemPtr->getSize() == 0) && dstMemPtr->getSize() > 0) { - // If input is empty fill ouptut with zero - std::fill_n(dst_data, dstMemPtr->getSize(), uint8_t{0}); + init_dst_data(dst_data, dstMemPtr->getSize()); return; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_max.cpp b/src/plugins/template/tests/functional/op_reference/reduce_max.cpp index e831c4089fdd2a..3486db387b3559 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_max.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_max.cpp @@ -80,14 +80,16 @@ std::vector generateReductionParams(const bool keep_dims) { element::Type(IN_ET), std::vector{27}))}; if (keep_dims == false) { + const auto default_val = std::numeric_limits::lowest(); params.push_back(ReductionParams( ReductionType::Max, keep_dims, std::vector{1, 2}, reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), - reference_tests::Tensor(Shape{2}, - element::Type(IN_ET), - std::vector{0, 0}))); // Keep dims false, tensor filled with zero + reference_tests::Tensor( + Shape{2}, + element::Type(IN_ET), + std::vector{default_val, default_val}))); // Keep dims false, tensor filled with lowest } return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_min.cpp b/src/plugins/template/tests/functional/op_reference/reduce_min.cpp index 45bd0ebe8656db..fd77c59d9156fe 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_min.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_min.cpp @@ -80,6 +80,8 @@ std::vector generateReductionParams(const bool keep_dims) { element::Type(IN_ET), std::vector{1}))}; if (keep_dims == false) { + constexpr auto max_value = + std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : std::numeric_limits::max(); params.push_back(ReductionParams( ReductionType::Min, keep_dims, @@ -87,7 +89,7 @@ std::vector generateReductionParams(const bool keep_dims) { reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), reference_tests::Tensor(Shape{2}, element::Type(IN_ET), - std::vector{0, 0}))); // Keep dims false, tensor filled with zero + std::vector{max_value, max_value}))); // Keep dims false, tensor filled with max or inf } return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_prod.cpp b/src/plugins/template/tests/functional/op_reference/reduce_prod.cpp index de94fc58143da2..380c772ccaf4e6 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_prod.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_prod.cpp @@ -75,14 +75,16 @@ std::vector generateReductionParams(const bool keep_dims) { 22 * 23 * 24, 25 * 26 * 27}))}; if (keep_dims == false) { + const T default_val = T{1}; params.push_back(ReductionParams( ReductionType::Prod, keep_dims, std::vector{1, 2}, reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), - reference_tests::Tensor(Shape{2}, - element::Type(IN_ET), - std::vector{0, 0}))); // Keep dims false, tensor filled with zero + reference_tests::Tensor( + Shape{2}, + element::Type(IN_ET), + std::vector{default_val, default_val}))); // Keep dims false, tensor filled with one } return params; } From 763dba13fb282c8e8e663ae9719a3bd16aba4c4b Mon Sep 17 00:00:00 2001 From: mitruska Date: Wed, 6 Nov 2024 16:34:44 +0100 Subject: [PATCH 09/18] Updat ref tests to check keep_dims for empty input --- .../functional/op_reference/reduce_l1.cpp | 19 ++++++++------- .../functional/op_reference/reduce_l2.cpp | 19 ++++++++------- .../functional/op_reference/reduce_max.cpp | 23 ++++++++++-------- .../functional/op_reference/reduce_mean.cpp | 19 ++++++++------- .../functional/op_reference/reduce_min.cpp | 24 +++++++++++-------- .../functional/op_reference/reduce_prod.cpp | 22 +++++++++-------- .../functional/op_reference/reduce_sum.cpp | 19 ++++++++------- 7 files changed, 83 insertions(+), 62 deletions(-) diff --git a/src/plugins/template/tests/functional/op_reference/reduce_l1.cpp b/src/plugins/template/tests/functional/op_reference/reduce_l1.cpp index 90663b539ed94b..ca6c632686ebe9 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_l1.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_l1.cpp @@ -25,16 +25,19 @@ std::vector generateReductionParams(const bool keep_dims) { reference_tests::Tensor(reduce(Shape{3, 2, 2}, AxisSet{2}, keep_dims), element::Type(IN_ET), std::vector{3, 7, 11, 15, 19, 23}))}; + auto out_shape_from_empty = Shape{2, 1, 1}; if (keep_dims == false) { - params.push_back(ReductionParams( - ReductionType::L1, - keep_dims, - std::vector{1, 2}, - reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), - reference_tests::Tensor(Shape{2}, - element::Type(IN_ET), - std::vector{0, 0}))); // Keep dims false, tensor filled with zero + out_shape_from_empty = Shape{2}; } + params.push_back(ReductionParams( + ReductionType::L1, + keep_dims, + std::vector{1, 2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), + reference_tests::Tensor(out_shape_from_empty, + element::Type(IN_ET), + std::vector{0, 0}))); + return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_l2.cpp b/src/plugins/template/tests/functional/op_reference/reduce_l2.cpp index 3f73a2571546b9..0fc05eaf445720 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_l2.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_l2.cpp @@ -29,16 +29,19 @@ std::vector generateReductionParams(const bool keep_dims) { reference_tests::Tensor(reduce(Shape{3, 2, 2}, AxisSet{2}, keep_dims), element::Type(IN_ET), std::vector{2.23606798, 5.0, 7.81024968, 10.63014581, 13.45362405, 16.2788206}))}; + auto out_shape_from_empty = Shape{2, 1, 1}; if (keep_dims == false) { - params.push_back(ReductionParams( - ReductionType::L2, - keep_dims, - std::vector{1, 2}, - reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), - reference_tests::Tensor(Shape{2}, - element::Type(IN_ET), - std::vector{0, 0}))); // Keep dims false, tensor filled with zero + out_shape_from_empty = Shape{2}; } + params.push_back(ReductionParams( + ReductionType::L2, + keep_dims, + std::vector{1, 2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), + reference_tests::Tensor(out_shape_from_empty, + element::Type(IN_ET), + std::vector{0, 0}))); + return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_max.cpp b/src/plugins/template/tests/functional/op_reference/reduce_max.cpp index 3486db387b3559..1dcca8abd3d4ff 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_max.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_max.cpp @@ -79,18 +79,21 @@ std::vector generateReductionParams(const bool keep_dims) { reference_tests::Tensor(reduce(Shape{3, 3, 3}, AxisSet{0, 1, 2}, keep_dims), element::Type(IN_ET), std::vector{27}))}; + auto out_shape_from_empty = Shape{2, 1, 1}; if (keep_dims == false) { - const auto default_val = std::numeric_limits::lowest(); - params.push_back(ReductionParams( - ReductionType::Max, - keep_dims, - std::vector{1, 2}, - reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), - reference_tests::Tensor( - Shape{2}, - element::Type(IN_ET), - std::vector{default_val, default_val}))); // Keep dims false, tensor filled with lowest + out_shape_from_empty = Shape{2}; } + const auto default_val = std::numeric_limits::lowest(); + params.push_back(ReductionParams( + ReductionType::Max, + keep_dims, + std::vector{1, 2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), + reference_tests::Tensor( + out_shape_from_empty, + element::Type(IN_ET), + std::vector{default_val, default_val}))); + return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_mean.cpp b/src/plugins/template/tests/functional/op_reference/reduce_mean.cpp index b369853ffbf7e8..1c533ab35877f9 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_mean.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_mean.cpp @@ -41,16 +41,19 @@ std::vector generateReductionParams(const bool keep_dims) { reference_tests::Tensor(reduce(Shape{3, 2}, AxisSet{1}, keep_dims), element::Type(IN_ET), std::vector{1.5, 3.5, 5.5}))}; + auto out_shape_from_empty = Shape{2, 1, 1}; if (keep_dims == false) { - params.push_back(ReductionParams( - ReductionType::Mean, - keep_dims, - std::vector{1, 2}, - reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), - reference_tests::Tensor(Shape{2}, - element::Type(IN_ET), - std::vector{0, 0}))); // Keep dims false, tensor filled with zero + out_shape_from_empty = Shape{2}; } + params.push_back(ReductionParams( + ReductionType::Mean, + keep_dims, + std::vector{1, 2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), + reference_tests::Tensor(out_shape_from_empty, + element::Type(IN_ET), + std::vector{0, 0}))); + return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_min.cpp b/src/plugins/template/tests/functional/op_reference/reduce_min.cpp index fd77c59d9156fe..b941e9865bf49a 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_min.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_min.cpp @@ -79,18 +79,22 @@ std::vector generateReductionParams(const bool keep_dims) { reference_tests::Tensor(reduce(Shape{3, 3, 3}, AxisSet{0, 1, 2}, keep_dims), element::Type(IN_ET), std::vector{1}))}; + auto out_shape_from_empty = Shape{2, 1, 1}; if (keep_dims == false) { - constexpr auto max_value = - std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : std::numeric_limits::max(); - params.push_back(ReductionParams( - ReductionType::Min, - keep_dims, - std::vector{1, 2}, - reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), - reference_tests::Tensor(Shape{2}, - element::Type(IN_ET), - std::vector{max_value, max_value}))); // Keep dims false, tensor filled with max or inf + out_shape_from_empty = Shape{2}; } + constexpr auto max_value = + std::numeric_limits::has_infinity ? std::numeric_limits::infinity() : std::numeric_limits::max(); + params.push_back(ReductionParams( + ReductionType::Min, + keep_dims, + std::vector{1, 2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), + reference_tests::Tensor( + out_shape_from_empty, + element::Type(IN_ET), + std::vector{max_value, max_value}))); + return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_prod.cpp b/src/plugins/template/tests/functional/op_reference/reduce_prod.cpp index 380c772ccaf4e6..ee37a320ab1f48 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_prod.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_prod.cpp @@ -74,18 +74,20 @@ std::vector generateReductionParams(const bool keep_dims) { 19 * 20 * 21, 22 * 23 * 24, 25 * 26 * 27}))}; + auto out_shape_from_empty = Shape{2, 1, 1}; if (keep_dims == false) { - const T default_val = T{1}; - params.push_back(ReductionParams( - ReductionType::Prod, - keep_dims, - std::vector{1, 2}, - reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), - reference_tests::Tensor( - Shape{2}, - element::Type(IN_ET), - std::vector{default_val, default_val}))); // Keep dims false, tensor filled with one + out_shape_from_empty = Shape{2}; } + const T default_val = T{1}; + params.push_back(ReductionParams( + ReductionType::Prod, + keep_dims, + std::vector{1, 2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), + reference_tests::Tensor(out_shape_from_empty, + element::Type(IN_ET), + std::vector{default_val, default_val}))); + return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_sum.cpp b/src/plugins/template/tests/functional/op_reference/reduce_sum.cpp index 89f76f110505bf..6495b85517eda1 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_sum.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_sum.cpp @@ -121,16 +121,19 @@ std::vector generateReductionParams(const bool keep_dims) { reference_tests::Tensor(reduce(Shape{3, 3, 3, 3, 3}, AxisSet{0, 1, 2, 3, 4}, keep_dims), element::Type(IN_ET), std::vector{243}))}; + auto out_shape_from_empty = Shape{2, 1, 1}; if (keep_dims == false) { - params.push_back(ReductionParams( - ReductionType::Sum, - keep_dims, - std::vector{1, 2}, - reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), - reference_tests::Tensor(Shape{2}, - element::Type(IN_ET), - std::vector{0, 0}))); // Keep dims false, tensor filled with zero + out_shape_from_empty = Shape{2}; } + params.push_back(ReductionParams( + ReductionType::Sum, + keep_dims, + std::vector{1, 2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), + reference_tests::Tensor(out_shape_from_empty, + element::Type(IN_ET), + std::vector{0, 0}))); + return params; } From 86f21109b9354a9fedfd64db61286e54eada0755 Mon Sep 17 00:00:00 2001 From: mitruska Date: Thu, 7 Nov 2024 09:32:01 +0100 Subject: [PATCH 10/18] Align tests format --- .../template/tests/functional/op_reference/reduce_l1.cpp | 4 +--- .../template/tests/functional/op_reference/reduce_l2.cpp | 4 +--- .../template/tests/functional/op_reference/reduce_max.cpp | 5 +---- .../template/tests/functional/op_reference/reduce_mean.cpp | 4 +--- .../template/tests/functional/op_reference/reduce_min.cpp | 5 +---- .../template/tests/functional/op_reference/reduce_prod.cpp | 4 +--- .../template/tests/functional/op_reference/reduce_sum.cpp | 4 +--- 7 files changed, 7 insertions(+), 23 deletions(-) diff --git a/src/plugins/template/tests/functional/op_reference/reduce_l1.cpp b/src/plugins/template/tests/functional/op_reference/reduce_l1.cpp index ca6c632686ebe9..0959179c65d4f8 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_l1.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_l1.cpp @@ -34,9 +34,7 @@ std::vector generateReductionParams(const bool keep_dims) { keep_dims, std::vector{1, 2}, reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), - reference_tests::Tensor(out_shape_from_empty, - element::Type(IN_ET), - std::vector{0, 0}))); + reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{0, 0}))); return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_l2.cpp b/src/plugins/template/tests/functional/op_reference/reduce_l2.cpp index 0fc05eaf445720..9550dd74a29f11 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_l2.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_l2.cpp @@ -38,9 +38,7 @@ std::vector generateReductionParams(const bool keep_dims) { keep_dims, std::vector{1, 2}, reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), - reference_tests::Tensor(out_shape_from_empty, - element::Type(IN_ET), - std::vector{0, 0}))); + reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{0, 0}))); return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_max.cpp b/src/plugins/template/tests/functional/op_reference/reduce_max.cpp index 1dcca8abd3d4ff..06cda9c50041b1 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_max.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_max.cpp @@ -89,10 +89,7 @@ std::vector generateReductionParams(const bool keep_dims) { keep_dims, std::vector{1, 2}, reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), - reference_tests::Tensor( - out_shape_from_empty, - element::Type(IN_ET), - std::vector{default_val, default_val}))); + reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{default_val, default_val}))); return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_mean.cpp b/src/plugins/template/tests/functional/op_reference/reduce_mean.cpp index 1c533ab35877f9..1e324f8e703578 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_mean.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_mean.cpp @@ -50,9 +50,7 @@ std::vector generateReductionParams(const bool keep_dims) { keep_dims, std::vector{1, 2}, reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), - reference_tests::Tensor(out_shape_from_empty, - element::Type(IN_ET), - std::vector{0, 0}))); + reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{0, 0}))); return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_min.cpp b/src/plugins/template/tests/functional/op_reference/reduce_min.cpp index b941e9865bf49a..2d35d802622bcb 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_min.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_min.cpp @@ -90,10 +90,7 @@ std::vector generateReductionParams(const bool keep_dims) { keep_dims, std::vector{1, 2}, reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), - reference_tests::Tensor( - out_shape_from_empty, - element::Type(IN_ET), - std::vector{max_value, max_value}))); + reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{max_value, max_value}))); return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_prod.cpp b/src/plugins/template/tests/functional/op_reference/reduce_prod.cpp index ee37a320ab1f48..b6557626d149c9 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_prod.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_prod.cpp @@ -84,9 +84,7 @@ std::vector generateReductionParams(const bool keep_dims) { keep_dims, std::vector{1, 2}, reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), - reference_tests::Tensor(out_shape_from_empty, - element::Type(IN_ET), - std::vector{default_val, default_val}))); + reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{default_val, default_val}))); return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_sum.cpp b/src/plugins/template/tests/functional/op_reference/reduce_sum.cpp index 6495b85517eda1..c4720321f59318 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_sum.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_sum.cpp @@ -130,9 +130,7 @@ std::vector generateReductionParams(const bool keep_dims) { keep_dims, std::vector{1, 2}, reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), - reference_tests::Tensor(out_shape_from_empty, - element::Type(IN_ET), - std::vector{0, 0}))); + reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{0, 0}))); return params; } From 0537fc66b105000e9b66dbe651f28b7bbd50a1ba Mon Sep 17 00:00:00 2001 From: mitruska Date: Thu, 7 Nov 2024 11:44:14 +0100 Subject: [PATCH 11/18] Ensure not proceeding for an empty output --- src/plugins/intel_cpu/src/nodes/reduce.cpp | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/src/plugins/intel_cpu/src/nodes/reduce.cpp b/src/plugins/intel_cpu/src/nodes/reduce.cpp index 8bc4d9b4615dc9..b3214488987486 100644 --- a/src/plugins/intel_cpu/src/nodes/reduce.cpp +++ b/src/plugins/intel_cpu/src/nodes/reduce.cpp @@ -2274,9 +2274,11 @@ void Reduce::execute(dnnl::stream strm) { const uint8_t *src_data = srcMemPtr->getDataAs(); uint8_t *dst_data = dstMemPtr->getDataAs(); - const auto& src_shape = getSrcMemoryAtPort(REDUCE_DATA)->getStaticDims(); - if ((shape_size(src_shape) == 0 || srcMemPtr->getSize() == 0) && dstMemPtr->getSize() > 0) { - init_dst_data(dst_data, dstMemPtr->getSize()); + const auto& src_shape = srcMemPtr->getStaticDims(); + if ((shape_size(src_shape) == 0 || srcMemPtr->getSize() == 0)) { + if (dstMemPtr->getSize() > 0) { + init_dst_data(dst_data, dstMemPtr->getSize()); + } return; } From 6e97dea30ab9f5e82d0d7cd7f21f8eae9dfa1fb4 Mon Sep 17 00:00:00 2001 From: mitruska Date: Fri, 15 Nov 2024 15:05:58 +0100 Subject: [PATCH 12/18] Move and add fusing tests for CPU --- .../instances/common/reduce.cpp | 26 ---------- .../instances/x64/reduce.cpp | 52 ++++++++++++++++++- 2 files changed, 51 insertions(+), 27 deletions(-) diff --git a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/common/reduce.cpp b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/common/reduce.cpp index a6c522fc4e1cc1..daada1ce839f91 100644 --- a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/common/reduce.cpp +++ b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/common/reduce.cpp @@ -41,12 +41,6 @@ std::vector> inputShapes_SingleBatch = { {{{}, {{1, 19, 2, 9}}}}, }; -std::vector> inputShapes_Dynmic_ZeroDim = { - {{{-1, -1, -1, -1}, {{2, 0, 3, 9}}}}, - {{{2, 0, -1, -1}, {{2, 0, 3, 9}}}}, - {{{2, 0, -1, -1}, {{2, 0, 3, 0}}}} -}; - std::vector cpuParams_4D = { CPUSpecificParams({nchw}, {nchw}, {}, {}), CPUSpecificParams({nhwc}, {nhwc}, {}, {}), @@ -109,20 +103,6 @@ const auto params_MultiAxis_4D_dynamic = testing::Combine( testing::Values(emptyFusingSpec), testing::ValuesIn(additionalConfig())); -const auto params_MultiAxis_4D_dynamic_with_zero = testing::Combine( - testing::Combine( - testing::Values(std::vector{0, 1}), - testing::Values(ov::test::utils::OpType::VECTOR), - testing::ValuesIn(keepDims()), - testing::ValuesIn(reductionTypes()), - testing::ValuesIn(inpOutPrc()), - testing::Values(ElementType::undefined), - testing::Values(ElementType::undefined), - testing::ValuesIn(inputShapes_Dynmic_ZeroDim)), - testing::Values(emptyCPUSpec), - testing::Values(emptyFusingSpec), - testing::ValuesIn(additionalConfig())); - const auto params_Int32 = testing::Combine( testing::Combine( testing::ValuesIn(axes()), @@ -165,12 +145,6 @@ INSTANTIATE_TEST_SUITE_P( ReduceCPULayerTest::getTestCaseName ); -INSTANTIATE_TEST_SUITE_P( - smoke_Reduce_MultiAxis_4D_dynamic_with_zero_CPU, - ReduceCPULayerTest, - params_MultiAxis_4D_dynamic_with_zero, - ReduceCPULayerTest::getTestCaseName -); INSTANTIATE_TEST_SUITE_P( smoke_Reduce_Int32_CPU, diff --git a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/x64/reduce.cpp b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/x64/reduce.cpp index 302e47fd45aa84..c5381a871954be 100644 --- a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/x64/reduce.cpp +++ b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/x64/reduce.cpp @@ -53,6 +53,12 @@ std::vector> inputShapes_SingleBatch_dyn = { {{{{1, 5}, 19, {1, 5}, {1, 10}}, {{1, 19, 2, 2}, {1, 19, 2, 9}}}}, }; +std::vector> inputShapes_Dynmic_ZeroDim = { + {{{-1, -1, -1, -1}, {{2, 0, 3, 9}}}}, + {{{2, 0, -1, -1}, {{2, 0, 3, 9}}}}, + {{{2, 0, -1, -1}, {{2, 0, 3, 0}}}} +}; + std::vector cpuParams_3D = { CPUSpecificParams({ncw}, {ncw}, {}, {}), }; @@ -699,7 +705,51 @@ INSTANTIATE_TEST_SUITE_P( ReduceCPULayerTest::getTestCaseName ); + +/* ================================ 2.3 Empty dims ================================ */ +const auto params_MultiAxis_4D_dynamic_with_zero = testing::Combine( + testing::Combine( + testing::ValuesIn(axesND()), + testing::Values(ov::test::utils::OpType::VECTOR), + testing::ValuesIn(keepDims()), + testing::ValuesIn(reductionTypes()), + testing::ValuesIn(inpOutPrc()), + testing::Values(ElementType::undefined), + testing::Values(ElementType::undefined), + testing::ValuesIn(inputShapes_Dynmic_ZeroDim)), + testing::Values(emptyCPUSpec), + testing::Values(emptyFusingSpec), + testing::ValuesIn(additionalConfig())); + +const auto params_MultiAxis_4D_dynamic_with_zero_fusing = testing::Combine( + testing::Combine( + testing::ValuesIn(axesNDFusing), + testing::Values(ov::test::utils::OpType::VECTOR), + testing::ValuesIn(keepDims()), + testing::ValuesIn(reductionTypes()), + testing::ValuesIn(inpOutPrc()), + testing::Values(ElementType::undefined), + testing::Values(ElementType::undefined), + testing::ValuesIn(inputShapes_Dynmic_ZeroDim)), + testing::Values(emptyCPUSpec), + testing::Values(fusingSwish), + testing::ValuesIn(additionalConfig())); + +INSTANTIATE_TEST_SUITE_P( + smoke_Reduce_MultiAxis_4D_dynamic_with_zero_CPU, + ReduceCPULayerTest, + params_MultiAxis_4D_dynamic_with_zero, + ReduceCPULayerTest::getTestCaseName +); + +INSTANTIATE_TEST_SUITE_P( + smoke_Reduce_MultiAxis_4D_dynamic_with_zero_fusing_CPU, + ReduceCPULayerTest, + params_MultiAxis_4D_dynamic_with_zero_fusing, + ReduceCPULayerTest::getTestCaseName +); + } // namespace } // namespace Reduce } // namespace test -} // namespace ov \ No newline at end of file +} // namespace ov From 15967a0ae8c737fb89db91e3d06c3eb7aaba89ed Mon Sep 17 00:00:00 2001 From: mitruska Date: Fri, 15 Nov 2024 15:07:14 +0100 Subject: [PATCH 13/18] Apply reduce_kernel_post_process --- src/plugins/intel_cpu/src/nodes/reduce.cpp | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/plugins/intel_cpu/src/nodes/reduce.cpp b/src/plugins/intel_cpu/src/nodes/reduce.cpp index b3214488987486..aa69d3d36f2f10 100644 --- a/src/plugins/intel_cpu/src/nodes/reduce.cpp +++ b/src/plugins/intel_cpu/src/nodes/reduce.cpp @@ -2278,6 +2278,10 @@ void Reduce::execute(dnnl::stream strm) { if ((shape_size(src_shape) == 0 || srcMemPtr->getSize() == 0)) { if (dstMemPtr->getSize() > 0) { init_dst_data(dst_data, dstMemPtr->getSize()); + const bool skip_post_process = getAlgorithm() == Algorithm::ReduceMean || attr.get()->post_ops_.len() == 0; + if (!skip_post_process) { + reduce_kernel_post_process(dst_data); + } } return; } From 9755831d89b4c2294d3a5a45891204e930425259 Mon Sep 17 00:00:00 2001 From: mitruska Date: Fri, 15 Nov 2024 15:08:01 +0100 Subject: [PATCH 14/18] Add arm tests --- .../custom/single_layer_tests/instances/arm/reduce.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/arm/reduce.cpp b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/arm/reduce.cpp index 6d1aa855c31865..313465eeb20a3e 100644 --- a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/arm/reduce.cpp +++ b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/arm/reduce.cpp @@ -18,6 +18,8 @@ namespace { std::vector> inputShapes_5D = { {{{}, {{2, 19, 2, 2, 9}}}}, + {{{}, {{0, 19, 2, 2, 9}}}}, + {{{}, {{1, 0, 0, 2, 9}}}}, }; const std::vector> axes5D = { From 17d18055251501fdd6328bffd717bcacbf624922 Mon Sep 17 00:00:00 2001 From: mitruska Date: Fri, 15 Nov 2024 15:50:12 +0100 Subject: [PATCH 15/18] Reduce ref tests improvements --- .../functional/op_reference/reduce_l1.cpp | 23 ++++++++++++++----- .../functional/op_reference/reduce_l2.cpp | 23 ++++++++++++++----- .../functional/op_reference/reduce_max.cpp | 13 ++++++++++- .../functional/op_reference/reduce_mean.cpp | 23 ++++++++++++++----- .../functional/op_reference/reduce_min.cpp | 12 +++++++++- .../functional/op_reference/reduce_prod.cpp | 12 +++++++++- .../functional/op_reference/reduce_sum.cpp | 23 ++++++++++++++----- 7 files changed, 102 insertions(+), 27 deletions(-) diff --git a/src/plugins/template/tests/functional/op_reference/reduce_l1.cpp b/src/plugins/template/tests/functional/op_reference/reduce_l1.cpp index 0959179c65d4f8..e47295f247b35f 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_l1.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_l1.cpp @@ -29,12 +29,23 @@ std::vector generateReductionParams(const bool keep_dims) { if (keep_dims == false) { out_shape_from_empty = Shape{2}; } - params.push_back(ReductionParams( - ReductionType::L1, - keep_dims, - std::vector{1, 2}, - reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), - reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{0, 0}))); + params.push_back( + ReductionParams(ReductionType::L1, + keep_dims, + std::vector{1, 2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{}), + reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{0, 0}))); + + out_shape_from_empty = Shape{2, 0, 1}; + if (keep_dims == false) { + out_shape_from_empty = Shape{2, 0}; + } + params.push_back( + ReductionParams(ReductionType::L1, + keep_dims, + std::vector{2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{}), + reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{0, 0}))); return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_l2.cpp b/src/plugins/template/tests/functional/op_reference/reduce_l2.cpp index 9550dd74a29f11..b5820f6970ae5b 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_l2.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_l2.cpp @@ -33,13 +33,23 @@ std::vector generateReductionParams(const bool keep_dims) { if (keep_dims == false) { out_shape_from_empty = Shape{2}; } - params.push_back(ReductionParams( - ReductionType::L2, - keep_dims, - std::vector{1, 2}, - reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), - reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{0, 0}))); + params.push_back( + ReductionParams(ReductionType::L2, + keep_dims, + std::vector{1, 2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{}), + reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{0, 0}))); + out_shape_from_empty = Shape{2, 0, 1}; + if (keep_dims == false) { + out_shape_from_empty = Shape{2, 0}; + } + params.push_back( + ReductionParams(ReductionType::L2, + keep_dims, + std::vector{2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{}), + reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{}))); return params; } @@ -56,6 +66,7 @@ std::vector generateReductionParams(const bool keep_dims) { reference_tests::Tensor(reduce(Shape{3, 2, 2}, AxisSet{2}, keep_dims), element::Type(IN_ET), std::vector{2, 5, 8, 11, 13, 16}))}; + return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_max.cpp b/src/plugins/template/tests/functional/op_reference/reduce_max.cpp index 06cda9c50041b1..7ab89fc16d1900 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_max.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_max.cpp @@ -88,9 +88,20 @@ std::vector generateReductionParams(const bool keep_dims) { ReductionType::Max, keep_dims, std::vector{1, 2}, - reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{}), reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{default_val, default_val}))); + out_shape_from_empty = Shape{2, 0, 1}; + if (keep_dims == false) { + out_shape_from_empty = Shape{2, 0}; + } + params.push_back( + ReductionParams(ReductionType::Max, + keep_dims, + std::vector{2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{}), + reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{}))); + return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_mean.cpp b/src/plugins/template/tests/functional/op_reference/reduce_mean.cpp index 1e324f8e703578..07159de9704a30 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_mean.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_mean.cpp @@ -45,12 +45,23 @@ std::vector generateReductionParams(const bool keep_dims) { if (keep_dims == false) { out_shape_from_empty = Shape{2}; } - params.push_back(ReductionParams( - ReductionType::Mean, - keep_dims, - std::vector{1, 2}, - reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), - reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{0, 0}))); + params.push_back( + ReductionParams(ReductionType::Mean, + keep_dims, + std::vector{1, 2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{}), + reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{0, 0}))); + + out_shape_from_empty = Shape{2, 0, 1}; + if (keep_dims == false) { + out_shape_from_empty = Shape{2, 0}; + } + params.push_back( + ReductionParams(ReductionType::Mean, + keep_dims, + std::vector{2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{}), + reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{}))); return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_min.cpp b/src/plugins/template/tests/functional/op_reference/reduce_min.cpp index 2d35d802622bcb..f982af07ab12a5 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_min.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_min.cpp @@ -89,9 +89,19 @@ std::vector generateReductionParams(const bool keep_dims) { ReductionType::Min, keep_dims, std::vector{1, 2}, - reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{}), reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{max_value, max_value}))); + out_shape_from_empty = Shape{2, 0, 1}; + if (keep_dims == false) { + out_shape_from_empty = Shape{2, 0}; + } + params.push_back( + ReductionParams(ReductionType::Min, + keep_dims, + std::vector{2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{}), + reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{}))); return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_prod.cpp b/src/plugins/template/tests/functional/op_reference/reduce_prod.cpp index b6557626d149c9..54e39dad68826f 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_prod.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_prod.cpp @@ -83,9 +83,19 @@ std::vector generateReductionParams(const bool keep_dims) { ReductionType::Prod, keep_dims, std::vector{1, 2}, - reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{}), reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{default_val, default_val}))); + out_shape_from_empty = Shape{2, 0, 1}; + if (keep_dims == false) { + out_shape_from_empty = Shape{2, 0}; + } + params.push_back( + ReductionParams(ReductionType::Prod, + keep_dims, + std::vector{2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{}), + reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{}))); return params; } diff --git a/src/plugins/template/tests/functional/op_reference/reduce_sum.cpp b/src/plugins/template/tests/functional/op_reference/reduce_sum.cpp index c4720321f59318..dd8dcd38635c79 100644 --- a/src/plugins/template/tests/functional/op_reference/reduce_sum.cpp +++ b/src/plugins/template/tests/functional/op_reference/reduce_sum.cpp @@ -125,12 +125,23 @@ std::vector generateReductionParams(const bool keep_dims) { if (keep_dims == false) { out_shape_from_empty = Shape{2}; } - params.push_back(ReductionParams( - ReductionType::Sum, - keep_dims, - std::vector{1, 2}, - reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{1, 2, 3, 4, 5, 6, 7, 8}), - reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{0, 0}))); + params.push_back( + ReductionParams(ReductionType::Sum, + keep_dims, + std::vector{1, 2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{}), + reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{0, 0}))); + + out_shape_from_empty = Shape{2, 0, 1}; + if (keep_dims == false) { + out_shape_from_empty = Shape{2, 0}; + } + params.push_back( + ReductionParams(ReductionType::Sum, + keep_dims, + std::vector{2}, + reference_tests::Tensor({2, 0, 4}, element::Type(IN_ET), std::vector{}), + reference_tests::Tensor(out_shape_from_empty, element::Type(IN_ET), std::vector{}))); return params; } From 7f805e5fa596a4e0af05cace634b21f3fa7786e8 Mon Sep 17 00:00:00 2001 From: mitruska Date: Fri, 15 Nov 2024 15:51:28 +0100 Subject: [PATCH 16/18] Remove early return from reduce refs --- src/core/reference/include/openvino/reference/reduce_l1.hpp | 3 --- src/core/reference/include/openvino/reference/reduce_l2.hpp | 3 --- src/core/reference/include/openvino/reference/reduce_max.hpp | 3 --- src/core/reference/include/openvino/reference/reduce_min.hpp | 3 --- src/core/reference/include/openvino/reference/reduce_prod.hpp | 3 --- src/core/reference/include/openvino/reference/reduce_sum.hpp | 3 --- 6 files changed, 18 deletions(-) diff --git a/src/core/reference/include/openvino/reference/reduce_l1.hpp b/src/core/reference/include/openvino/reference/reduce_l1.hpp index 1f3ee5e47c30ee..cfde6337cf1c70 100644 --- a/src/core/reference/include/openvino/reference/reduce_l1.hpp +++ b/src/core/reference/include/openvino/reference/reduce_l1.hpp @@ -31,9 +31,6 @@ void reduce_l1(InputIt in, OutputIt out, const Shape& in_shape, const AxisSet& r const auto out_shape = ov::util::reduce(in_shape, reduction_axes); std::fill(out, std::next(out, shape_size(out_shape)), T(0)); - if (shape_size(in_shape) == 0) { - return; - } const auto in_strides = row_major_strides(in_shape); const auto out_strides = row_major_strides(out_shape); diff --git a/src/core/reference/include/openvino/reference/reduce_l2.hpp b/src/core/reference/include/openvino/reference/reduce_l2.hpp index 162e8448c53cc2..d5c9308903a8e4 100644 --- a/src/core/reference/include/openvino/reference/reduce_l2.hpp +++ b/src/core/reference/include/openvino/reference/reduce_l2.hpp @@ -31,9 +31,6 @@ void reduce_l2(InputIt in, OutputIt out, const Shape& in_shape, const AxisSet& r const auto out_shape = ov::util::reduce(in_shape, reduction_axes); const auto out_last = std::next(out, shape_size(out_shape)); std::fill(out, out_last, T(0)); - if (shape_size(in_shape) == 0) { - return; - } const auto in_strides = row_major_strides(in_shape); const auto out_strides = row_major_strides(out_shape); diff --git a/src/core/reference/include/openvino/reference/reduce_max.hpp b/src/core/reference/include/openvino/reference/reduce_max.hpp index 6ed7818538bcd8..8fb0f9caa0dd31 100644 --- a/src/core/reference/include/openvino/reference/reduce_max.hpp +++ b/src/core/reference/include/openvino/reference/reduce_max.hpp @@ -29,9 +29,6 @@ void reduce_max(const T* in, T* out, const Shape& in_shape, const AxisSet& reduc const auto out_shape = util::reduce(in_shape, reduction_axes); std::fill(out, std::next(out, shape_size(out_shape)), min_value); - if (shape_size(in_shape) == 0) { - return; - } const auto in_strides = row_major_strides(in_shape); const auto out_strides = row_major_strides(out_shape); diff --git a/src/core/reference/include/openvino/reference/reduce_min.hpp b/src/core/reference/include/openvino/reference/reduce_min.hpp index bc4f687abfb336..795894789d39a2 100644 --- a/src/core/reference/include/openvino/reference/reduce_min.hpp +++ b/src/core/reference/include/openvino/reference/reduce_min.hpp @@ -29,9 +29,6 @@ void reduce_min(const T* in, T* out, const Shape& in_shape, const AxisSet& reduc const auto out_shape = util::reduce(in_shape, reduction_axes); std::fill(out, out + shape_size(out_shape), max_value); - if (shape_size(in_shape) == 0) { - return; - } const auto in_strides = row_major_strides(in_shape); const auto out_strides = row_major_strides(out_shape); diff --git a/src/core/reference/include/openvino/reference/reduce_prod.hpp b/src/core/reference/include/openvino/reference/reduce_prod.hpp index c53d26f6545fb7..cf274eb182730d 100644 --- a/src/core/reference/include/openvino/reference/reduce_prod.hpp +++ b/src/core/reference/include/openvino/reference/reduce_prod.hpp @@ -25,9 +25,6 @@ template void reduce_prod(const T* arg, T* out, const Shape& in_shape, const AxisSet& reduction_axes) { const auto out_shape = util::reduce(in_shape, reduction_axes); std::fill(out, out + shape_size(out_shape), T(1)); - if (shape_size(in_shape) == 0) { - return; - } const auto in_strides = row_major_strides(in_shape); const auto out_strides = row_major_strides(out_shape); diff --git a/src/core/reference/include/openvino/reference/reduce_sum.hpp b/src/core/reference/include/openvino/reference/reduce_sum.hpp index 551c56827cd48d..213527262f9920 100644 --- a/src/core/reference/include/openvino/reference/reduce_sum.hpp +++ b/src/core/reference/include/openvino/reference/reduce_sum.hpp @@ -77,9 +77,6 @@ void reduce_sum(const T* in, T* out, const Shape& in_shape, const AxisSet& reduc const auto out_size = shape_size(out_shape); std::vector cs(out_size, T{0}); std::fill(out, std::next(out, out_size), T{0}); - if (shape_size(in_shape) == 0) { - return; - } const auto in_strides = row_major_strides(in_shape); const auto out_strides = row_major_strides(out_shape); From 0d00b3e5855b272ce014a833bea3d3ac08e48eeb Mon Sep 17 00:00:00 2001 From: xuchen-intel Date: Tue, 19 Nov 2024 09:53:24 +0800 Subject: [PATCH 17/18] [CPU] Finalize fixing empty input of Reduce node on CPU part --- src/plugins/intel_cpu/src/nodes/reduce.cpp | 59 +++++-- src/plugins/intel_cpu/src/nodes/reduce.h | 3 + .../arm/pass/convert_reduce_multi_axis.cpp | 3 + .../single_layer_tests/classes/reduce.cpp | 19 +++ .../single_layer_tests/classes/reduce.hpp | 2 + .../instances/arm/reduce.cpp | 49 +++++- .../instances/common/reduce.cpp | 1 - .../instances/x64/reduce.cpp | 161 ++++++++++++++---- 8 files changed, 245 insertions(+), 52 deletions(-) diff --git a/src/plugins/intel_cpu/src/nodes/reduce.cpp b/src/plugins/intel_cpu/src/nodes/reduce.cpp index aa69d3d36f2f10..5375b27f212b60 100644 --- a/src/plugins/intel_cpu/src/nodes/reduce.cpp +++ b/src/plugins/intel_cpu/src/nodes/reduce.cpp @@ -2020,6 +2020,7 @@ void Reduce::initSupportedPrimitiveDescriptors() { config.outConfs[0].setMemDesc(creatorsMap.at(outFormat)->createSharedDesc(outPrecision, getOutputShapeAtPort(0))); if (useAclExecutor) { +#if defined (OV_CPU_WITH_ACL) std::vector srcMemoryDescs; for (size_t i = 0; i < config.inConfs.size(); i++) { srcMemoryDescs.push_back(config.inConfs[i].getMemDesc()); @@ -2029,11 +2030,27 @@ void Reduce::initSupportedPrimitiveDescriptors() { dstMemoryDescs.push_back(config.outConfs[i].getMemDesc()); } - auto factory = std::make_shared(reduceAttrs, srcMemoryDescs, dstMemoryDescs, + auto attrs = reduceAttrs; + bool apply_ref = customImplPriorities.size() > 0 && customImplPriorities[0] == ref; + bool single_axis_only = one_of(algorithm, Algorithm::ReduceSum, Algorithm::ReduceMax, + Algorithm::ReduceMin, Algorithm::ReduceProd); + // For the case of empty input, transformations ConvertReduceProd(Min, Max, Sum) are disabled to avoid empty output. + // So these 4 reduce modes with empty input reducing more than one axis are not supported by acl executor. Then + // factory->isEmpty() returns true, supportedPrimitiveDescriptors is emtpy. Though we don't actually need these acl + // kernels in execution, here we pass a fake axis {1} to pass assertion of "!supportedPrimitiveDescriptors.empty()" + // in Node::filterSupportedPrimitiveDescriptors(). + if (!apply_ref && !isDynamicNode() && single_axis_only) { + const auto& src_shape = getInputShapeAtPort(REDUCE_DATA).getStaticDims(); + if (shape_size(src_shape) == 0) { + attrs.axes = {1}; + } + } + auto factory = std::make_shared(attrs, srcMemoryDescs, dstMemoryDescs, std::make_shared(context, getImplPriority())); if (!factory->isEmpty()) { supportedPrimitiveDescriptors.push_back({config, impl_type, factory}); } +#endif } else { supportedPrimitiveDescriptors.push_back({config, impl_type}); } @@ -2093,6 +2110,12 @@ bool Reduce::isExecutable() const { } void Reduce::prepareParams() { + auto srcMemPtr = getSrcMemoryAtPort(REDUCE_DATA); + auto dstMemPtr = getDstMemoryAtPort(0); + const auto& src_shape = srcMemPtr->getStaticDims(); + dst_size = dstMemPtr->getSize(); + empty_input = shape_size(src_shape) == 0 || srcMemPtr->getSize() == 0; +#if defined (OV_CPU_WITH_ACL) if (canUseAclExecutor) { std::vector srcMemoryDescs; for (size_t i = 0; i < getParentEdges().size(); i++) { @@ -2102,11 +2125,15 @@ void Reduce::prepareParams() { dstMemoryDescs.push_back(getDstMemoryAtPort(0)->getDescPtr()); auto selectedPD = getSelectedPrimitiveDescriptor(); - aclExecPtr = selectedPD->getExecutorFactoryAs()->makeExecutor(reduceAttrs, srcMemoryDescs, dstMemoryDescs, {}); - selectedPD->setImplementationType(aclExecPtr->getImplType()); - + if (!empty_input) { + aclExecPtr = selectedPD->getExecutorFactoryAs()->makeExecutor(reduceAttrs, srcMemoryDescs, dstMemoryDescs, {}); + selectedPD->setImplementationType(aclExecPtr->getImplType()); + } else { + selectedPD->setImplementationType(acl); + } return; } +#endif src_dims = getParentEdgeAt(REDUCE_DATA)->getMemory().getDesc().getShape().getDims(); std::vector reduce_axes; @@ -2116,9 +2143,7 @@ void Reduce::prepareParams() { reduce_axes = raw_axes; } - auto dstMemPtr = getDstMemoryAtPort(0); const VectorDims &dst_dims = dstMemPtr->getDesc().getShape().getDims(); - dst_size = dstMemPtr->getSize(); calc_process_dst_dims(reduce_axes, dst_dims); if (jit_mode) { set_reduce_dim_flags(); @@ -2274,15 +2299,17 @@ void Reduce::execute(dnnl::stream strm) { const uint8_t *src_data = srcMemPtr->getDataAs(); uint8_t *dst_data = dstMemPtr->getDataAs(); - const auto& src_shape = srcMemPtr->getStaticDims(); - if ((shape_size(src_shape) == 0 || srcMemPtr->getSize() == 0)) { - if (dstMemPtr->getSize() > 0) { - init_dst_data(dst_data, dstMemPtr->getSize()); - const bool skip_post_process = getAlgorithm() == Algorithm::ReduceMean || attr.get()->post_ops_.len() == 0; - if (!skip_post_process) { - reduce_kernel_post_process(dst_data); - } + if (empty_input && dst_size > 0) { +#if defined(OPENVINO_ARCH_X86_64) + output_info_reassign(&dst_data); + init_dst_data(dst_data, dst_size); + output_info_restore(&dst_data); + if (attr.get()->post_ops_.len() != 0) { + reduce_kernel_post_process(dst_data); } +#else + init_dst_data(dst_data, dst_size); +#endif return; } @@ -2291,6 +2318,7 @@ void Reduce::execute(dnnl::stream strm) { dst_data = reinterpret_cast(prc_mem.get_data_handle()); } reduce_type(src_data, dst_data); +#if defined (OV_CPU_WITH_ACL) } else if (aclExecPtr) { std::vector srcMemory; for (size_t i = 0; i < getParentEdges().size(); i++) { @@ -2300,6 +2328,7 @@ void Reduce::execute(dnnl::stream strm) { dstMemory.push_back(getDstMemoryAtPort(0)); aclExecPtr->exec(srcMemory, dstMemory, postOpsDataPtrs.data()); +#endif } else { if (layout == ReduceLayoutType::reduce_ncsp) { auto in_ptr = reinterpret_cast(src_data); @@ -2737,7 +2766,7 @@ inline void Reduce::reduce_kernel_process(const uint8_t *in_p, uint8_t *out_p, s inline void Reduce::reduce_kernel_post_process(uint8_t *out_ptr) { const uint8_t *in_ptr = fuse_low_precision ? static_cast(&intermediate_buf[0]) : nullptr; - const size_t integerDivisor = IB * IC * ID * IH * IW / (OB * OC * OD * OH * OW); + const size_t integerDivisor = empty_input ? 1 : IB * IC * ID * IH * IW / (OB * OC * OD * OH * OW); const float divisor = static_cast(integerDivisor); if (layout == ReduceLayoutType::reduce_ncsp) { parallel_for2d(OB, OC, [&](size_t ob, size_t oc) { diff --git a/src/plugins/intel_cpu/src/nodes/reduce.h b/src/plugins/intel_cpu/src/nodes/reduce.h index 2464686edb1ee4..c790cefb0583b0 100644 --- a/src/plugins/intel_cpu/src/nodes/reduce.h +++ b/src/plugins/intel_cpu/src/nodes/reduce.h @@ -152,6 +152,7 @@ class Reduce : public Node { bool ReduceCDW_opt = false; bool use_aux_kernel = false; bool set_use_aux_kernel = false; + bool empty_input = false; bool ReduceN, ReduceC, ReduceD, ReduceH, ReduceW; size_t IB, IC, ID, IH, IW; size_t OB, OC, OD, OH, OW; @@ -188,9 +189,11 @@ class Reduce : public Node { std::string errorPrefix; +#if defined (OV_CPU_WITH_ACL) ReduceAttrs reduceAttrs; bool canUseAclExecutor = false; std::shared_ptr aclExecPtr = nullptr; +#endif }; } // namespace node diff --git a/src/plugins/intel_cpu/src/transformations/cpu_opset/arm/pass/convert_reduce_multi_axis.cpp b/src/plugins/intel_cpu/src/transformations/cpu_opset/arm/pass/convert_reduce_multi_axis.cpp index 22692e644e6e56..ff5632cb0a5e8f 100644 --- a/src/plugins/intel_cpu/src/transformations/cpu_opset/arm/pass/convert_reduce_multi_axis.cpp +++ b/src/plugins/intel_cpu/src/transformations/cpu_opset/arm/pass/convert_reduce_multi_axis.cpp @@ -23,6 +23,9 @@ ov::matcher_pass_callback ov::intel_cpu::ConvertReduceMultiAxisBase::convert_red if (!reduction_axes) { return false; } + if (!reduce->is_dynamic() && ov::shape_size(input0.get_shape()) == 0) { + return false; + } if (ov::shape_size(input1.get_shape()) <= 1) { return false; } diff --git a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/classes/reduce.cpp b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/classes/reduce.cpp index 66b1d60932b262..b379655338aaf9 100644 --- a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/classes/reduce.cpp +++ b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/classes/reduce.cpp @@ -243,6 +243,25 @@ const std::vector& reductionTypes() { return reductionTypes; } +const std::vector& reductionTypesArithmetic() { + static const std::vector reductionTypesArithmetic = { + ov::test::utils::ReductionType::Mean, + ov::test::utils::ReductionType::Sum, + ov::test::utils::ReductionType::Prod, + ov::test::utils::ReductionType::L1, + ov::test::utils::ReductionType::L2, + }; + return reductionTypesArithmetic; +} + +const std::vector& reductionTypesCompare() { + static const std::vector reductionTypesCompare = { + ov::test::utils::ReductionType::Max, + ov::test::utils::ReductionType::Min, + }; + return reductionTypesCompare; +} + const std::vector& inpOutPrc() { static const std::vector inpOutPrc = {ElementType::f32}; return inpOutPrc; diff --git a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/classes/reduce.hpp b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/classes/reduce.hpp index b3e5fff2ba0b7b..d45cce4b3f913e 100644 --- a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/classes/reduce.hpp +++ b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/classes/reduce.hpp @@ -52,6 +52,8 @@ const std::vector>& axes(); const std::vector>& axesND(); const std::vector& opTypes(); const std::vector& reductionTypes(); +const std::vector& reductionTypesArithmetic(); +const std::vector& reductionTypesCompare(); const std::vector& inpOutPrc(); const std::vector> additionalConfig(); const std::vector> additionalConfigFP32(); diff --git a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/arm/reduce.cpp b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/arm/reduce.cpp index 313465eeb20a3e..366fe9a0ad8b4a 100644 --- a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/arm/reduce.cpp +++ b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/arm/reduce.cpp @@ -18,8 +18,11 @@ namespace { std::vector> inputShapes_5D = { {{{}, {{2, 19, 2, 2, 9}}}}, - {{{}, {{0, 19, 2, 2, 9}}}}, - {{{}, {{1, 0, 0, 2, 9}}}}, +}; + +std::vector> inputShapes_5D_ZeroDim = { + {{{}, {{2, 19, 0, 2, 9}}}}, + {{{}, {{2, 19, 0, 2, 0}}}}, }; const std::vector> axes5D = { @@ -46,6 +49,34 @@ const auto params_MultiAxis_5D = testing::Combine( testing::Values(emptyFusingSpec), testing::ValuesIn(additionalConfig())); +const auto params_MultiAxis_5D_ZeroDim = testing::Combine( + testing::Combine( + testing::ValuesIn(axes5D), + testing::Values(ov::test::utils::OpType::VECTOR), + testing::Values(true), + testing::ValuesIn(reductionTypesArithmetic()), + testing::ValuesIn(inpOutPrc()), + testing::Values(ElementType::undefined), + testing::Values(ElementType::undefined), + testing::ValuesIn(inputShapes_5D_ZeroDim)), + testing::ValuesIn(filterCPUSpecificParams(cpuParams_5D)), + testing::Values(emptyFusingSpec), + testing::ValuesIn(additionalConfig())); + +const auto params_MultiAxis_5D_ZeroDim_Compare = testing::Combine( + testing::Combine( + testing::ValuesIn(axes5D), + testing::Values(ov::test::utils::OpType::VECTOR), + testing::Values(true), + testing::ValuesIn(reductionTypesCompare()), + testing::ValuesIn(inpOutPrc()), + testing::Values(ElementType::undefined), + testing::Values(ElementType::undefined), + testing::ValuesIn(inputShapes_5D_ZeroDim)), + testing::ValuesIn(filterCPUSpecificParams(cpuParams_5D)), + testing::Values(emptyFusingSpec), + testing::ValuesIn(additionalConfigFP32())); + const std::vector> axes5D_ref = { {0} }; @@ -81,6 +112,20 @@ INSTANTIATE_TEST_SUITE_P( ReduceCPULayerTest::getTestCaseName ); +INSTANTIATE_TEST_SUITE_P( + smoke_Reduce_MultiAxis_5D_ZeroDim_CPU, + ReduceCPULayerTest, + params_MultiAxis_5D_ZeroDim, + ReduceCPULayerTest::getTestCaseName +); + +INSTANTIATE_TEST_SUITE_P( + smoke_Reduce_MultiAxis_5D_ZeroDim_Compare_CPU, + ReduceCPULayerTest, + params_MultiAxis_5D_ZeroDim_Compare, + ReduceCPULayerTest::getTestCaseName +); + // Reference implementation testing of ACL unsupported case INSTANTIATE_TEST_SUITE_P( smoke_Reduce_MultiAxis_5D_CPU_ref, diff --git a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/common/reduce.cpp b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/common/reduce.cpp index daada1ce839f91..f962c20e1566f5 100644 --- a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/common/reduce.cpp +++ b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/common/reduce.cpp @@ -145,7 +145,6 @@ INSTANTIATE_TEST_SUITE_P( ReduceCPULayerTest::getTestCaseName ); - INSTANTIATE_TEST_SUITE_P( smoke_Reduce_Int32_CPU, ReduceCPULayerTest, diff --git a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/x64/reduce.cpp b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/x64/reduce.cpp index c5381a871954be..3f4e064c2bf733 100644 --- a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/x64/reduce.cpp +++ b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/x64/reduce.cpp @@ -105,6 +105,17 @@ const std::vector> axesGather = { {3} }; +const std::vector> axesZeroDim { + {1, 3}, + {0, 1, 3}, + {1, 2, 3}, + {0, 1, 2, 3} +}; + +const std::vector> axesZeroDimFusing = { + {1, 3}, +}; + std::vector cpuParams_5D = { CPUSpecificParams({nCdhw16c}, {nCdhw16c}, {}, {}), CPUSpecificParams({ndhwc}, {ndhwc}, {}, {}), @@ -331,6 +342,34 @@ const auto params_SingleBatch = testing::Combine( testing::Values(emptyFusingSpec), testing::ValuesIn(additionalConfig())); +const auto params_DimZero_Arithmetic = testing::Combine( + testing::Combine( + testing::ValuesIn(axesZeroDim), + testing::Values(ov::test::utils::OpType::VECTOR), + testing::ValuesIn(keepDims()), + testing::ValuesIn(reductionTypesArithmetic()), + testing::ValuesIn(inpOutPrc()), + testing::Values(ElementType::undefined), + testing::Values(ElementType::undefined), + testing::ValuesIn(inputShapes_Dynmic_ZeroDim)), + testing::Values(emptyCPUSpec), + testing::Values(emptyFusingSpec), + testing::ValuesIn(additionalConfig())); + +const auto params_DimZero_Compare = testing::Combine( + testing::Combine( + testing::ValuesIn(axesZeroDim), + testing::Values(ov::test::utils::OpType::VECTOR), + testing::ValuesIn(keepDims()), + testing::ValuesIn(reductionTypesCompare()), + testing::ValuesIn(inpOutPrc()), + testing::Values(ElementType::undefined), + testing::Values(ElementType::undefined), + testing::ValuesIn(inputShapes_Dynmic_ZeroDim)), + testing::Values(emptyCPUSpec), + testing::Values(emptyFusingSpec), + testing::ValuesIn(additionalConfigFP32())); + INSTANTIATE_TEST_SUITE_P( smoke_Reduce_OneAxis_CPU, ReduceCPULayerTest, @@ -408,6 +447,20 @@ INSTANTIATE_TEST_SUITE_P( ReduceCPULayerTest::getTestCaseName ); +INSTANTIATE_TEST_SUITE_P( + smoke_Reduce_DimZero_Arithmetic_CPU, + ReduceCPULayerTest, + params_DimZero_Arithmetic, + ReduceCPULayerTest::getTestCaseName +); + +INSTANTIATE_TEST_SUITE_P( + smoke_Reduce_DimZero_Compare_CPU, + ReduceCPULayerTest, + params_DimZero_Compare, + ReduceCPULayerTest::getTestCaseName +); + /* ================================ 1.2 No fusion - Logical ================================ */ const auto params_OneAxis_Logical = testing::Combine( testing::Combine( @@ -606,6 +659,34 @@ const auto params_LowPrecision_fusing = testing::Combine( testing::ValuesIn(fusingParamsSet_LowPrecision), testing::ValuesIn(additionalConfig())); +const auto params_DimZero_Arithmetic_fusing = testing::Combine( + testing::Combine( + testing::ValuesIn(axesZeroDimFusing), + testing::Values(ov::test::utils::OpType::VECTOR), + testing::Values(true), + testing::ValuesIn(reductionTypesArithmetic()), + testing::ValuesIn(inpOutPrc()), + testing::Values(ElementType::undefined), + testing::Values(ElementType::undefined), + testing::ValuesIn(inputShapes_Dynmic_ZeroDim)), + testing::Values(emptyCPUSpec), + testing::ValuesIn(fusingParamsSet), + testing::ValuesIn(additionalConfig())); + +const auto params_DimZero_Compare_fusing = testing::Combine( + testing::Combine( + testing::ValuesIn(axesZeroDimFusing), + testing::Values(ov::test::utils::OpType::VECTOR), + testing::Values(true), + testing::ValuesIn(reductionTypesCompare()), + testing::ValuesIn(inpOutPrc()), + testing::Values(ElementType::undefined), + testing::Values(ElementType::undefined), + testing::ValuesIn(inputShapes_Dynmic_ZeroDim)), + testing::Values(emptyCPUSpec), + testing::ValuesIn(fusingParamsSet), + testing::ValuesIn(additionalConfigFP32())); + INSTANTIATE_TEST_SUITE_P( smoke_Reduce_OneAxis_fusing_CPU, ReduceCPULayerTest, @@ -641,6 +722,20 @@ INSTANTIATE_TEST_SUITE_P( ReduceCPULayerTest::getTestCaseName ); +INSTANTIATE_TEST_SUITE_P( + smoke_Reduce_DimZero_Arithmetic_fusing_CPU, + ReduceCPULayerTest, + params_DimZero_Arithmetic_fusing, + ReduceCPULayerTest::getTestCaseName +); + +INSTANTIATE_TEST_SUITE_P( + smoke_Reduce_DimZero_Compare_fusing_CPU, + ReduceCPULayerTest, + params_DimZero_Compare_fusing, + ReduceCPULayerTest::getTestCaseName +); + /* ================================ 2.2 Fusion - KeepNoDims ================================ */ const auto params_OneAxis_fusing_KeepNoDims = testing::Combine( testing::Combine( @@ -684,6 +779,34 @@ const auto params_MultiAxis_5D_Hybrid_fusing_KeepNoDims = testing::Combine( testing::ValuesIn(fusingParamsSet_KeepNoDims), testing::ValuesIn(additionalConfigFP32())); +const auto params_DimZero_Arithmetic_fusing_KeepNoDims = testing::Combine( + testing::Combine( + testing::ValuesIn(axesZeroDimFusing), + testing::Values(ov::test::utils::OpType::VECTOR), + testing::Values(false), + testing::ValuesIn(reductionTypesArithmetic()), + testing::ValuesIn(inpOutPrc()), + testing::Values(ElementType::undefined), + testing::Values(ElementType::undefined), + testing::ValuesIn(inputShapes_Dynmic_ZeroDim)), + testing::Values(emptyCPUSpec), + testing::ValuesIn(fusingParamsSet_KeepNoDims), + testing::ValuesIn(additionalConfig())); + +const auto params_DimZero_Compare_fusing_KeepNoDims = testing::Combine( + testing::Combine( + testing::ValuesIn(axesZeroDimFusing), + testing::Values(ov::test::utils::OpType::VECTOR), + testing::Values(false), + testing::ValuesIn(reductionTypesCompare()), + testing::ValuesIn(inpOutPrc()), + testing::Values(ElementType::undefined), + testing::Values(ElementType::undefined), + testing::ValuesIn(inputShapes_Dynmic_ZeroDim)), + testing::Values(emptyCPUSpec), + testing::ValuesIn(fusingParamsSet_KeepNoDims), + testing::ValuesIn(additionalConfigFP32())); + INSTANTIATE_TEST_SUITE_P( smoke_Reduce_OneAxis_fusing_KeepNoDims_CPU, ReduceCPULayerTest, @@ -705,47 +828,17 @@ INSTANTIATE_TEST_SUITE_P( ReduceCPULayerTest::getTestCaseName ); - -/* ================================ 2.3 Empty dims ================================ */ -const auto params_MultiAxis_4D_dynamic_with_zero = testing::Combine( - testing::Combine( - testing::ValuesIn(axesND()), - testing::Values(ov::test::utils::OpType::VECTOR), - testing::ValuesIn(keepDims()), - testing::ValuesIn(reductionTypes()), - testing::ValuesIn(inpOutPrc()), - testing::Values(ElementType::undefined), - testing::Values(ElementType::undefined), - testing::ValuesIn(inputShapes_Dynmic_ZeroDim)), - testing::Values(emptyCPUSpec), - testing::Values(emptyFusingSpec), - testing::ValuesIn(additionalConfig())); - -const auto params_MultiAxis_4D_dynamic_with_zero_fusing = testing::Combine( - testing::Combine( - testing::ValuesIn(axesNDFusing), - testing::Values(ov::test::utils::OpType::VECTOR), - testing::ValuesIn(keepDims()), - testing::ValuesIn(reductionTypes()), - testing::ValuesIn(inpOutPrc()), - testing::Values(ElementType::undefined), - testing::Values(ElementType::undefined), - testing::ValuesIn(inputShapes_Dynmic_ZeroDim)), - testing::Values(emptyCPUSpec), - testing::Values(fusingSwish), - testing::ValuesIn(additionalConfig())); - INSTANTIATE_TEST_SUITE_P( - smoke_Reduce_MultiAxis_4D_dynamic_with_zero_CPU, + smoke_Reduce_DimZero_Arithmetic_fusing_KeepNoDims_CPU, ReduceCPULayerTest, - params_MultiAxis_4D_dynamic_with_zero, + params_DimZero_Arithmetic_fusing_KeepNoDims, ReduceCPULayerTest::getTestCaseName ); INSTANTIATE_TEST_SUITE_P( - smoke_Reduce_MultiAxis_4D_dynamic_with_zero_fusing_CPU, + smoke_Reduce_DimZero_Comapre_fusing_KeepNoDims_CPU, ReduceCPULayerTest, - params_MultiAxis_4D_dynamic_with_zero_fusing, + params_DimZero_Arithmetic_fusing_KeepNoDims, ReduceCPULayerTest::getTestCaseName ); From f2e7983b3778c5d77740a643c56b4d6456676e9a Mon Sep 17 00:00:00 2001 From: xuchen-intel Date: Thu, 28 Nov 2024 04:06:17 +0100 Subject: [PATCH 18/18] Apply review comments --- src/plugins/intel_cpu/src/nodes/reduce.cpp | 43 +++---- .../instances/arm/reduce.cpp | 59 ++++------ .../instances/x64/reduce.cpp | 106 +++--------------- 3 files changed, 49 insertions(+), 159 deletions(-) diff --git a/src/plugins/intel_cpu/src/nodes/reduce.cpp b/src/plugins/intel_cpu/src/nodes/reduce.cpp index 5375b27f212b60..1bc0209e0d9c69 100644 --- a/src/plugins/intel_cpu/src/nodes/reduce.cpp +++ b/src/plugins/intel_cpu/src/nodes/reduce.cpp @@ -2030,22 +2030,7 @@ void Reduce::initSupportedPrimitiveDescriptors() { dstMemoryDescs.push_back(config.outConfs[i].getMemDesc()); } - auto attrs = reduceAttrs; - bool apply_ref = customImplPriorities.size() > 0 && customImplPriorities[0] == ref; - bool single_axis_only = one_of(algorithm, Algorithm::ReduceSum, Algorithm::ReduceMax, - Algorithm::ReduceMin, Algorithm::ReduceProd); - // For the case of empty input, transformations ConvertReduceProd(Min, Max, Sum) are disabled to avoid empty output. - // So these 4 reduce modes with empty input reducing more than one axis are not supported by acl executor. Then - // factory->isEmpty() returns true, supportedPrimitiveDescriptors is emtpy. Though we don't actually need these acl - // kernels in execution, here we pass a fake axis {1} to pass assertion of "!supportedPrimitiveDescriptors.empty()" - // in Node::filterSupportedPrimitiveDescriptors(). - if (!apply_ref && !isDynamicNode() && single_axis_only) { - const auto& src_shape = getInputShapeAtPort(REDUCE_DATA).getStaticDims(); - if (shape_size(src_shape) == 0) { - attrs.axes = {1}; - } - } - auto factory = std::make_shared(attrs, srcMemoryDescs, dstMemoryDescs, + auto factory = std::make_shared(reduceAttrs, srcMemoryDescs, dstMemoryDescs, std::make_shared(context, getImplPriority())); if (!factory->isEmpty()) { supportedPrimitiveDescriptors.push_back({config, impl_type, factory}); @@ -2057,16 +2042,22 @@ void Reduce::initSupportedPrimitiveDescriptors() { }; #if defined (OV_CPU_WITH_ACL) - reduceAttrs.operation = algorithm; - reduceAttrs.keepDims = keep_dims; - reduceAttrs.axes = raw_axes; - for (auto &axis : reduceAttrs.axes) { - if (axis < 0) - axis += static_cast(getInputShapeAtPort(REDUCE_DATA).getRank()); + // acl doesn't support empty input + if (!isDynamicNode() && shape_size(getInputShapeAtPort(REDUCE_DATA).getStaticDims()) == 0) { + canUseAclExecutor = false; + } else { + reduceAttrs.operation = algorithm; + reduceAttrs.keepDims = keep_dims; + reduceAttrs.axes = raw_axes; + for (auto &axis : reduceAttrs.axes) { + if (axis < 0) + axis += static_cast(getInputShapeAtPort(REDUCE_DATA).getRank()); + } + pushDesc(LayoutType::nspc, LayoutType::nspc, input_prec, output_prec, impl_desc_type::undef, true); + pushDesc(LayoutType::ncsp, LayoutType::ncsp, input_prec, output_prec, impl_desc_type::undef, true); + canUseAclExecutor = !supportedPrimitiveDescriptors.empty(); } - pushDesc(LayoutType::nspc, LayoutType::nspc, input_prec, output_prec, impl_desc_type::undef, true); - pushDesc(LayoutType::ncsp, LayoutType::ncsp, input_prec, output_prec, impl_desc_type::undef, true); - canUseAclExecutor = !supportedPrimitiveDescriptors.empty(); + if (canUseAclExecutor) return; #endif @@ -2114,7 +2105,7 @@ void Reduce::prepareParams() { auto dstMemPtr = getDstMemoryAtPort(0); const auto& src_shape = srcMemPtr->getStaticDims(); dst_size = dstMemPtr->getSize(); - empty_input = shape_size(src_shape) == 0 || srcMemPtr->getSize() == 0; + empty_input = shape_size(src_shape) == 0; #if defined (OV_CPU_WITH_ACL) if (canUseAclExecutor) { std::vector srcMemoryDescs; diff --git a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/arm/reduce.cpp b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/arm/reduce.cpp index 366fe9a0ad8b4a..45ecc774b5dbf9 100644 --- a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/arm/reduce.cpp +++ b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/arm/reduce.cpp @@ -49,34 +49,6 @@ const auto params_MultiAxis_5D = testing::Combine( testing::Values(emptyFusingSpec), testing::ValuesIn(additionalConfig())); -const auto params_MultiAxis_5D_ZeroDim = testing::Combine( - testing::Combine( - testing::ValuesIn(axes5D), - testing::Values(ov::test::utils::OpType::VECTOR), - testing::Values(true), - testing::ValuesIn(reductionTypesArithmetic()), - testing::ValuesIn(inpOutPrc()), - testing::Values(ElementType::undefined), - testing::Values(ElementType::undefined), - testing::ValuesIn(inputShapes_5D_ZeroDim)), - testing::ValuesIn(filterCPUSpecificParams(cpuParams_5D)), - testing::Values(emptyFusingSpec), - testing::ValuesIn(additionalConfig())); - -const auto params_MultiAxis_5D_ZeroDim_Compare = testing::Combine( - testing::Combine( - testing::ValuesIn(axes5D), - testing::Values(ov::test::utils::OpType::VECTOR), - testing::Values(true), - testing::ValuesIn(reductionTypesCompare()), - testing::ValuesIn(inpOutPrc()), - testing::Values(ElementType::undefined), - testing::Values(ElementType::undefined), - testing::ValuesIn(inputShapes_5D_ZeroDim)), - testing::ValuesIn(filterCPUSpecificParams(cpuParams_5D)), - testing::Values(emptyFusingSpec), - testing::ValuesIn(additionalConfigFP32())); - const std::vector> axes5D_ref = { {0} }; @@ -103,6 +75,20 @@ const auto params_MultiAxis_5D_ref = testing::Combine( testing::Values(emptyFusingSpec), testing::ValuesIn(config_infer_prec_f32)); +const auto params_MultiAxis_5D_ZeroDim_ref = testing::Combine( + testing::Combine( + testing::ValuesIn(axes5D), + testing::Values(ov::test::utils::OpType::VECTOR), + testing::Values(true), + testing::ValuesIn(reductionTypes()), + testing::ValuesIn(inpOutPrc()), + testing::Values(ElementType::undefined), + testing::Values(ElementType::undefined), + testing::ValuesIn(inputShapes_5D_ZeroDim)), + testing::ValuesIn(filterCPUSpecificParams(cpuParams_5D_ref)), + testing::Values(emptyFusingSpec), + testing::ValuesIn(additionalConfigFP32())); + //There are dedicated instences of smoke_Reduce_MultiAxis_5D_CPU test in arm and x64 folders //because ACL does not support 0 as reduction axis INSTANTIATE_TEST_SUITE_P( @@ -112,25 +98,18 @@ INSTANTIATE_TEST_SUITE_P( ReduceCPULayerTest::getTestCaseName ); +// Reference implementation testing of ACL unsupported case INSTANTIATE_TEST_SUITE_P( - smoke_Reduce_MultiAxis_5D_ZeroDim_CPU, - ReduceCPULayerTest, - params_MultiAxis_5D_ZeroDim, - ReduceCPULayerTest::getTestCaseName -); - -INSTANTIATE_TEST_SUITE_P( - smoke_Reduce_MultiAxis_5D_ZeroDim_Compare_CPU, + smoke_Reduce_MultiAxis_5D_CPU_ref, ReduceCPULayerTest, - params_MultiAxis_5D_ZeroDim_Compare, + params_MultiAxis_5D_ref, ReduceCPULayerTest::getTestCaseName ); -// Reference implementation testing of ACL unsupported case INSTANTIATE_TEST_SUITE_P( - smoke_Reduce_MultiAxis_5D_CPU_ref, + smoke_Reduce_MultiAxis_5D_ZeroDim_CPU_ref, ReduceCPULayerTest, - params_MultiAxis_5D_ref, + params_MultiAxis_5D_ZeroDim_ref, ReduceCPULayerTest::getTestCaseName ); diff --git a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/x64/reduce.cpp b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/x64/reduce.cpp index 3f4e064c2bf733..af4319d66a6efe 100644 --- a/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/x64/reduce.cpp +++ b/src/plugins/intel_cpu/tests/functional/custom/single_layer_tests/instances/x64/reduce.cpp @@ -105,13 +105,6 @@ const std::vector> axesGather = { {3} }; -const std::vector> axesZeroDim { - {1, 3}, - {0, 1, 3}, - {1, 2, 3}, - {0, 1, 2, 3} -}; - const std::vector> axesZeroDimFusing = { {1, 3}, }; @@ -161,6 +154,17 @@ const auto fusingFakeQuantizeTranspose = fusingSpecificParams{std::make_shared

fusingParamsFullSet { + emptyFusingSpec, + /* activations */ + fusingSwish, + /* FQ */ + fusingFakeQuantizePerChannelRelu, + fusingFakeQuantizePerTensorRelu, + /* another patterns */ + fusingScaleShift +}; + const std::vector fusingParamsSet { /* activations */ fusingSwish, @@ -342,34 +346,6 @@ const auto params_SingleBatch = testing::Combine( testing::Values(emptyFusingSpec), testing::ValuesIn(additionalConfig())); -const auto params_DimZero_Arithmetic = testing::Combine( - testing::Combine( - testing::ValuesIn(axesZeroDim), - testing::Values(ov::test::utils::OpType::VECTOR), - testing::ValuesIn(keepDims()), - testing::ValuesIn(reductionTypesArithmetic()), - testing::ValuesIn(inpOutPrc()), - testing::Values(ElementType::undefined), - testing::Values(ElementType::undefined), - testing::ValuesIn(inputShapes_Dynmic_ZeroDim)), - testing::Values(emptyCPUSpec), - testing::Values(emptyFusingSpec), - testing::ValuesIn(additionalConfig())); - -const auto params_DimZero_Compare = testing::Combine( - testing::Combine( - testing::ValuesIn(axesZeroDim), - testing::Values(ov::test::utils::OpType::VECTOR), - testing::ValuesIn(keepDims()), - testing::ValuesIn(reductionTypesCompare()), - testing::ValuesIn(inpOutPrc()), - testing::Values(ElementType::undefined), - testing::Values(ElementType::undefined), - testing::ValuesIn(inputShapes_Dynmic_ZeroDim)), - testing::Values(emptyCPUSpec), - testing::Values(emptyFusingSpec), - testing::ValuesIn(additionalConfigFP32())); - INSTANTIATE_TEST_SUITE_P( smoke_Reduce_OneAxis_CPU, ReduceCPULayerTest, @@ -447,20 +423,6 @@ INSTANTIATE_TEST_SUITE_P( ReduceCPULayerTest::getTestCaseName ); -INSTANTIATE_TEST_SUITE_P( - smoke_Reduce_DimZero_Arithmetic_CPU, - ReduceCPULayerTest, - params_DimZero_Arithmetic, - ReduceCPULayerTest::getTestCaseName -); - -INSTANTIATE_TEST_SUITE_P( - smoke_Reduce_DimZero_Compare_CPU, - ReduceCPULayerTest, - params_DimZero_Compare, - ReduceCPULayerTest::getTestCaseName -); - /* ================================ 1.2 No fusion - Logical ================================ */ const auto params_OneAxis_Logical = testing::Combine( testing::Combine( @@ -670,7 +632,7 @@ const auto params_DimZero_Arithmetic_fusing = testing::Combine( testing::Values(ElementType::undefined), testing::ValuesIn(inputShapes_Dynmic_ZeroDim)), testing::Values(emptyCPUSpec), - testing::ValuesIn(fusingParamsSet), + testing::ValuesIn(fusingParamsFullSet), testing::ValuesIn(additionalConfig())); const auto params_DimZero_Compare_fusing = testing::Combine( @@ -684,7 +646,7 @@ const auto params_DimZero_Compare_fusing = testing::Combine( testing::Values(ElementType::undefined), testing::ValuesIn(inputShapes_Dynmic_ZeroDim)), testing::Values(emptyCPUSpec), - testing::ValuesIn(fusingParamsSet), + testing::ValuesIn(fusingParamsFullSet), testing::ValuesIn(additionalConfigFP32())); INSTANTIATE_TEST_SUITE_P( @@ -779,34 +741,6 @@ const auto params_MultiAxis_5D_Hybrid_fusing_KeepNoDims = testing::Combine( testing::ValuesIn(fusingParamsSet_KeepNoDims), testing::ValuesIn(additionalConfigFP32())); -const auto params_DimZero_Arithmetic_fusing_KeepNoDims = testing::Combine( - testing::Combine( - testing::ValuesIn(axesZeroDimFusing), - testing::Values(ov::test::utils::OpType::VECTOR), - testing::Values(false), - testing::ValuesIn(reductionTypesArithmetic()), - testing::ValuesIn(inpOutPrc()), - testing::Values(ElementType::undefined), - testing::Values(ElementType::undefined), - testing::ValuesIn(inputShapes_Dynmic_ZeroDim)), - testing::Values(emptyCPUSpec), - testing::ValuesIn(fusingParamsSet_KeepNoDims), - testing::ValuesIn(additionalConfig())); - -const auto params_DimZero_Compare_fusing_KeepNoDims = testing::Combine( - testing::Combine( - testing::ValuesIn(axesZeroDimFusing), - testing::Values(ov::test::utils::OpType::VECTOR), - testing::Values(false), - testing::ValuesIn(reductionTypesCompare()), - testing::ValuesIn(inpOutPrc()), - testing::Values(ElementType::undefined), - testing::Values(ElementType::undefined), - testing::ValuesIn(inputShapes_Dynmic_ZeroDim)), - testing::Values(emptyCPUSpec), - testing::ValuesIn(fusingParamsSet_KeepNoDims), - testing::ValuesIn(additionalConfigFP32())); - INSTANTIATE_TEST_SUITE_P( smoke_Reduce_OneAxis_fusing_KeepNoDims_CPU, ReduceCPULayerTest, @@ -828,20 +762,6 @@ INSTANTIATE_TEST_SUITE_P( ReduceCPULayerTest::getTestCaseName ); -INSTANTIATE_TEST_SUITE_P( - smoke_Reduce_DimZero_Arithmetic_fusing_KeepNoDims_CPU, - ReduceCPULayerTest, - params_DimZero_Arithmetic_fusing_KeepNoDims, - ReduceCPULayerTest::getTestCaseName -); - -INSTANTIATE_TEST_SUITE_P( - smoke_Reduce_DimZero_Comapre_fusing_KeepNoDims_CPU, - ReduceCPULayerTest, - params_DimZero_Arithmetic_fusing_KeepNoDims, - ReduceCPULayerTest::getTestCaseName -); - } // namespace } // namespace Reduce } // namespace test