[CPU] Fix Reduce node bug regarding fusing with low precision (#18835)

This commit is contained in:
Chen Xu
2023-08-01 11:56:36 +00:00
committed by GitHub
parent 7fd6563827
commit 74a608592a
3 changed files with 50 additions and 8 deletions
+7 -7
View File
@@ -2154,7 +2154,7 @@ void Reduce::createPrimitive() {
auto reduce_jcp = jcp;
reduce_jcp.dst_dt = fuse_low_precision ? DnnlExtensionUtils::IEPrecisionToDataType(intermediate_prec) : jcp.dst_dt;
jcp.dst_data_size = DnnlExtensionUtils::sizeOfDataType(reduce_jcp.dst_dt);
reduce_jcp.dst_data_size = DnnlExtensionUtils::sizeOfDataType(reduce_jcp.dst_dt);
create_reduce_kernel(reduce_kernel, reduce_jcp);
// set_use_aux_kernel being false means this is a dynamic case, and prepareParams() hasn't been invoked yet.
@@ -2255,7 +2255,7 @@ void Reduce::reduce_type(const uint8_t *in_ptr, uint8_t *out_ptr) {
}
void Reduce::reduce_PLN(const uint8_t *in_ptr, uint8_t *out_ptr) {
output_info_reassign(out_ptr);
output_info_reassign(&out_ptr);
init_dst_data(out_ptr, dst_size);
if (ReduceN && !ReduceC && !ReduceD && !ReduceH && !ReduceW) {
@@ -2472,7 +2472,7 @@ void Reduce::reduce_PLN(const uint8_t *in_ptr, uint8_t *out_ptr) {
void Reduce::reduce_BLK(const uint8_t *in_ptr, uint8_t *out_ptr) {
size_t ICB = div_up(IC, blk_size);
size_t OCB = div_up(OC, blk_size);
output_info_reassign(out_ptr);
output_info_reassign(&out_ptr);
init_dst_data(out_ptr, dst_size);
for (size_t ib = 0; ib < IB; ib++) {
@@ -2552,7 +2552,7 @@ void Reduce::reduce_BLK(const uint8_t *in_ptr, uint8_t *out_ptr) {
void Reduce::reduce_BLK_concern_padding(const uint8_t *in_ptr, uint8_t *out_ptr) {
size_t ICB = div_up(IC, blk_size);
size_t OCB = div_up(OC, blk_size);
output_info_reassign(out_ptr);
output_info_reassign(&out_ptr);
init_dst_data(out_ptr, dst_size);
auto reduceSkipPadding = [&](const uint8_t *in_ptr_ncd, uint8_t *out_ptr_ncd, size_t ic) {
@@ -2720,10 +2720,10 @@ inline void Reduce::reduce_kernel_restore() {
}
}
inline void Reduce::output_info_reassign(uint8_t *out_ptr) {
inline void Reduce::output_info_reassign(uint8_t **out_ptr) {
if (fuse_low_precision) {
tmp_ptr = out_ptr;
out_ptr = static_cast<uint8_t *>(&intermediate_buf[0]);
tmp_ptr = *out_ptr;
*out_ptr = static_cast<uint8_t *>(&intermediate_buf[0]);
tmp_prec = output_prec;
output_prec = intermediate_prec;
tmp_data_size = dst_data_size;
+1 -1
View File
@@ -117,7 +117,7 @@ private:
inline void reduce_kernel_post_process(uint8_t *out_ptr);
inline void reduce_kernel_reassign();
inline void reduce_kernel_restore();
inline void output_info_reassign(uint8_t *out_ptr);
inline void output_info_reassign(uint8_t **out_ptr);
inline void output_info_restore(uint8_t **out_ptr);
inline void init_dst_data(uint8_t *out_ptr, size_t dst_size);
inline void create_hybrid_working_memory();
@@ -6,6 +6,7 @@
#include "shared_test_classes/single_layer/reduce_ops.hpp"
#include "test_utils/cpu_test_utils.hpp"
#include "test_utils/fusing_test_utils.hpp"
#include "lpt_ngraph_functions/common/builders.hpp"
using namespace InferenceEngine;
using namespace CPUTestUtils;
@@ -110,6 +111,22 @@ const std::vector<ngraph::helpers::ReductionType> reductionTypesFusing = {
ngraph::helpers::ReductionType::L2,
};
// This custom subgraph is used to test post-ops fusing case with U8/I8 precision on output,
// since Transpose prevents dequantization part to be fused back into Reduce
const auto fusingFakeQuantizeTranspose = fusingSpecificParams{std::make_shared<postNodesMgr>(std::vector<postNodeBuilder>{
{[](postNodeConfig& cfg){
auto localPrc = cfg.input->get_element_type();
ngraph::Shape newShape(cfg.input->get_output_partial_shape(0).size(), 1);
const auto fakeQuantize = ngraph::builder::makeFakeQuantize(cfg.input, localPrc, 256, newShape);
std::vector<size_t> order(newShape.size());
std::iota(order.begin(), order.end(), 0);
auto last = order[order.size() - 1];
order.pop_back();
order.insert(order.begin(), last);
const auto transpose = ngraph::builder::subgraph::Transpose(order);
return ngraph::builder::subgraph::makeTranspose(fakeQuantize, transpose);
}, "FakeQuantize(PerTensor)"}}), {"FakeQuantize"}};
const std::vector<fusingSpecificParams> fusingParamsSet {
/* activations */
fusingSwish,
@@ -132,6 +149,10 @@ const std::vector<fusingSpecificParams> fusingParamsSet_KeepNoDims {
fusingScaleShift
};
const std::vector<fusingSpecificParams> fusingParamsSet_LowPrecision {
fusingFakeQuantizeTranspose
};
/* ================================ 1.1 No fusion - Arithmetic ================================ */
const auto params_OneAxis = testing::Combine(
testing::Combine(
@@ -492,6 +513,20 @@ const auto params_MultiAxis_5D_fusing = testing::Combine(
testing::ValuesIn(fusingParamsSet),
testing::ValuesIn(additionalConfig()));
const auto params_LowPrecision_fusing = testing::Combine(
testing::Combine(
testing::ValuesIn(axesNDFusing),
testing::Values(ov::test::utils::OpType::VECTOR),
testing::Values(true),
testing::ValuesIn(reductionTypesFusing),
testing::ValuesIn(inpOutPrc()),
testing::Values(ElementType::undefined),
testing::Values(ElementType::undefined),
testing::ValuesIn(inputShapes_dyn)),
testing::ValuesIn(filterCPUSpecificParams(cpuParams_4D)),
testing::ValuesIn(fusingParamsSet_LowPrecision),
testing::ValuesIn(additionalConfig()));
INSTANTIATE_TEST_SUITE_P(
smoke_Reduce_OneAxis_fusing_CPU,
ReduceCPULayerTest,
@@ -513,6 +548,13 @@ INSTANTIATE_TEST_SUITE_P(
ReduceCPULayerTest::getTestCaseName
);
INSTANTIATE_TEST_SUITE_P(
smoke_Reduce_LowPrecision_fusing_CPU,
ReduceCPULayerTest,
params_LowPrecision_fusing,
ReduceCPULayerTest::getTestCaseName
);
/* ================================ 2.2 Fusion - KeepNoDims ================================ */
const auto params_OneAxis_fusing_KeepNoDims = testing::Combine(
testing::Combine(