diff --git a/src/core/reference/include/ngraph/runtime/reference/fake_quantize.hpp b/src/core/reference/include/ngraph/runtime/reference/fake_quantize.hpp index 94f613cd91fb75..7982dc841d9184 100644 --- a/src/core/reference/include/ngraph/runtime/reference/fake_quantize.hpp +++ b/src/core/reference/include/ngraph/runtime/reference/fake_quantize.hpp @@ -19,11 +19,62 @@ namespace ngraph { namespace runtime { namespace reference { namespace fake_quantize_details { +inline std::vector calc_broadcast_index_offset(const std::vector& memory_offsets, + const std::vector& broadcast_shape) { + std::vector broadcast_offsets(broadcast_shape.size(), 0); + for (int i = static_cast(broadcast_shape.size()) - 2; i >= 0; --i) { + if (broadcast_shape[i] == 1) { + broadcast_offsets[i] = memory_offsets[i]; + } + } + const auto not_one = [](size_t i) { + return i != 1; + }; + if (std::any_of(broadcast_shape.begin(), broadcast_shape.end(), not_one) && broadcast_shape.back() == 1) { + broadcast_offsets[broadcast_offsets.size() - 1] = 1; + } + if (broadcast_shape.back() == 1) { + for (int i = static_cast(broadcast_shape.size()) - 1; i >= 0; --i) { + if (broadcast_shape[i] != 1) { + broadcast_offsets[i] = memory_offsets[i] - 1; + break; + } + } + } + return broadcast_offsets; +} inline size_t calc_full_broadcast_offset(const std::vector& current_dims, const std::vector& offsets) { return std::inner_product(begin(current_dims), end(current_dims), begin(offsets), uint64_t(0)); } +inline Shape align_shape_sizes(const Shape& shape, const Shape& target_shape, const op::AutoBroadcastSpec& broadcast) { + Shape s; + switch (broadcast.m_type) { + case op::AutoBroadcastType::NONE: { + s = shape; + break; + } + case op::AutoBroadcastType::NUMPY: { + s = Shape(target_shape.size(), 1); + std::copy(begin(shape), end(shape), prev(end(s), shape.size())); + break; + } + case op::AutoBroadcastType::PDPD: { + const size_t axis = + broadcast.m_axis == -1 ? target_shape.size() - shape.size() : static_cast(broadcast.m_axis); + + s = Shape(target_shape.size(), 1); + const auto axis_to_copy = target_shape.size() - axis; + const auto b = begin(shape); + const auto e = b + axis_to_copy; // from e to end(shape) should be only ones + std::copy(b, e, next(begin(s), axis)); + break; + } + } + return s; +} + inline void increment_current_dim(std::vector& current_dims, const std::vector& shape) { size_t incremented_dim_number = current_dims.size(); while (incremented_dim_number-- > 0) { @@ -54,7 +105,9 @@ class QuantizationBound { bound = Bound::aligned; } else { bound = Bound::broadcast; - row_strides = row_major_strides(arg_shape); + const auto arg_memory_offsets = row_major_strides(arg_shape); + const auto unsqueezed_bound_shape = align_shape_sizes(bound_shape, arg_shape, broadcast_spec); + row_strides = calc_broadcast_index_offset(arg_memory_offsets, unsqueezed_bound_shape); } } T get_value(const std::vector& current_dim, size_t idx) const { diff --git a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/skip_tests_config.cpp b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/skip_tests_config.cpp index 5e58623f5a6dc3..224abb78c87322 100644 --- a/src/plugins/intel_cpu/tests/functional/shared_tests_instances/skip_tests_config.cpp +++ b/src/plugins/intel_cpu/tests/functional/shared_tests_instances/skip_tests_config.cpp @@ -186,6 +186,9 @@ std::vector disabledTestPatterns() { R"(smoke_dynamic_BatchSizeOne/RNNSequenceCPUTest.*IS=\(\[1\.\?\.10\]_\[1\.1\.10\]_\[\?\]_\)_TS=\{\(1\.2\.10\)_\(1\.1\.10\)_\(1\)\}_\{\(1\.4\.10\)_\(1\.1\.10\)_\(1\)\}_\{\(1\.8\.10\)_\(1\.1\.10\)_\(1\)\}_seqMode=PURE_SEQ_activations=\(relu\)_clip=0_direction=forward_netPrec=f32__inFmts=ncw\.ntc_outFmts=ncw\.ncw_primitive=ref_any)", // NOLINT // 98151. Not valid sorting for slices in reference. R"(.*UniqueLayerTestCPU.*axis.*True.*)", + // Issue: 104402. Incorrect broadcasting in FQ reference implentation + R"(.*smoke_FakeQuantizeLayerCPUTest_Decompos.*IS=\[4\.5\.6\.6\]_TS=\(\(4\.5\.6\.6\)\)_RS=\(\(1\.1\.6\.6\)\)_\(\(1\.1\.6\.6\)\)_\(\(1\.5\.6\.1\)\)_\(\(1\.5\.1\.6\)\).*)", + R"(.*smoke_FakeQuantizeLayerCPUTest_Decompos.*IS=\[4\.5\.6\.6\]_TS=\(\(4\.5\.6\.6\)\)_RS=\(\(1\.5\.6\.1\)\)_\(\(1\.5\.6\.1\)\)_\(\(1\.5\.6\.1\)\)_\(\(1\.5\.1\.6\)\).*)", }; #define FIX_62820 0