From 4f0b1fe74a90c684e519fb4ff976e91a906ff119 Mon Sep 17 00:00:00 2001 From: Aleksandr Voron Date: Thu, 1 Feb 2024 10:47:11 +0100 Subject: [PATCH] [CPU][ARM] Disable f16 eltwise fusing (#22169) * init * check parentNode * move the check in FuseConvolutionSumAndConvolutionSumActivation * force f16 everywhere (rollback this commit before merge) * force f32 deconv and reference on arm * force f32 in reference node for all float types * revert changes in reference node and * remove hardcode * rename fuse map * bring f16 infer back * remove f16 infer prec hardcode --- src/plugins/intel_cpu/src/graph_optimizer.cpp | 19 +++++++++++ src/plugins/intel_cpu/src/nodes/deconv.cpp | 14 ++++---- src/plugins/intel_cpu/src/nodes/reference.cpp | 2 +- .../transformation_pipeline.cpp | 32 +++++++++++++++++-- .../transformations/transformation_pipeline.h | 1 + 5 files changed, 59 insertions(+), 9 deletions(-) diff --git a/src/plugins/intel_cpu/src/graph_optimizer.cpp b/src/plugins/intel_cpu/src/graph_optimizer.cpp index 9808e0e6d11..4b77fec6c0c 100644 --- a/src/plugins/intel_cpu/src/graph_optimizer.cpp +++ b/src/plugins/intel_cpu/src/graph_optimizer.cpp @@ -1376,6 +1376,13 @@ void GraphOptimizer::FuseConvolutionAndSimpleOperationThroughMaxPool(Graph &grap parent++; continue; } +//Disable ACL post-ops in fp16 to avoid performance degradation +#if defined(OPENVINO_ARCH_ARM64) + if (parentNode->getOriginalInputPrecisionAtPort(0) == ov::element::f16) { + parent++; + continue; + } +#endif auto fuseCandidate = childNode->getChildEdgeAt(0)->getChild(); if (parentNode->getType() == Type::BinaryConvolution && !parentNode->canFuse(fuseCandidate)) { @@ -1425,6 +1432,13 @@ void GraphOptimizer::FuseConvolutionAndSimpleOperation(Graph &graph) { parent++; continue; } +//Disable ACL post-ops in fp16 to avoid performance degradation +#if defined(OPENVINO_ARCH_ARM64) + if (parentNode->getOriginalInputPrecisionAtPort(0) == ov::element::f16) { + parent++; + continue; + } +#endif childNode->fuseInto(parentNode); @@ -1683,6 +1697,11 @@ void GraphOptimizer::FuseConvolutionSumAndConvolutionSumActivation(Graph &graph) if (mergedConv->isConstant() && !sum->isConstant()) continue; +//Disable ACL post-ops in fp16 to avoid performance degradation +#if defined(OPENVINO_ARCH_ARM64) + if (mergedConv->getOriginalInputPrecisionAtPort(0) == ov::element::f16) + continue; +#endif // Disable fusing for Add with broadcasing in case of known data ranges. Add with brodcasting triggers // non-optimal code path inside Convolution node, so better to avoid fusing at all. auto shape1 = sum->getInputShapeAtPort(0); diff --git a/src/plugins/intel_cpu/src/nodes/deconv.cpp b/src/plugins/intel_cpu/src/nodes/deconv.cpp index 811ba79b024..3e92fbcd711 100644 --- a/src/plugins/intel_cpu/src/nodes/deconv.cpp +++ b/src/plugins/intel_cpu/src/nodes/deconv.cpp @@ -481,11 +481,13 @@ void Deconvolution::getSupportedDescriptors() { config.outConfs.resize(getOriginalOutputsNumber()); for (size_t i = 0; i < getParentEdges().size(); ++i) { + //force f32 precision to avoid reference inference (CVS-114087) config.inConfs[i].setMemDesc( - creatorsMap.at(format)->createSharedDesc(getOriginalInputPrecisionAtPort(i), getInputShapeAtPort(i))); + creatorsMap.at(format)->createSharedDesc(ov::element::f32, getInputShapeAtPort(i))); } + //force f32 precision to avoid reference inference (CVS-114087) config.outConfs[0].setMemDesc( - creatorsMap.at(format)->createSharedDesc(getOriginalOutputPrecisionAtPort(0), getOutputShapeAtPort(0))); + creatorsMap.at(format)->createSharedDesc(ov::element::f32, getOutputShapeAtPort(0))); std::vector srcMemoryDescs; for (size_t i = 0; i < config.inConfs.size(); i++) { @@ -1218,12 +1220,12 @@ void Deconvolution::initSupportedPrimitiveDescriptors() { for (size_t i = 0; i < getParentEdges().size(); ++i) { config.inConfs[i].setMemDesc( - // ACL expected equal precision - creatorsMap.at(format)->createSharedDesc(getOriginalInputPrecisionAtPort(0), getInputShapeAtPort(i))); + // force f32 precision to avoid reference inference (CVS-114087) + creatorsMap.at(format)->createSharedDesc(ov::element::f32, getInputShapeAtPort(i))); } config.outConfs[0].setMemDesc( - // ACL expected equal precision - creatorsMap.at(format)->createSharedDesc(getOriginalInputPrecisionAtPort(0), getOutputShapeAtPort(0))); + // force f32 precision to avoid reference inference (CVS-114087) + creatorsMap.at(format)->createSharedDesc(ov::element::f32, getOutputShapeAtPort(0))); std::vector srcMemoryDescs; for (size_t i = 0; i < config.inConfs.size(); i++) { diff --git a/src/plugins/intel_cpu/src/nodes/reference.cpp b/src/plugins/intel_cpu/src/nodes/reference.cpp index 819ec8f84fd..947568fa366 100644 --- a/src/plugins/intel_cpu/src/nodes/reference.cpp +++ b/src/plugins/intel_cpu/src/nodes/reference.cpp @@ -143,4 +143,4 @@ ov::TensorVector Reference::prepareOutputs() const { } // namespace node } // namespace intel_cpu -} // namespace ov +} // namespace ov \ No newline at end of file diff --git a/src/plugins/intel_cpu/src/transformations/transformation_pipeline.cpp b/src/plugins/intel_cpu/src/transformations/transformation_pipeline.cpp index e08bec765f9..bd546f844db 100644 --- a/src/plugins/intel_cpu/src/transformations/transformation_pipeline.cpp +++ b/src/plugins/intel_cpu/src/transformations/transformation_pipeline.cpp @@ -167,6 +167,34 @@ bool Transformations::is_decompression_multiply(const_node_ptr& node) const { return false; } +bool Transformations::fuse_type_to_fq(const std::shared_ptr& node, const precisions_map& precisions) { + auto fq = ov::as_type_ptr(node); + if (!fq) + return false; + const auto& from = node->get_output_element_type(0); + auto it = precisions.find(from); + if (it == precisions.end()) + return false; + const auto& to = it->second; + + for (size_t i = 0; i < node->get_input_size(); ++i) { + auto convert_before = std::make_shared(node->input_value(i), from); + node->input(i).replace_source_output(convert_before); + } + + auto consumers = node->output(0).get_target_inputs(); + for (auto& input : consumers) { + const auto consumer = input.get_node(); + if (ov::is_type(consumer) || ov::is_type(consumer)) { + continue; + } + auto convert_after = std::make_shared(node, to); + input.replace_source_output(convert_after); + } + + return true; +} + bool Transformations::fuse_type_to_convert(const std::shared_ptr& node, const precisions_map& precisions) { auto convert = ov::as_type_ptr(node); if (!convert) @@ -297,12 +325,12 @@ void Transformations::PreLpt(const std::vector& defaultPrecis const auto precisions = get_convert_precisions(); if (inferencePrecision == ov::element::f16) { precisions_map fp_convert_precision_map = {{ov::element::f32, ov::element::f16}}; - type_to_fuse_map empty_fuse_map = {}; + type_to_fuse_map f16_fuse_map = {{ov::opset1::FakeQuantize::get_type_info_static(), fuse_type_to_fq}}; const bool keep_precision_sensitive_in_fp32 = true; CPU_REGISTER_PASS_COMMON(manager, ov::pass::ConvertPrecision, fp_convert_precision_map, - empty_fuse_map, + f16_fuse_map, keep_precision_sensitive_in_fp32, false); } diff --git a/src/plugins/intel_cpu/src/transformations/transformation_pipeline.h b/src/plugins/intel_cpu/src/transformations/transformation_pipeline.h index 6979e56230b..e79dadf44da 100644 --- a/src/plugins/intel_cpu/src/transformations/transformation_pipeline.h +++ b/src/plugins/intel_cpu/src/transformations/transformation_pipeline.h @@ -59,6 +59,7 @@ private: bool is_decompression_multiply(const std::shared_ptr& node) const; static bool fuse_type_to_convert(const std::shared_ptr& node, const precisions_map& precisions); + static bool fuse_type_to_fq(const std::shared_ptr& node, const precisions_map& precisions); }; } // namespace intel_cpu