removed defaultPrecisions as global variable and added as field in Params class (#9185)

fix canConvolutionBeTransformed arguments

fix isAsymmetricOnWeights in GPU plugin

added defaultPrecisions in TestTransformationParams

set new default attribute precisions

try to set const default precisions in network_helper.cpp

apply precision_set

[LPT] Default precisions

rebase

remove extra const

used defaultPrecision in tests

fixed SimpleLowPrecisionTransformer default argument

fixed AttributeParameters default argument

added defaultPrecisions in functions

fix assign_and_read_value_transformation tests

fixed wrong defaultPrecisions definition

fixed ConcatWithNeighborsWithConvolutionTransformation tests

remove getDefaultPrecisions

rebase

remove getDefaultPrecisions from gpu plugin

remove getDefaultPrecisions from lpt_mkldnn_plugin.cpp

use predefined member

update mkldnn_plugin.cpp & lpt_mkldnn_plugin.cpp

resolved conversations

make all lambda captures by ref
This commit is contained in:
Nikita Demashov authored and GitHub committed 2022-02-11 13:41:03 +03:00
1 parent 04c1b9760c
commit 20d2633af0
81 files changed
+486 -362

No files matched your search

@@ -7,6 +7,7 @@
#include <memory>
#include <ngraph/pass/pass.hpp>
#include "low_precision/lpt_visibility.hpp"
#include "low_precision/layer_transformation.hpp"
namespace ngraph {
namespace pass {
@@ -30,5 +31,8 @@ class LP_TRANSFORMATIONS_API AlignQuantizationIntervals;
class ngraph::pass::low_precision::AlignQuantizationIntervals : public ngraph::pass::FunctionPass {
public:
NGRAPH_RTTI_DECLARATION;
AlignQuantizationIntervals(const std::vector<ngraph::element::Type>& defaultPrecisions = ngraph::pass::low_precision::precision_set::int8_support);
bool run_on_model(const std::shared_ptr<ngraph::Function>& m) override;
private:
const std::vector<ngraph::element::Type> defaultPrecisions;
};
@@ -8,6 +8,7 @@
#include <ngraph/pass/pass.hpp>
#include "low_precision/lpt_visibility.hpp"
#include "low_precision/layer_transformation.hpp"
namespace ngraph {
namespace pass {
@@ -31,5 +32,8 @@ class LP_TRANSFORMATIONS_API AlignQuantizationParameters;
class ngraph::pass::low_precision::AlignQuantizationParameters : public ngraph::pass::FunctionPass {
public:
NGRAPH_RTTI_DECLARATION;
AlignQuantizationParameters(const std::vector<ngraph::element::Type> defaultPrecisions = ngraph::pass::low_precision::precision_set::int8_support);
bool run_on_model(const std::shared_ptr<ngraph::Function>& m) override;
private:
const std::vector<ngraph::element::Type> defaultPrecisions;
};
@@ -24,8 +24,10 @@ public:
NGRAPH_RTTI_DECLARATION;
ConvolutionTransformation(const Params& params = Params());
bool transform(TransformationContext& context, ngraph::pattern::Matcher &m) override;
bool isQuantized(const std::shared_ptr<const Node>& layer) const override;
static bool isQuantizedStatic(const std::shared_ptr<const Node>& layer);
bool isQuantized(const std::shared_ptr<const Node>& layer,
const std::vector<ngraph::element::Type>&defaultPrecisions) const override;
static bool isQuantizedStatic(const std::shared_ptr<const Node>& layer,
const std::vector<ngraph::element::Type>& defaultPrecisions);
protected:
size_t getInputChannels(const std::shared_ptr<ngraph::Node> conv) const override;
@@ -24,8 +24,10 @@ public:
ConvolutionBackpropDataTransformation(const Params& params = Params());
bool transform(TransformationContext& context, ngraph::pattern::Matcher &m) override;
bool canBeTransformed(const TransformationContext& context, std::shared_ptr<Node> op) const override;
bool isQuantized(const std::shared_ptr<const Node>& layer) const override;
static bool isQuantizedStatic(const std::shared_ptr<const Node>& layer);
bool isQuantized(const std::shared_ptr<const Node>& layer,
const std::vector<ngraph::element::Type>&defaultPrecisions) const override;
static bool isQuantizedStatic(const std::shared_ptr<const Node>& layer,
const std::vector<ngraph::element::Type>& defaultPrecisions);
protected:
size_t getInputChannels(const std::shared_ptr<ngraph::Node> conv) const override;
@@ -41,7 +41,7 @@ enum class AttributeSource {
template <typename AttributeType, typename OperationType = ngraph::pattern::op::Label>
class ngraph::pass::low_precision::CreateAttribute : public ngraph::pass::low_precision::BaseMatcherPass {
public:
CreateAttribute(const AttributeSource source = AttributeSource::Node) {
CreateAttribute(const AttributeParameters& params = AttributeParameters(), const AttributeSource source = AttributeSource::Node) : BaseMatcherPass(params) {
assert((source == AttributeSource::Node) || (source == AttributeSource::OutputPort));
auto operation = std::is_same<OperationType, pattern::op::Label>::value ?
pattern::any_input() :
@@ -54,7 +54,7 @@ public:
}
{
OV_ITT_SCOPE(FIRST_INFERENCE, itt::domains::LPT_LT, "CreateAttribute");
const auto attribute = AttributeType::create(op, params);
const auto attribute = AttributeType::create(op, this->params);
if (attribute.empty()) {
return false;
}
@@ -50,6 +50,8 @@ public:
return false;
}
std::cout << "CreatePrecisionsDependentAttribute: " << node->get_type_name() << "." << node->get_friendly_name() << std::endl;
{
OV_ITT_SCOPE(FIRST_INFERENCE, itt::domains::LPT_LT, "CreatePrecisionsDependentAttribute");
auto &rt = node->get_rt_info();
@@ -24,8 +24,10 @@ public:
NGRAPH_RTTI_DECLARATION;
GroupConvolutionTransformation(const Params& params = Params());
bool transform(TransformationContext& context, ngraph::pattern::Matcher &m) override;
bool isQuantized(const std::shared_ptr<const Node>& layer) const override;
static bool isQuantizedStatic(const std::shared_ptr<const Node>& layer);
bool isQuantized(const std::shared_ptr<const Node>& layer,
const std::vector<ngraph::element::Type>& defaultPrecisions) const override;
static bool isQuantizedStatic(const std::shared_ptr<const Node>& layer,
const std::vector<ngraph::element::Type>& defaultPrecisions);
protected:
size_t getInputChannels(const std::shared_ptr<ngraph::Node> conv) const override;
@@ -235,18 +235,18 @@ inline std::ostream &operator << (std::ostream &os, const DataPrecision& value)
* @brief Base class for low precision transformation.
*/
class LP_TRANSFORMATIONS_API LayerTransformation : public ngraph::pass::MatcherPass {
static std::vector<ngraph::element::Type> defaultPrecisions;
static std::mutex defaultPrecisionsMutex;
public:
class Params {
public:
Params(
const bool updatePrecisions = true,
element::Type deqPrecision = element::f32,
const std::vector<ngraph::element::Type> defaultPrecisions =
{ ngraph::element::u8, ngraph::element::i8 },
const bool reshapeIgnorePerTensorQuantizationCheck = false) :
updatePrecisions(updatePrecisions),
deqPrecision(deqPrecision),
defaultPrecisions(defaultPrecisions),
reshapeIgnorePerTensorQuantizationCheck(reshapeIgnorePerTensorQuantizationCheck) {}
Params& setUpdatePrecisions(const bool updatePrecisions) {
@@ -259,8 +259,14 @@ public:
return *this;
}
Params& setDefaultPrecisions(const std::vector<ngraph::element::Type>& defaultPrecisions) {
this->defaultPrecisions = defaultPrecisions;
return *this;
}
bool updatePrecisions;
element::Type deqPrecision;
std::vector<ngraph::element::Type> defaultPrecisions;
// to support GPU workarround to keep Reshape and MatMul in FP32
bool reshapeIgnorePerTensorQuantizationCheck;
};
@@ -285,8 +291,11 @@ public:
void setUpdatePrecisions(const bool updatePrecisions);
void setDefaultPrecisions(const std::vector<ngraph::element::Type>& defaultPrecisions);
virtual bool canBeTransformed(const TransformationContext& context, std::shared_ptr<Node> layer) const;
static bool canBeTransformedStatic(const std::shared_ptr<Node>& layer);
static bool canBeTransformedStatic(const std::shared_ptr<Node>& layer,
const std::vector<ngraph::element::Type>& defaultPrecisions = precision_set::int8_support);
bool canSubtractBeHandled(const std::shared_ptr<Node>& op, const FakeQuantizeDequantization& dequantization) const;
@@ -299,12 +308,14 @@ public:
const std::vector<float>& outputHighValues);
static PrecisionDetails getPrecisionDetails(const QuantizationDetails& quantizationDetails);
static bool isAsymmetricQuantization(const std::shared_ptr<const Node>& node);
static bool isAsymmetricQuantization(const std::shared_ptr<const Node>& node,
const std::vector<ngraph::element::Type>& defaultPrecisions = precision_set::int8_support);
// return true if operation can be quantized and false otherwise
// for example: if convolution operation weights are not quantized, then isQuantize returns false and true otherwise
// note: dequantization operations on activations are absent during method execution
virtual bool isQuantized(const std::shared_ptr<const Node>& layer) const;
virtual bool isQuantized(const std::shared_ptr<const Node>& layer,
const std::vector<ngraph::element::Type>& defaultPrecisions) const;
// return true if operation can be preserved for precision
// note: dequantization operations on activations are absent during method execution
@@ -316,9 +327,6 @@ public:
const QuantizationDetails& quantizationDetails,
const std::vector<element::Type>& requiredPrecisions);
static void setDefaultPrecisions(const std::vector<ngraph::element::Type>& precisions);
static std::vector<ngraph::element::Type> getDefaultPrecisions();
protected:
#ifdef LPT_PRINT_DEQUANTIZATION_INFO
static void printDequantizationInfo(const std::shared_ptr<Node>& layer);
@@ -330,6 +338,7 @@ protected:
bool updatePrecisions;
element::Type deqPrecision;
std::vector<ngraph::element::Type> defaultPrecisions;
bool reshapeIgnorePerTensorQuantizationCheck;
static constexpr char originalLayerPostfix[] = "_original";
@@ -42,11 +42,13 @@ public:
NGRAPH_RTTI_DECLARATION;
MarkupOptimizations(
const std::vector<OperationPrecisionRestriction>& precisionRestrictions,
const std::vector<OperationPerTensorQuantizationRestriction>& quantizationRestrictions);
const std::vector<OperationPerTensorQuantizationRestriction>& quantizationRestrictions,
const AttributeParameters& params);
bool run_on_model(const std::shared_ptr<ngraph::Function>& m) override;
private:
const std::vector<OperationPrecisionRestriction>& precisionRestrictions;
const std::vector<OperationPerTensorQuantizationRestriction>& quantizationRestrictions;
const AttributeParameters& params;
};
class LP_TRANSFORMATIONS_API ngraph::pass::low_precision::TypeRelaxedReplacer : public ngraph::pass::GraphRewrite {
@@ -66,7 +68,6 @@ public:
static bool isFunctionQuantized(const std::shared_ptr<const ngraph::Function>& function);
static bool isFQLevelsPresent(const std::shared_ptr<const ngraph::Function>& function, const std::set<size_t>& levels);
static void setDefaultPrecisions(const std::vector<element::Type>& precisions);
protected:
std::vector<OperationPrecisionRestriction> precisionRestrictions;
@@ -7,6 +7,7 @@
#include <memory>
#include <ngraph/pass/pass.hpp>
#include <low_precision/lpt_visibility.hpp>
#include "low_precision/layer_transformation.hpp"
namespace ngraph {
namespace pass {
@@ -29,5 +30,8 @@ class LP_TRANSFORMATIONS_API MarkupAvgPoolPrecisionPreserved;
class ngraph::pass::low_precision::MarkupAvgPoolPrecisionPreserved : public ngraph::pass::FunctionPass {
public:
NGRAPH_RTTI_DECLARATION;
MarkupAvgPoolPrecisionPreserved(const std::vector<ngraph::element::Type> defaultPrecisions = ngraph::pass::low_precision::precision_set::int8_support);
bool run_on_model(const std::shared_ptr<ngraph::Function>& m) override;
private:
const std::vector<ngraph::element::Type> defaultPrecisions;
};
@@ -31,5 +31,8 @@ class LP_TRANSFORMATIONS_API MarkupCanBeQuantized;
class ngraph::pass::low_precision::MarkupCanBeQuantized : public ngraph::pass::FunctionPass {
public:
NGRAPH_RTTI_DECLARATION;
MarkupCanBeQuantized(const std::vector<ngraph::element::Type> defaultPrecisions = { ngraph::element::u8, ngraph::element::i8 });
bool run_on_model(const std::shared_ptr<ngraph::Function>& m) override;
private:
const std::vector<ngraph::element::Type> defaultPrecisions;
};
@@ -48,11 +48,13 @@ public:
};
NGRAPH_RTTI_DECLARATION;
explicit MarkupPrecisions(const std::vector<OperationPrecisionRestriction>& restrictions = {});
explicit MarkupPrecisions(const std::vector<OperationPrecisionRestriction>& restrictions = {},
const std::vector<ngraph::element::Type>& defaultPrecisions = { ngraph::element::u8, ngraph::element::i8 });
bool run_on_model(const std::shared_ptr<ngraph::Function>& m) override;
private:
static bool isPrecisionPreserved(const std::shared_ptr<Node>& node);
static bool isSupported(const std::shared_ptr<Node>& node);
std::unordered_map<std::string, Restriction> restrictionsByOperation;
std::vector<ngraph::element::Type> defaultPrecisions;
};
@@ -31,7 +31,8 @@ public:
bool transform(TransformationContext& context, ngraph::pattern::Matcher &m) override;
bool canBeTransformed(const TransformationContext& context, std::shared_ptr<Node> layer) const override;
bool isPrecisionPreserved(std::shared_ptr<Node> layer) const noexcept override;
bool isQuantized(const std::shared_ptr<const Node>& layer) const override;
bool isQuantized(const std::shared_ptr<const Node>& layer,
const std::vector<ngraph::element::Type>& defaultPrecisions) const override;
static bool canBeTransformedToGroupConvolution(const std::shared_ptr<const Node>& layer);
static bool isDynamicOrScalar(const std::shared_ptr<const Node>& node);
@@ -99,7 +99,8 @@ public:
static std::shared_ptr<opset1::Constant> round(std::shared_ptr<Node> node, element::Type target_type);
static std::shared_ptr<opset1::FakeQuantize> composeFakeQuantize(const std::shared_ptr<opset1::FakeQuantize>& fq);
static std::shared_ptr<opset1::FakeQuantize> composeFakeQuantize(const std::shared_ptr<opset1::FakeQuantize>& fq,
const std::vector<ngraph::element::Type>& defaultPrecisions = precision_set::int8_support);
static std::tuple<std::shared_ptr<Node>, std::shared_ptr<Node>> decomposeFakeQuantize(
std::shared_ptr<opset1::FakeQuantize> fq,
@@ -136,13 +137,18 @@ public:
const bool updatePrecision,
const element::Type deqPrecision = element::f32);
static bool areQuantizeAndDequantizeSupportedForSubtract(const std::shared_ptr<const ngraph::Node>& node);
static bool areQuantizeAndDequantizeSupportedForSubtract(const std::shared_ptr<const ngraph::Node>& node,
const std::vector<ngraph::element::Type>& defaultPrecisions = precision_set::int8_support);
static bool areQuantizeAndDequantizeSupportedForMultiply(const std::shared_ptr<const ngraph::Node>& node);
static bool areQuantizeAndDequantizeSupportedForMultiply(const std::shared_ptr<const ngraph::Node>& node,
const std::vector<ngraph::element::Type>& _defaultPrecisions = precision_set::int8_support);
static bool isQuantizeSupported(const std::shared_ptr<opset1::FakeQuantize>& fakeQuantize);
static FakeQuantizeDequantization getDequantization(const std::shared_ptr<const Node>& node, const size_t parentIndex = 0ul, const bool inPlace = false);
static FakeQuantizeDequantization getDequantization(const std::shared_ptr<const Node>& node,
const std::vector<ngraph::element::Type> _defaultPrecisions = precision_set::int8_support,
const size_t parentIndex = 0ul,
const bool inPlace = false);
static FakeQuantizeDequantization getDequantizationBelow(const std::shared_ptr<Node>& node, const bool convertIsMandatory = false);
@@ -171,7 +177,8 @@ public:
const std::shared_ptr<ngraph::Node>& operation,
const FakeQuantizeDequantization& dequantization,
const bool updatePrecision,
const bool moveSubtract);
const bool moveSubtract,
const std::vector<ngraph::element::Type>& defaultPrecisions = precision_set::int8_support);
static InsertDequantizationResult moveDequantizationBefore(
const std::shared_ptr<ngraph::Node>& operation,
@@ -199,9 +206,13 @@ public:
static std::shared_ptr<Node> fold_fake_quantize(const std::shared_ptr<opset1::FakeQuantize>& fq);
static std::shared_ptr<Node> fold_fake_quantize(const std::shared_ptr<opset1::FakeQuantize>& fq, const bool roundValues, int outChannelsShapeIndex = 0);
static FakeQuantizeDequantization foldDequantization(const std::shared_ptr<Node>& node, const size_t branchIndex, const bool inPlace = false);
static FakeQuantizeDequantization foldDequantization(const std::shared_ptr<Node>& node,
const size_t branchIndex,
const std::vector<ngraph::element::Type>& defaultPrecisions = precision_set::int8_support,
const bool inPlace = false);
static std::shared_ptr<ngraph::Node> separateInStandaloneBranch(std::shared_ptr<ngraph::Node> node);
static std::shared_ptr<ngraph::Node> separateInStandaloneBranch(std::shared_ptr<ngraph::Node> node,
const std::vector<ngraph::element::Type>& defaultPrecisions = precision_set::int8_support);
static std::shared_ptr<opset1::FakeQuantize> fuseConvert(const std::shared_ptr<opset1::FakeQuantize>& fakeQuantize);
@@ -11,6 +11,7 @@
#include <ngraph/variant.hpp>
#include <ngraph/pass/graph_rewrite.hpp>
#include <low_precision/lpt_visibility.hpp>
#include "low_precision/rt_info/attribute_parameters.hpp"
namespace ngraph {
namespace pass {
@@ -33,5 +34,9 @@ class LP_TRANSFORMATIONS_API PropagatePrecisions;
class ngraph::pass::low_precision::PropagatePrecisions : public ngraph::pass::FunctionPass {
public:
NGRAPH_RTTI_DECLARATION;
PropagatePrecisions(const AttributeParameters& params = AttributeParameters());
bool run_on_model(const std::shared_ptr<ngraph::Function>& m) override;
private:
const AttributeParameters params;
};
@@ -39,7 +39,7 @@ class PropagateThroughPrecisionPreserved;
template <typename AttributeType>
class ngraph::pass::low_precision::PropagateThroughPrecisionPreserved : public ngraph::pass::MatcherPass {
public:
PropagateThroughPrecisionPreserved() {
PropagateThroughPrecisionPreserved(const std::vector<ngraph::element::Type>& defaultPrecisions = precision_set::int8_support) {
ngraph::graph_rewrite_callback callback = [&](pattern::Matcher& m) {
auto node = m.get_match_root();
if (transformation_callback(node)) {
@@ -53,7 +53,7 @@ public:
return false;
}
const auto parentRestrictions = getParentInputRestrictions(node);
const auto parentRestrictions = getParentInputRestrictions(node, defaultPrecisions);
if (parentRestrictions.empty()) {
return false;
}
@@ -99,11 +99,11 @@ private:
}
// TODO: possible duplicate: PropagateToInput::getSourceOutputAttribute
std::vector<ov::Any> getParentInputRestrictions(
const std::shared_ptr<ngraph::Node> node) {
std::vector<ov::Any> getParentInputRestrictions(const std::shared_ptr<ngraph::Node> node,
const std::vector<ngraph::element::Type>& defaultPrecisions) {
std::vector<ov::Any> parentAttributes;
auto getInput = [](const std::shared_ptr<ngraph::Node>& node, const size_t index) -> Input<Node> {
const auto dequantization = NetworkHelper::getDequantization(node, index);
auto getInput = [&defaultPrecisions](const std::shared_ptr<ngraph::Node>& node, const size_t index) -> Input<Node> {
const auto dequantization = NetworkHelper::getDequantization(node, defaultPrecisions, index);
if (!dequantization.empty() &&
ov::is_type<opset1::Convert>(dequantization.data.get_node()) &&
(dequantization.data.get_node()->get_input_size() == 1ul) &&
@@ -38,7 +38,7 @@ class PropagateToInput;
template <typename AttributeType>
class ngraph::pass::low_precision::PropagateToInput : public ngraph::pass::MatcherPass {
public:
PropagateToInput() {
PropagateToInput(const std::vector<ngraph::element::Type>& defaultPrecisions = { ngraph::element::u8, ngraph::element::i8 }) {
ngraph::graph_rewrite_callback callback = [&](pattern::Matcher& m) {
auto node = m.get_match_root();
if (transformation_callback(node)) {
@@ -49,7 +49,7 @@ public:
OV_ITT_SCOPE(FIRST_INFERENCE, itt::domains::LPT_LT, "PropagateToInput");
for (auto input : node->inputs()) {
auto parentAttribute = getSourceOutputAttribute(input);
auto parentAttribute = getSourceOutputAttribute(input, defaultPrecisions);
if (parentAttribute == nullptr) {
continue;
}
@@ -78,9 +78,9 @@ public:
private:
// TODO: possible duplicate: PropagateThroughPrecisionPreserved::getParentInputRestrictions
ov::Any getSourceOutputAttribute(const Input<Node>& input) {
auto getInput = [](const Input<Node>& input) {
const auto dequantization = NetworkHelper::getDequantization(input.get_node()->shared_from_this(), input.get_index());
ov::Any getSourceOutputAttribute(const Input<Node>& input, const std::vector<ngraph::element::Type>& defaultPrecisions) {
auto getInput = [&defaultPrecisions](const Input<Node>& input) {
const auto dequantization = NetworkHelper::getDequantization(input.get_node()->shared_from_this(), defaultPrecisions, input.get_index());
if (!dequantization.empty() &&
ov::is_type<opset1::Convert>(dequantization.data.get_node()) &&
(dequantization.data.get_node()->get_input_size() == 1ul) &&
@@ -9,6 +9,10 @@
class LP_TRANSFORMATIONS_API AttributeParameters {
public:
AttributeParameters(const ngraph::element::Type deqPrecision = ngraph::element::f32) : deqPrecision(deqPrecision) {}
AttributeParameters(
const ngraph::element::Type deqPrecision = ngraph::element::f32,
const std::vector<ngraph::element::Type> defaultPrecisions = { ngraph::element::u8, ngraph::element::i8 })
: deqPrecision(deqPrecision), defaultPrecisions(defaultPrecisions) {}
ngraph::element::Type deqPrecision;
std::vector<ngraph::element::Type> defaultPrecisions;
};
@@ -70,7 +70,7 @@ public:
static ov::Any create(
const std::shared_ptr<ngraph::Node>& node,
const AttributeParameters& params);
const AttributeParameters& params = AttributeParameters());
void merge(std::vector<ov::Any>& attributes);
std::string to_string() const override;
@@ -33,7 +33,7 @@ public:
static ov::Any create(
const std::shared_ptr<ngraph::Node>& node,
const AttributeParameters& params);
const AttributeParameters& params = AttributeParameters());
void merge(std::vector<ov::Any>& attributes);
std::string to_string() const override;
};
@@ -37,7 +37,7 @@ class UpdateSharedPrecisionPreserved;
template <typename AttributeType, typename ExpectedAttributeType = AttributeType>
class ngraph::pass::low_precision::UpdateSharedPrecisionPreserved : public ngraph::pass::MatcherPass {
public:
UpdateSharedPrecisionPreserved() {
UpdateSharedPrecisionPreserved(const std::vector<ngraph::element::Type>& defaultPrecisions = precision_set::int8_support) {
ngraph::graph_rewrite_callback callback = [&](pattern::Matcher& m) {
auto node = m.get_match_root();
@@ -74,7 +74,7 @@ public:
return false;
}
}
auto parentAttribute = getSourceAttribute(input);
auto parentAttribute = getSourceAttribute(input, defaultPrecisions);
if (parentAttribute.empty()) {
continue;
}
@@ -90,8 +90,8 @@ public:
}
private:
Input<Node> getDequantizationInput(const Input<Node>& input) {
const auto dequantization = NetworkHelper::getDequantization(input.get_node()->shared_from_this(), input.get_index());
Input<Node> getDequantizationInput(const Input<Node>& input, const std::vector<ngraph::element::Type>& defaultPrecisions) {
const auto dequantization = NetworkHelper::getDequantization(input.get_node()->shared_from_this(), defaultPrecisions, input.get_index());
if (!dequantization.empty() &&
(ov::is_type<opset1::Convert>(dequantization.data.get_node())) &&
ov::is_type<opset1::FakeQuantize>(dequantization.data.get_node()->get_input_node_ptr(0))) {
@@ -101,8 +101,8 @@ private:
return input;
}
ov::Any getSourceAttribute(const Input<Node>& input) {
const auto dequantizationInput = getDequantizationInput(input);
ov::Any getSourceAttribute(const Input<Node>& input, const std::vector<ngraph::element::Type>& defaultPrecisions) {
const auto dequantizationInput = getDequantizationInput(input, defaultPrecisions);
const auto output = dequantizationInput.get_source_output();
auto attribute = ngraph::pass::low_precision::getAttribute<AttributeType>(output.get_node()->shared_from_this());
if (attribute.empty()) {
@@ -21,7 +21,8 @@ class LP_TRANSFORMATIONS_API WeightableLayerTransformation : public LayerTransfo
public:
WeightableLayerTransformation(const Params& params);
bool canBeTransformed(const TransformationContext& context, std::shared_ptr<Node> layer) const override;
bool canConvolutionBeTransformed(const TransformationContext& context, std::shared_ptr<Node> layer) const;
bool canConvolutionBeTransformed(const TransformationContext& context, std::shared_ptr<Node> layer,
const std::vector<ngraph::element::Type>& defaultPrecisions) const;
bool isPrecisionPreserved(std::shared_ptr<Node> layer) const noexcept override;
static bool checkPrecisionOnActivation(
@@ -30,7 +31,9 @@ public:
return true;
}
static bool isQuantizedStatic(const std::shared_ptr<const Node>& layer, const bool reshapeIsRequired);
static bool isQuantizedStatic(const std::shared_ptr<const Node>& layer,
const bool reshapeIsRequired,
const std::vector<ngraph::element::Type>& defaultPrecisions = precision_set::int8_support);
protected:
bool decomposeFakeQuantizeForWeightsPath(const std::shared_ptr<Node>& weightableLayer, size_t outChannelsShapeIndex = 0ul) const;
@@ -40,8 +43,9 @@ protected:
public:
static std::shared_ptr<opset1::FakeQuantize> getFakeQuantizeOnWeights(const std::shared_ptr<Node>& node);
static DataPrecision getDataPrecisionOnWeights(const std::shared_ptr<Node>& node);
static bool isAsymmetricOnWeights(const std::shared_ptr<const Node>& node);
static DataPrecision getDataPrecisionOnWeights(const std::shared_ptr<Node>& node, const std::vector<ngraph::element::Type>& defaultPrecisions);
static bool isAsymmetricOnWeights(const std::shared_ptr<const Node>& node,
const std::vector<ngraph::element::Type>& defaultPrecisions = precision_set::int8_support);
};
} // namespace low_precision
@@ -115,10 +115,10 @@ bool AddTransformation::transform(TransformationContext& context, ngraph::patter
return false;
}
NetworkHelper::normalizeDequantization(NetworkHelper::getDequantization(op, 0));
NetworkHelper::normalizeDequantization(NetworkHelper::getDequantization(op, 1));
NetworkHelper::normalizeDequantization(NetworkHelper::getDequantization(op, defaultPrecisions, 0));
NetworkHelper::normalizeDequantization(NetworkHelper::getDequantization(op, defaultPrecisions, 1));
std::shared_ptr<Node> addNode = NetworkHelper::separateInStandaloneBranch(op);
std::shared_ptr<Node> addNode = NetworkHelper::separateInStandaloneBranch(op, defaultPrecisions);
std::shared_ptr<opset1::Add> add = ov::as_type_ptr<opset1::Add>(addNode);
const int fullPathIndex = getNotEmpty(add);
@@ -129,11 +129,11 @@ bool AddTransformation::transform(TransformationContext& context, ngraph::patter
// swap constant multiply and add and possibly fuse to subtract
const auto multiplyBranch = getMultiplyConstBranch(add);
if (multiplyBranch.first != -1) {
NetworkHelper::foldDequantization(add, multiplyBranch.first == 0 ? 1 : 0);
NetworkHelper::foldDequantization(add, multiplyBranch.first == 0 ? 1 : 0, defaultPrecisions);
} else {
// constant folding on dequantization ops (for example: Convert on Subtract)
NetworkHelper::foldDequantization(addNode, 0);
NetworkHelper::foldDequantization(addNode, 1);
NetworkHelper::foldDequantization(addNode, 0, defaultPrecisions);
NetworkHelper::foldDequantization(addNode, 1, defaultPrecisions);
return false;
}
@@ -159,18 +159,18 @@ bool AddTransformation::transform(TransformationContext& context, ngraph::patter
const int emptyPathIndex = fullPathIndex == 0 ? 1 : 0;
if (updatePrecisions) {
const FakeQuantizeDequantization dequantizationEmptyPath = NetworkHelper::getDequantization(add, emptyPathIndex);
const FakeQuantizeDequantization dequantizationEmptyPath = NetworkHelper::getDequantization(add, defaultPrecisions, emptyPathIndex);
if (!dequantizationEmptyPath.empty() && !dequantizationEmptyPath.isLowPrecision()) {
return false;
}
}
const FakeQuantizeDequantization dequantizationEmptyPath = NetworkHelper::foldDequantization(addNode, emptyPathIndex);
const FakeQuantizeDequantization dequantizationEmptyPath = NetworkHelper::foldDequantization(addNode, emptyPathIndex, defaultPrecisions);
std::shared_ptr<Node> subtractEmptyPathValues;
std::shared_ptr<Node> multiplyEmptyPathValues;
std::tie(subtractEmptyPathValues, multiplyEmptyPathValues) = NetworkHelper::createEmptyValues(dequantizationEmptyPath, deqPrecision);
const FakeQuantizeDequantization dequantizationFullPath = NetworkHelper::foldDequantization(addNode, fullPathIndex);
const FakeQuantizeDequantization dequantizationFullPath = NetworkHelper::foldDequantization(addNode, fullPathIndex, defaultPrecisions);
std::shared_ptr<Node> subtractFullPathValues;
std::shared_ptr<Node> multiplyFullPathValues;
std::tie(subtractFullPathValues, multiplyFullPathValues) = NetworkHelper::createEmptyValues(dequantizationFullPath, deqPrecision);
@@ -236,19 +236,19 @@ bool AddTransformation::transform(TransformationContext& context, ngraph::patter
if (fullPathIndex != -1) {
std::shared_ptr<Node> node = add;
NetworkHelper::foldDequantization(node, fullPathIndex);
NetworkHelper::foldDequantization(node, fullPathIndex, defaultPrecisions);
}
return true;
}
bool AddTransformation::canBeTransformed(const TransformationContext& context, std::shared_ptr<Node> layer) const {
const FakeQuantizeDequantization dequantization1 = pass::low_precision::NetworkHelper::getDequantization(layer, 0ul);
const FakeQuantizeDequantization dequantization1 = pass::low_precision::NetworkHelper::getDequantization(layer, defaultPrecisions, 0ul);
if (dequantization1.multiplyHasZeroOrDenormal()) {
return false;
}
const FakeQuantizeDequantization dequantization2 = pass::low_precision::NetworkHelper::getDequantization(layer, 1ul);
const FakeQuantizeDequantization dequantization2 = pass::low_precision::NetworkHelper::getDequantization(layer, defaultPrecisions, 1ul);
if (dequantization2.multiplyHasZeroOrDenormal()) {
return false;
}
@@ -8,18 +8,23 @@
#include "low_precision/create_attribute.hpp"
#include "low_precision/propagate_through_precision_preserved.hpp"
#include "low_precision/rt_info/intervals_alignment_attribute.hpp"
#include "low_precision/rt_info/attribute_parameters.hpp"
using namespace ngraph;
using namespace ngraph::pass::low_precision;
NGRAPH_RTTI_DEFINITION(ngraph::pass::low_precision::AlignQuantizationIntervals, "AlignQuantizationIntervals", 0);
ngraph::pass::low_precision::AlignQuantizationIntervals::AlignQuantizationIntervals(const std::vector<ngraph::element::Type>& defaultPrecisions)
: defaultPrecisions(defaultPrecisions) {}
bool ngraph::pass::low_precision::AlignQuantizationIntervals::run_on_model(const std::shared_ptr<ngraph::Function>& f) {
ngraph::pass::Manager manager;
manager.set_per_pass_validation(false);
std::shared_ptr<ngraph::pass::GraphRewrite> intervalsAlignment = manager.register_pass<ngraph::pass::GraphRewrite>();
intervalsAlignment->add_matcher<low_precision::CreateAttribute<IntervalsAlignmentAttribute, opset1::FakeQuantize>>();
intervalsAlignment->add_matcher<low_precision::PropagateThroughPrecisionPreserved<IntervalsAlignmentAttribute>>();
intervalsAlignment->add_matcher<low_precision::CreateAttribute<IntervalsAlignmentAttribute, opset1::FakeQuantize>>(
AttributeParameters(ngraph::element::f32, defaultPrecisions));
intervalsAlignment->add_matcher<low_precision::PropagateThroughPrecisionPreserved<IntervalsAlignmentAttribute>>(defaultPrecisions);
manager.run_passes(f);
return false;
}
@@ -9,12 +9,16 @@
#include "low_precision/rt_info/quantization_alignment_attribute.hpp"
#include "low_precision/rt_info/per_tensor_quantization_attribute.hpp"
#include "low_precision/update_shared_precision_preserved.hpp"
#include "low_precision/rt_info/attribute_parameters.hpp"
using namespace ngraph;
using namespace ngraph::pass::low_precision;
NGRAPH_RTTI_DEFINITION(ngraph::pass::low_precision::AlignQuantizationParameters, "AlignQuantizationParameters", 0);
ngraph::pass::low_precision::AlignQuantizationParameters::AlignQuantizationParameters(const std::vector<ngraph::element::Type> defaultPrecisions)
: defaultPrecisions(defaultPrecisions) {}
bool ngraph::pass::low_precision::AlignQuantizationParameters::run_on_model(const std::shared_ptr<ngraph::Function>& f) {
ngraph::pass::Manager manager;
manager.set_per_pass_validation(false);
@@ -57,8 +57,8 @@ bool AssignAndReadValueTransformation::transform(TransformationContext& context,
const auto readValue = oldAssign->get_control_dependencies()[0];
oldAssign->remove_control_dependency(readValue);
const auto assign = NetworkHelper::separateInStandaloneBranch(oldAssign);
const auto dequantization = NetworkHelper::getDequantization(assign);
const auto assign = NetworkHelper::separateInStandaloneBranch(oldAssign, defaultPrecisions);
const auto dequantization = NetworkHelper::getDequantization(assign, defaultPrecisions);
auto oldVar = ov::as_type_ptr<op::ReadValueBase>(readValue)->get_variable();
auto variableInfo = oldVar->get_info();
@@ -119,7 +119,7 @@ bool AssignAndReadValueTransformation::canBeTransformed(const TransformationCont
return false;
}
const auto dequantization = NetworkHelper::getDequantization(op);
const auto dequantization = NetworkHelper::getDequantization(op, defaultPrecisions);
return dequantization.subtract == nullptr && dequantization.multiply != nullptr;
}
@@ -38,9 +38,9 @@ bool AvgPoolTransformation::transform(TransformationContext& context, ngraph::pa
return false;
}
const std::shared_ptr<Node> pooling = NetworkHelper::separateInStandaloneBranch(m.get_match_root());
const std::shared_ptr<Node> pooling = NetworkHelper::separateInStandaloneBranch(m.get_match_root(), defaultPrecisions);
const bool updatePrecision = isPrecisionPreserved(pooling);
moveDequantizationAfter(context, pooling, NetworkHelper::getDequantization(pooling), updatePrecision);
moveDequantizationAfter(context, pooling, NetworkHelper::getDequantization(pooling, defaultPrecisions), updatePrecision);
return true;
}
@@ -49,7 +49,7 @@ bool AvgPoolTransformation::canBeTransformed(const TransformationContext& contex
return false;
}
auto dequantization = NetworkHelper::getDequantization(operation);
auto dequantization = NetworkHelper::getDequantization(operation, defaultPrecisions);
return !dequantization.empty();
}
@@ -36,8 +36,8 @@ bool ClampTransformation::transform(TransformationContext& context, ngraph::patt
return false;
}
const std::shared_ptr<Node> clamp = NetworkHelper::separateInStandaloneBranch(m.get_match_root());
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(clamp);
const std::shared_ptr<Node> clamp = NetworkHelper::separateInStandaloneBranch(m.get_match_root(), defaultPrecisions);
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(clamp, defaultPrecisions);
const bool moveSubtract = dequantization.subtract == nullptr ? false : NetworkHelper::isScalarLike(dequantization.subtractConstant);
// issue #43136
@@ -84,7 +84,7 @@ bool ClampTransformation::canBeTransformed(const TransformationContext& context,
return false;
}
const auto dequantization = NetworkHelper::getDequantization(op);
const auto dequantization = NetworkHelper::getDequantization(op, defaultPrecisions);
if (dequantization.multiply == nullptr) {
return false;
}
@@ -47,7 +47,7 @@ bool ConcatTransformation::transform(TransformationContext& context, ngraph::pat
std::vector<FakeQuantizeDequantization> layerDequantizations;
layerDequantizations.reserve(concat->get_input_size());
for (size_t parentIndex = 0ul; parentIndex < concat->get_input_size(); parentIndex++) {
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(concat, parentIndex);
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(concat, defaultPrecisions, parentIndex);
if (dequantization.empty()) {
return false;
}
@@ -237,7 +237,7 @@ bool ConcatTransformation::canBeTransformed(const TransformationContext& context
element::Type precision;
for (size_t i = 0ul; i < concat->get_input_size(); i++) {
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(concat, i);
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(concat, defaultPrecisions, i);
if (dequantization.empty() || (updatePrecisions && !dequantization.isLowPrecision())) {
return false;
}
@@ -43,12 +43,14 @@ ConvolutionTransformation::ConvolutionTransformation(const Params& params) : Wei
this->register_matcher(m, callback);
}
bool ConvolutionTransformation::isQuantized(const std::shared_ptr<const Node>& layer) const {
return ConvolutionTransformation::isQuantizedStatic(layer);
bool ConvolutionTransformation::isQuantized(const std::shared_ptr<const Node>& layer,
const std::vector<ngraph::element::Type>& defaultPrecisions) const {
return ConvolutionTransformation::isQuantizedStatic(layer, defaultPrecisions);
}
bool ConvolutionTransformation::isQuantizedStatic(const std::shared_ptr<const Node>& layer) {
return WeightableLayerTransformation::isQuantizedStatic(layer, false);
bool ConvolutionTransformation::isQuantizedStatic(const std::shared_ptr<const Node>& layer,
const std::vector<ngraph::element::Type>& defaultPrecisions) {
return WeightableLayerTransformation::isQuantizedStatic(layer, false, defaultPrecisions);
}
size_t ConvolutionTransformation::getInputChannels(const std::shared_ptr<ngraph::Node> conv) const {
@@ -60,12 +62,12 @@ size_t ConvolutionTransformation::getInputChannels(const std::shared_ptr<ngraph:
bool ConvolutionTransformation::transform(TransformationContext &context, ngraph::pattern::Matcher &m) {
auto convolution = m.get_match_root();
if (!canConvolutionBeTransformed(context, convolution)) {
if (!canConvolutionBeTransformed(context, convolution, defaultPrecisions)) {
const auto weightInput = convolution->get_input_node_shared_ptr(1);
const auto reshapeFromWeights = ov::as_type_ptr<opset1::Reshape>(weightInput);
FakeQuantizeDequantization dequantization = reshapeFromWeights == nullptr ?
NetworkHelper::getDequantization(convolution, 1ul) :
NetworkHelper::getDequantization(reshapeFromWeights);
NetworkHelper::getDequantization(convolution, defaultPrecisions, 1ul) :
NetworkHelper::getDequantization(reshapeFromWeights, defaultPrecisions);
if (dequantization.empty()) {
const auto fqOnWeights = getFakeQuantizeOnWeights(convolution);
std::shared_ptr<ngraph::Node> resultConstant = NetworkHelper::fold_fake_quantize(fqOnWeights);
@@ -79,19 +81,19 @@ bool ConvolutionTransformation::transform(TransformationContext &context, ngraph
replace_node(weightInput, resultConstant);
}
} else {
NetworkHelper::foldDequantization(dequantization.multiply, 0, true);
NetworkHelper::foldDequantization(dequantization.multiply, 0, defaultPrecisions, true);
}
return true;
}
convolution = NetworkHelper::separateInStandaloneBranch(convolution);
convolution = NetworkHelper::separateInStandaloneBranch(convolution, defaultPrecisions);
const bool fqOnWeightsWasDecomposed = decomposeFakeQuantizeForWeightsPath(convolution);
if (updatePrecisions && !fqOnWeightsWasDecomposed) {
return false;
}
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(convolution);
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(convolution, defaultPrecisions);
std::shared_ptr<Node> newMultiplyAfter;
{
@@ -213,8 +215,8 @@ bool ConvolutionTransformation::transform(TransformationContext &context, ngraph
std::shared_ptr<opset1::Reshape> reshapeFromWeights = ov::as_type_ptr<opset1::Reshape>(convolution->get_input_node_shared_ptr(1));
dequantization = reshapeFromWeights == nullptr ?
NetworkHelper::getDequantization(convolution, 1ul) :
NetworkHelper::getDequantization(reshapeFromWeights);
NetworkHelper::getDequantization(convolution, defaultPrecisions, 1ul) :
NetworkHelper::getDequantization(reshapeFromWeights, defaultPrecisions);
assert(!dequantization.empty());
if (ov::is_type<opset1::FakeQuantize>(dequantization.data.get_node())) {
const std::shared_ptr<opset1::FakeQuantize> fq = ov::as_type_ptr<opset1::FakeQuantize>(dequantization.data.get_node_shared_ptr());
@@ -53,12 +53,14 @@ ConvolutionBackpropDataTransformation::ConvolutionBackpropDataTransformation(con
this->register_matcher(m, callback);
}
bool ConvolutionBackpropDataTransformation::isQuantized(const std::shared_ptr<const Node>& layer) const {
return ConvolutionBackpropDataTransformation::isQuantizedStatic(layer);
bool ConvolutionBackpropDataTransformation::isQuantized(const std::shared_ptr<const Node>& layer,
const std::vector<ngraph::element::Type>& defaultPrecisions) const {
return ConvolutionBackpropDataTransformation::isQuantizedStatic(layer, defaultPrecisions);
}
bool ConvolutionBackpropDataTransformation::isQuantizedStatic(const std::shared_ptr<const Node>& layer) {
return WeightableLayerTransformation::isQuantizedStatic(layer, false);
bool ConvolutionBackpropDataTransformation::isQuantizedStatic(const std::shared_ptr<const Node>& layer,
const std::vector<ngraph::element::Type>& defaultPrecisions) {
return WeightableLayerTransformation::isQuantizedStatic(layer, false, defaultPrecisions);
}
size_t ConvolutionBackpropDataTransformation::getInputChannels(const std::shared_ptr<ngraph::Node> conv) const {
@@ -74,8 +76,8 @@ bool ConvolutionBackpropDataTransformation::transform(TransformationContext &con
auto weightsInput = convolutionBackpropData->get_input_node_shared_ptr(1);
std::shared_ptr<opset1::Reshape> reshapeFromWeights = ov::as_type_ptr<opset1::Reshape>(weightsInput);
FakeQuantizeDequantization dequantization = reshapeFromWeights == nullptr ?
NetworkHelper::getDequantization(convolutionBackpropData, 1ul) :
NetworkHelper::getDequantization(reshapeFromWeights);
NetworkHelper::getDequantization(convolutionBackpropData, defaultPrecisions, 1ul) :
NetworkHelper::getDequantization(reshapeFromWeights, defaultPrecisions);
if (dequantization.empty()) {
const auto fqOnWeights = getFakeQuantizeOnWeights(convolutionBackpropData);
auto constantShape = fqOnWeights->input(1).get_partial_shape();
@@ -97,13 +99,13 @@ bool ConvolutionBackpropDataTransformation::transform(TransformationContext &con
replace_node(weightsInput, resultConstant);
}
} else {
NetworkHelper::foldDequantization(dequantization.multiply, 0, true);
NetworkHelper::foldDequantization(dequantization.multiply, 0, defaultPrecisions, true);
}
return true;
}
convolutionBackpropData = NetworkHelper::separateInStandaloneBranch(convolutionBackpropData);
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(convolutionBackpropData);
convolutionBackpropData = NetworkHelper::separateInStandaloneBranch(convolutionBackpropData, defaultPrecisions);
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(convolutionBackpropData, defaultPrecisions);
std::shared_ptr<Node> newMultiplyAfter;
{
if (dequantization.subtract != nullptr) {
@@ -141,7 +143,7 @@ bool ConvolutionBackpropDataTransformation::transform(TransformationContext &con
{
decomposeFakeQuantizeForWeightsPath(convolutionBackpropData, 1ul);
dequantization = NetworkHelper::getDequantization(convolutionBackpropData, 1ul);
dequantization = NetworkHelper::getDequantization(convolutionBackpropData, defaultPrecisions, 1ul);
if (ov::is_type<opset1::FakeQuantize>(dequantization.data.get_node())) {
const std::shared_ptr<opset1::FakeQuantize> fq = ov::as_type_ptr<opset1::FakeQuantize>(dequantization.data.get_node_shared_ptr());
@@ -229,7 +231,7 @@ bool ConvolutionBackpropDataTransformation::transform(TransformationContext &con
}
bool ConvolutionBackpropDataTransformation::canBeTransformed(const TransformationContext& context, std::shared_ptr<Node> op) const {
return canConvolutionBeTransformed(context, op);
return canConvolutionBeTransformed(context, op, defaultPrecisions);
}
} // namespace low_precision
@@ -34,7 +34,7 @@ bool DepthToSpaceTransformation::canBeTransformed(const TransformationContext& c
return false;
}
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(layer);
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(layer, defaultPrecisions);
if (dequantization.multiply != nullptr) {
if (!NetworkHelper::isScalarLike(dequantization.multiplyConstant)) {
return false;
@@ -41,8 +41,8 @@ bool EltwiseBaseTransformation::canBeTransformed(const TransformationContext& co
return false;
}
FakeQuantizeDequantization dequantization1 = pass::low_precision::NetworkHelper::getDequantization(operation, 0ul);
FakeQuantizeDequantization dequantization2 = pass::low_precision::NetworkHelper::getDequantization(operation, 1ul);
FakeQuantizeDequantization dequantization1 = pass::low_precision::NetworkHelper::getDequantization(operation, defaultPrecisions, 0ul);
FakeQuantizeDequantization dequantization2 = pass::low_precision::NetworkHelper::getDequantization(operation, defaultPrecisions, 1ul);
if ((dequantization1.empty() || ((dequantization1.multiply != nullptr) && !FakeQuantizeDequantization::checkElementwise(dequantization1.multiply))) &&
(dequantization2.empty() || ((dequantization2.multiply != nullptr) && !FakeQuantizeDequantization::checkElementwise(dequantization2.multiply)))) {
return false;
@@ -89,12 +89,12 @@ static bool isBranchHaveMultipleConsumers(const std::shared_ptr<Node> branchData
// return branch index with FP32 precision after eltwise transformation
int EltwiseBaseTransformation::getNotEmpty(const std::shared_ptr<Node>& eltwise) const {
const FakeQuantizeDequantization dequantization1 = pass::low_precision::NetworkHelper::getDequantization(eltwise, 0ul);
const FakeQuantizeDequantization dequantization1 = pass::low_precision::NetworkHelper::getDequantization(eltwise, defaultPrecisions, 0ul);
if (ov::as_type<opset1::Constant>(dequantization1.data.get_node())) {
return -1;
}
const FakeQuantizeDequantization dequantization2 = pass::low_precision::NetworkHelper::getDequantization(eltwise, 1ul);
const FakeQuantizeDequantization dequantization2 = pass::low_precision::NetworkHelper::getDequantization(eltwise, defaultPrecisions, 1ul);
if (ov::as_type<opset1::Constant>(dequantization2.data.get_node())) {
return -1;
}
@@ -188,9 +188,9 @@ int EltwiseBaseTransformation::getNotEmpty(const std::shared_ptr<Node>& eltwise)
std::pair<int, int> EltwiseBaseTransformation::getMultiplyConstBranch(const std::shared_ptr<Node>& eltwise) const {
const std::shared_ptr<Node> parent1 = eltwise->get_input_node_shared_ptr(0);
const auto dequantization1 = NetworkHelper::getDequantization(eltwise, 0);
const auto dequantization1 = NetworkHelper::getDequantization(eltwise, defaultPrecisions, 0);
const std::shared_ptr<Node> parent2 = eltwise->get_input_node_shared_ptr(1);
const auto dequantization2 = NetworkHelper::getDequantization(eltwise, 1);
const auto dequantization2 = NetworkHelper::getDequantization(eltwise, defaultPrecisions, 1);
std::shared_ptr<opset1::Constant> constParent = dequantization1.empty() ?
ov::as_type_ptr<opset1::Constant>(parent1) :
@@ -300,7 +300,7 @@ bool FakeQuantizeDecompositionTransformation::transform(TransformationContext& c
return false;
}
layer = NetworkHelper::composeFakeQuantize(layer);
layer = NetworkHelper::composeFakeQuantize(layer, defaultPrecisions);
if (layer == nullptr) {
return false;
}
@@ -316,7 +316,7 @@ bool FakeQuantizeDecompositionTransformation::transform(TransformationContext& c
DataPrecision dataPrecision = fq_decomposition::getDataPrecisionByOutputPort(layer);
PrecisionsAttribute precisionsAttribute(getDefaultPrecisions());
PrecisionsAttribute precisionsAttribute(defaultPrecisions);
{
// TODO: LPT: return attribute (not wrapper)
auto attributeWrapper = getAttributeFromOutput<PrecisionsAttribute>(layer->output(0));
@@ -32,8 +32,9 @@ GroupConvolutionTransformation::GroupConvolutionTransformation(const Params& par
this->register_matcher(m, callback);
}
bool GroupConvolutionTransformation::isQuantized(const std::shared_ptr<const Node>& layer) const {
return GroupConvolutionTransformation::isQuantizedStatic(layer);
bool GroupConvolutionTransformation::isQuantized(const std::shared_ptr<const Node>& layer,
const std::vector<ngraph::element::Type>& defaultPrecisions) const {
return GroupConvolutionTransformation::isQuantizedStatic(layer, defaultPrecisions);
}
bool GroupConvolutionTransformation::transform(TransformationContext &context, ngraph::pattern::Matcher &m) {
@@ -47,8 +48,9 @@ bool GroupConvolutionTransformation::transform(TransformationContext &context, n
return true;
}
bool GroupConvolutionTransformation::isQuantizedStatic(const std::shared_ptr<const Node>& layer) {
return WeightableLayerTransformation::isQuantizedStatic(layer, true);
bool GroupConvolutionTransformation::isQuantizedStatic(const std::shared_ptr<const Node>& layer,
const std::vector<ngraph::element::Type>& defaultPrecisions) {
return WeightableLayerTransformation::isQuantizedStatic(layer, true, defaultPrecisions);
}
size_t GroupConvolutionTransformation::getInputChannels(const std::shared_ptr<ngraph::Node> conv) const {
@@ -57,8 +57,8 @@ bool InterpolateTransformation::transform(TransformationContext &context, ngraph
if (!canBeTransformed(context, m.get_match_root())) {
return false;
}
interpolate = NetworkHelper::separateInStandaloneBranch(interpolate);
moveDequantizationAfter(context, interpolate, NetworkHelper::getDequantization(interpolate), true);
interpolate = NetworkHelper::separateInStandaloneBranch(interpolate, defaultPrecisions);
moveDequantizationAfter(context, interpolate, NetworkHelper::getDequantization(interpolate, defaultPrecisions), true);
return true;
}
@@ -85,7 +85,7 @@ bool InterpolateTransformation::canBeTransformed(const TransformationContext& co
// TODO: expand transformation cases
// just repeat CNNNetwork Resample transformation
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(layer);
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(layer, defaultPrecisions);
if (dequantization.empty()) {
return false;
}
@@ -23,14 +23,11 @@ namespace low_precision {
constexpr char LayerTransformation::originalLayerPostfix[];
// order defines default precision
std::vector<ngraph::element::Type> LayerTransformation::defaultPrecisions = precision_set::int8_support;
std::mutex LayerTransformation::defaultPrecisionsMutex;
LayerTransformation::LayerTransformation(const Params& params) :
updatePrecisions(params.updatePrecisions),
deqPrecision(params.deqPrecision),
reshapeIgnorePerTensorQuantizationCheck(params.reshapeIgnorePerTensorQuantizationCheck),
defaultPrecisions(params.defaultPrecisions),
context(nullptr) {}
void LayerTransformation::setContext(TransformationContext* context) noexcept {
@@ -41,15 +38,20 @@ void LayerTransformation::setUpdatePrecisions(const bool updatePrecisions) {
this->updatePrecisions = updatePrecisions;
}
void LayerTransformation::setDefaultPrecisions(const std::vector<ngraph::element::Type>& defaultPrecisions) {
this->defaultPrecisions = defaultPrecisions;
}
bool LayerTransformation::canBeTransformed(const TransformationContext& context, std::shared_ptr<Node> layer) const {
if (!isQuantized(layer)) {
if (!isQuantized(layer, defaultPrecisions)) {
return false;
}
return canBeTransformedStatic(layer);
}
bool LayerTransformation::canBeTransformedStatic(const std::shared_ptr<Node>& layer) {
bool LayerTransformation::canBeTransformedStatic(const std::shared_ptr<Node>& layer,
const std::vector<ngraph::element::Type>& defaultPrecisions) {
for (const auto& output : layer->outputs()) {
const auto rank = output.get_partial_shape().rank();
if (rank.is_dynamic() || rank.get_length() < 2) {
@@ -57,7 +59,7 @@ bool LayerTransformation::canBeTransformedStatic(const std::shared_ptr<Node>& la
}
}
const auto dequantization = NetworkHelper::getDequantization(layer);
const auto dequantization = NetworkHelper::getDequantization(layer, defaultPrecisions);
if (!dequantization.empty()) {
auto perChannelQuantization = [](const PartialShape dataPShape, Shape constShape) {
if (ngraph::shape_size(constShape) == 1ul) {
@@ -103,7 +105,7 @@ bool LayerTransformation::canBeTransformedStatic(const std::shared_ptr<Node>& la
}
bool LayerTransformation::canBeTransformedSpatialDimension(const TransformationContext& context, std::shared_ptr<Node> layer) const {
if (!isQuantized(layer)) {
if (!isQuantized(layer, defaultPrecisions)) {
return false;
}
@@ -308,16 +310,17 @@ LayerTransformation::PrecisionDetails LayerTransformation::getPrecisionDetails(c
return getPrecisionDetails(quantizationDetails.levels, quantizationDetails.outputLowValues, quantizationDetails.outputHighValues);
}
bool LayerTransformation::isAsymmetricQuantization(const std::shared_ptr<const Node>& layer) {
bool LayerTransformation::isAsymmetricQuantization(const std::shared_ptr<const Node>& layer,
const std::vector<ngraph::element::Type>& defaultPrecisions) {
const auto nonConstNode = const_cast<ngraph::Node*>(layer.get())->shared_from_this();
const auto dequantization = NetworkHelper::getDequantization(nonConstNode);
const auto dequantization = NetworkHelper::getDequantization(nonConstNode, defaultPrecisions);
if (dequantization.empty()) {
return false;
}
return dequantization.subtract != nullptr;
}
bool LayerTransformation::isQuantized(const std::shared_ptr<const Node>& layer) const {
bool LayerTransformation::isQuantized(const std::shared_ptr<const Node>& layer, const std::vector<ngraph::element::Type>& defaultPrecisions) const {
return true;
}
@@ -374,7 +377,11 @@ std::shared_ptr<ngraph::Node> LayerTransformation::moveDequantizationAfter(
const FakeQuantizeDequantization& dequantization,
const bool updatePrecision,
const bool moveSubtract) const {
const auto result = ngraph::pass::low_precision::NetworkHelper::moveDequantizationAfter(operation, dequantization, updatePrecision, moveSubtract);
const auto result = ngraph::pass::low_precision::NetworkHelper::moveDequantizationAfter(operation,
dequantization,
updatePrecision,
moveSubtract,
defaultPrecisions);
updateOutput(context, result.lastDequantization, result.newOperation);
return result.newOperation;
}
@@ -385,7 +392,10 @@ std::shared_ptr<ngraph::Node> LayerTransformation::moveDequantizationBefore(
const FakeQuantizeDequantization& dequantization,
const bool updatePrecision,
const bool moveSubtract) const {
const auto result = ngraph::pass::low_precision::NetworkHelper::moveDequantizationBefore(operation, dequantization, updatePrecision, moveSubtract);
const auto result = ngraph::pass::low_precision::NetworkHelper::moveDequantizationBefore(operation,
dequantization,
updatePrecision,
moveSubtract);
updateOutput(context, result.newOperation, result.lastDequantization);
return result.newOperation;
}
@@ -445,16 +455,6 @@ void LayerTransformation::addPattern(ngraph::pass::GraphRewrite& pass, Transform
NGRAPH_SUPPRESS_DEPRECATED_END
}
void LayerTransformation::setDefaultPrecisions(const std::vector<ngraph::element::Type>& precisions) {
std::lock_guard<std::mutex> lock(defaultPrecisionsMutex);
defaultPrecisions = precisions;
}
std::vector<ngraph::element::Type> LayerTransformation::getDefaultPrecisions() {
std::lock_guard<std::mutex> lock(defaultPrecisionsMutex);
return defaultPrecisions;
}
} // namespace low_precision
} // namespace pass
} // namespace ngraph
@@ -163,27 +163,29 @@ NGRAPH_RTTI_DEFINITION(ngraph::pass::low_precision::MarkupOptimizations, "Markup
MarkupOptimizations::MarkupOptimizations(
const std::vector<OperationPrecisionRestriction>& precisionRestrictions,
const std::vector<OperationPerTensorQuantizationRestriction>& quantizationRestrictions) :
const std::vector<OperationPerTensorQuantizationRestriction>& quantizationRestrictions,
const AttributeParameters& params) :
precisionRestrictions(precisionRestrictions),
quantizationRestrictions(quantizationRestrictions) {}
quantizationRestrictions(quantizationRestrictions),
params(params) {}
bool ngraph::pass::low_precision::MarkupOptimizations::run_on_model(const std::shared_ptr<ngraph::Function>& f) {
ngraph::pass::Manager markup(get_pass_config());
markup.set_per_pass_validation(false);
markup.register_pass<low_precision::MarkupCanBeQuantized>();
markup.register_pass<low_precision::MarkupCanBeQuantized>(params.defaultPrecisions);
if (!precisionRestrictions.empty()) {
markup.register_pass<low_precision::MarkupPrecisions>(precisionRestrictions);
markup.register_pass<low_precision::MarkupPrecisions>(precisionRestrictions, params.defaultPrecisions);
}
if (!quantizationRestrictions.empty()) {
markup.register_pass<low_precision::MarkupPerTensorQuantization>(quantizationRestrictions);
}
if (ngraph::op::util::has_op_with_type<ngraph::opset1::AvgPool>(f)) {
markup.register_pass<low_precision::MarkupAvgPoolPrecisionPreserved>();
markup.register_pass<low_precision::MarkupAvgPoolPrecisionPreserved>(params.defaultPrecisions);
}
markup.register_pass<low_precision::PropagatePrecisions>();
markup.register_pass<low_precision::PropagatePrecisions>(params);
if (ngraph::op::util::has_op_with_type<ngraph::opset1::Concat>(f)) {
markup.register_pass<low_precision::AlignQuantizationIntervals>();
markup.register_pass<low_precision::AlignQuantizationParameters>();
markup.register_pass<low_precision::AlignQuantizationIntervals>(params.defaultPrecisions);
markup.register_pass<low_precision::AlignQuantizationParameters>(params.defaultPrecisions);
}
markup.run_passes(f);
return false;
@@ -204,7 +206,8 @@ bool ngraph::pass::low_precision::LowPrecision::run_on_model(const std::shared_p
manager.register_pass<TypeRelaxedReplacer>();
manager.register_pass<ngraph::pass::low_precision::MarkupOptimizations>(precisionRestrictions, quantizationRestrictions);
AttributeParameters attributeParams(params.deqPrecision, params.defaultPrecisions);
manager.register_pass<ngraph::pass::low_precision::MarkupOptimizations>(precisionRestrictions, quantizationRestrictions, attributeParams);
std::shared_ptr<ngraph::pass::GraphRewrite> common = manager.register_pass<ngraph::pass::GraphRewrite>();
common->add_matcher<ngraph::pass::low_precision::AddTransformation>(params);
@@ -301,7 +304,3 @@ bool ngraph::pass::low_precision::LowPrecision::isFQLevelsPresent(
}
return false;
}
void ngraph::pass::low_precision::LowPrecision::setDefaultPrecisions(const std::vector<element::Type>& precisions) {
LayerTransformation::setDefaultPrecisions(precisions);
}
@@ -14,13 +14,16 @@ using namespace ngraph;
NGRAPH_RTTI_DEFINITION(ngraph::pass::low_precision::MarkupAvgPoolPrecisionPreserved, "MarkupAvgPoolPrecisionPreserved", 0);
ngraph::pass::low_precision::MarkupAvgPoolPrecisionPreserved::MarkupAvgPoolPrecisionPreserved(const std::vector<ngraph::element::Type> defaultPrecisions)
: defaultPrecisions(defaultPrecisions) {}
bool ngraph::pass::low_precision::MarkupAvgPoolPrecisionPreserved::run_on_model(const std::shared_ptr<ngraph::Function>& f) {
ngraph::pass::Manager manager;
manager.set_per_pass_validation(false);
std::shared_ptr<ngraph::pass::GraphRewrite> markupAvgPoolPrecision = manager.register_pass<ngraph::pass::GraphRewrite>();
markupAvgPoolPrecision->add_matcher<low_precision::CreatePrecisionsDependentAttribute<AvgPoolPrecisionPreservedAttribute, opset1::AvgPool>>();
markupAvgPoolPrecision->add_matcher<low_precision::PropagateThroughPrecisionPreserved<AvgPoolPrecisionPreservedAttribute>>();
markupAvgPoolPrecision->add_matcher<low_precision::UpdateSharedPrecisionPreserved<AvgPoolPrecisionPreservedAttribute>>();
markupAvgPoolPrecision->add_matcher<low_precision::PropagateThroughPrecisionPreserved<AvgPoolPrecisionPreservedAttribute>>(defaultPrecisions);
markupAvgPoolPrecision->add_matcher<low_precision::UpdateSharedPrecisionPreserved<AvgPoolPrecisionPreservedAttribute>>(defaultPrecisions);
manager.run_passes(f);
return false;
}
@@ -18,6 +18,9 @@ using namespace ngraph;
NGRAPH_RTTI_DEFINITION(ngraph::pass::low_precision::MarkupCanBeQuantized, "MarkupCanBeQuantized", 0);
ngraph::pass::low_precision::MarkupCanBeQuantized::MarkupCanBeQuantized(const std::vector<ngraph::element::Type> defaultPrecisions)
: defaultPrecisions(defaultPrecisions) {}
bool ngraph::pass::low_precision::MarkupCanBeQuantized::run_on_model(const std::shared_ptr<ngraph::Function>& f) {
auto setEmptyPrecisions = [](const std::shared_ptr<ngraph::Node>& node) {
for (auto& input : node->inputs()) {
@@ -34,19 +37,19 @@ bool ngraph::pass::low_precision::MarkupCanBeQuantized::run_on_model(const std::
}
if (const auto convolution = std::dynamic_pointer_cast<ngraph::opset1::Convolution>(node)) {
if (!ConvolutionTransformation::isQuantizedStatic(convolution)) {
if (!ConvolutionTransformation::isQuantizedStatic(convolution, defaultPrecisions)) {
setEmptyPrecisions(convolution);
}
continue;
}
if (const auto convolutionBackpropData = std::dynamic_pointer_cast<ngraph::opset1::ConvolutionBackpropData>(node)) {
if (!ConvolutionBackpropDataTransformation::isQuantizedStatic(convolutionBackpropData)) {
if (!ConvolutionBackpropDataTransformation::isQuantizedStatic(convolutionBackpropData, defaultPrecisions)) {
setEmptyPrecisions(convolutionBackpropData);
}
continue;
}
if (const auto groupConvolution = std::dynamic_pointer_cast<ngraph::opset1::GroupConvolution>(node)) {
if (!GroupConvolutionTransformation::isQuantizedStatic(groupConvolution)) {
if (!GroupConvolutionTransformation::isQuantizedStatic(groupConvolution, defaultPrecisions)) {
setEmptyPrecisions(groupConvolution);
}
continue;
@@ -21,7 +21,8 @@ using namespace ngraph;
NGRAPH_RTTI_DEFINITION(ngraph::pass::low_precision::MarkupPrecisions, "MarkupPrecisions", 0);
ngraph::pass::low_precision::MarkupPrecisions::MarkupPrecisions(const std::vector<OperationPrecisionRestriction>& restrictions) {
ngraph::pass::low_precision::MarkupPrecisions::MarkupPrecisions(const std::vector<OperationPrecisionRestriction>& restrictions,
const std::vector<ngraph::element::Type>& defaultPrecisions) : defaultPrecisions(defaultPrecisions) {
for (const auto& restriction : restrictions) {
const auto it = restrictionsByOperation.find(restriction.operationType.name);
if (it == restrictionsByOperation.end()) {
@@ -75,7 +76,7 @@ bool ngraph::pass::low_precision::MarkupPrecisions::run_on_model(const std::shar
// TODO: don't need to set restrictions for not supported operations
// if don't set restrictions for not supported operations then accuracy drop appears, issue #59197
const bool supported = ov::is_type<opset1::Result>(node) || isSupported(node);
if (!supported || !LayerTransformation::canBeTransformedStatic(node)) {
if (!supported || !LayerTransformation::canBeTransformedStatic(node, defaultPrecisions)) {
setRestriction(node, std::vector<std::pair<size_t, std::vector<ngraph::element::Type>>> { {0ul, {}}});
continue;
}
@@ -44,9 +44,9 @@ bool MatMulTransformation::transform(TransformationContext &context, ngraph::pat
return false;
}
matMul = ov::as_type_ptr<opset1::MatMul>(NetworkHelper::separateInStandaloneBranch(matMul));
const auto dequantization1 = NetworkHelper::getDequantization(matMul, 0);
auto dequantization2 = NetworkHelper::getDequantization(matMul, 1);
matMul = ov::as_type_ptr<opset1::MatMul>(NetworkHelper::separateInStandaloneBranch(matMul, defaultPrecisions));
const auto dequantization1 = NetworkHelper::getDequantization(matMul, defaultPrecisions, 0);
auto dequantization2 = NetworkHelper::getDequantization(matMul, defaultPrecisions, 1);
if (dequantization2.empty()) {
const std::shared_ptr<opset1::FakeQuantize> fakeQuantize =
@@ -56,7 +56,7 @@ bool MatMulTransformation::transform(TransformationContext &context, ngraph::pat
const auto precisionsAttribute = getAttributeFromOutput<PrecisionsAttribute>(fakeQuantize);
const auto precisions = precisionsAttribute.empty() ?
getDefaultPrecisions() :
defaultPrecisions :
precisionsAttribute.as<PrecisionsAttribute>().value();
const DataPrecision dataPrecision = getDataPrecision(fakeQuantize, quantizationDetails, precisions);
if (dataPrecision.empty()) {
@@ -71,13 +71,13 @@ bool MatMulTransformation::transform(TransformationContext &context, ngraph::pat
dataPrecision.hasZeroPoint,
updatePrecisions);
dequantization2 = NetworkHelper::getDequantization(matMul, 1);
dequantization2 = NetworkHelper::getDequantization(matMul, defaultPrecisions, 1);
}
}
if (dequantization2.subtract != nullptr) {
NetworkHelper::optimizeSubtract(dequantization2.subtract);
dequantization2 = NetworkHelper::getDequantization(matMul, 1);
dequantization2 = NetworkHelper::getDequantization(matMul, defaultPrecisions, 1);
}
const std::shared_ptr<opset1::MatMul> newMatMul = std::make_shared<ngraph::op::TypeRelaxed<opset1::MatMul>>(
@@ -197,7 +197,7 @@ bool MatMulTransformation::canBeTransformed(const TransformationContext& context
return false;
}
const auto dequantization1 = NetworkHelper::getDequantization(layer, 0);
const auto dequantization1 = NetworkHelper::getDequantization(layer, defaultPrecisions, 0);
if (!dequantization1.empty()) {
if (updatePrecisions && !dequantization1.isLowPrecision()) {
return false;
@@ -223,7 +223,7 @@ bool MatMulTransformation::canBeTransformed(const TransformationContext& context
return false;
}
const auto dequantization2 = NetworkHelper::getDequantization(layer, 1);
const auto dequantization2 = NetworkHelper::getDequantization(layer, defaultPrecisions, 1);
if (!dequantization2.empty()) {
if ((updatePrecisions && !dequantization2.isLowPrecision())) {
return false;
@@ -260,7 +260,7 @@ bool MatMulTransformation::canBeTransformed(const TransformationContext& context
const auto precisionsAttribute = getAttribute<PrecisionsAttribute>(matMul->input(1));
const auto precisions = precisionsAttribute.empty() ?
getDefaultPrecisions() :
defaultPrecisions :
precisionsAttribute.as<PrecisionsAttribute>().value();
const DataPrecision dataPrecision = getDataPrecision(fakeQuantize, quantizationDetails, precisions);
@@ -38,7 +38,7 @@ bool MaxPoolTransformation::canBeTransformed(const TransformationContext& contex
return false;
}
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(op);
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(op, defaultPrecisions);
if (dequantization.empty()) {
return false;
}
@@ -56,8 +56,8 @@ bool MaxPoolTransformation::transform(TransformationContext& context, ngraph::pa
return false;
}
const std::shared_ptr<Node> pooling = NetworkHelper::separateInStandaloneBranch(m.get_match_root());
moveDequantizationAfter(context, pooling, NetworkHelper::getDequantization(pooling), false);
const std::shared_ptr<Node> pooling = NetworkHelper::separateInStandaloneBranch(m.get_match_root(), defaultPrecisions);
moveDequantizationAfter(context, pooling, NetworkHelper::getDequantization(pooling, defaultPrecisions), false);
return true;
}
@@ -44,10 +44,10 @@ bool MultiplyTransformation::transform(TransformationContext& context, ngraph::p
return false;
}
NetworkHelper::normalizeDequantization(NetworkHelper::getDequantization(multiply, 0));
NetworkHelper::normalizeDequantization(NetworkHelper::getDequantization(multiply, 1));
NetworkHelper::normalizeDequantization(NetworkHelper::getDequantization(multiply, defaultPrecisions, 0));
NetworkHelper::normalizeDequantization(NetworkHelper::getDequantization(multiply, defaultPrecisions, 1));
multiply = NetworkHelper::separateInStandaloneBranch(multiply);
multiply = NetworkHelper::separateInStandaloneBranch(multiply, defaultPrecisions);
auto newMultiply = multiply;
auto fold_fake_quantizes = [](std::shared_ptr<Node>& multiply, const size_t index) {
@@ -67,13 +67,13 @@ bool MultiplyTransformation::transform(TransformationContext& context, ngraph::p
if (fullPathIndex == -1) {
const auto multiplyBranch = getMultiplyConstBranch(multiply);
if (multiplyBranch.first != -1) {
NetworkHelper::foldDequantization(multiply, multiplyBranch.first == 0 ? 1 : 0);
NetworkHelper::foldDequantization(multiply, multiplyBranch.first == 0 ? 1 : 0, defaultPrecisions);
}
if (multiplyBranch.first == -1 || multiplyBranch.second == -1) {
// constant folding on dequantization ops (for example: Convert on Subtract)
NetworkHelper::foldDequantization(multiply, 0);
NetworkHelper::foldDequantization(multiply, 1);
NetworkHelper::foldDequantization(multiply, 0, defaultPrecisions);
NetworkHelper::foldDequantization(multiply, 1, defaultPrecisions);
return false;
}
@@ -98,13 +98,13 @@ bool MultiplyTransformation::transform(TransformationContext& context, ngraph::p
const int emptyPathIndex = fullPathIndex == 0 ? 1 : 0;
if (updatePrecisions) {
const FakeQuantizeDequantization dequantizationEmptyPath = NetworkHelper::getDequantization(multiply, emptyPathIndex);
const FakeQuantizeDequantization dequantizationEmptyPath = NetworkHelper::getDequantization(multiply, defaultPrecisions, emptyPathIndex);
if (!dequantizationEmptyPath.empty() && !dequantizationEmptyPath.isLowPrecision()) {
return false;
}
}
FakeQuantizeDequantization dequantizationEmptyPath = NetworkHelper::foldDequantization(multiply, emptyPathIndex);
FakeQuantizeDequantization dequantizationEmptyPath = NetworkHelper::foldDequantization(multiply, emptyPathIndex, defaultPrecisions);
std::shared_ptr<Node> subtractValuesEmptyPath;
std::shared_ptr<Node> multiplyValuesEmptyPath;
std::tie(subtractValuesEmptyPath, multiplyValuesEmptyPath) = NetworkHelper::createEmptyValues(dequantizationEmptyPath, deqPrecision);
@@ -114,7 +114,7 @@ bool MultiplyTransformation::transform(TransformationContext& context, ngraph::p
return false;
}
FakeQuantizeDequantization dequantizationFullPath = NetworkHelper::foldDequantization(multiply, fullPathIndex);
FakeQuantizeDequantization dequantizationFullPath = NetworkHelper::foldDequantization(multiply, fullPathIndex, defaultPrecisions);
std::shared_ptr<Node> subtractValuesFullPath;
std::shared_ptr<Node> multiplyValuesFullPath;
std::tie(subtractValuesFullPath, multiplyValuesFullPath) = NetworkHelper::createEmptyValues(dequantizationFullPath, deqPrecision);
@@ -145,15 +145,15 @@ bool MultiplyTransformation::transform(TransformationContext& context, ngraph::p
updateOutput(context, newMultiply, multiply);
if (fullPathIndex != -1) {
NetworkHelper::foldDequantization(newMultiply, fullPathIndex);
NetworkHelper::foldDequantization(newMultiply, fullPathIndex, defaultPrecisions);
}
return true;
}
bool MultiplyTransformation::canBeTransformed(const TransformationContext& context, std::shared_ptr<Node> layer) const {
FakeQuantizeDequantization dequantization1 = pass::low_precision::NetworkHelper::getDequantization(layer, 0ul);
FakeQuantizeDequantization dequantization2 = pass::low_precision::NetworkHelper::getDequantization(layer, 1ul);
FakeQuantizeDequantization dequantization1 = pass::low_precision::NetworkHelper::getDequantization(layer, defaultPrecisions, 0ul);
FakeQuantizeDequantization dequantization2 = pass::low_precision::NetworkHelper::getDequantization(layer, defaultPrecisions, 1ul);
if (dequantization1.data.get_node() == nullptr || dequantization2.data.get_node() == nullptr) {
return false;
@@ -46,12 +46,12 @@ bool MultiplyToGroupConvolutionTransformation::transform(TransformationContext&
inputIndex = 1;
}
auto dequantization = NetworkHelper::getDequantization(multiply, inputIndex);
auto dequantization = NetworkHelper::getDequantization(multiply, defaultPrecisions, inputIndex);
if (dequantization.data.get_node() == nullptr) {
return false;
}
if (dequantization.subtractConvert != nullptr) {
dequantization = NetworkHelper::foldDequantization(multiply, inputIndex);
dequantization = NetworkHelper::foldDequantization(multiply, inputIndex, defaultPrecisions);
}
element::Type weightsPrecision = element::undefined;
@@ -68,7 +68,7 @@ bool MultiplyToGroupConvolutionTransformation::transform(TransformationContext&
if (weightsPrecision == element::undefined) {
const auto precisionsAttribute = getAttribute<PrecisionsAttribute>(multiply->input(inputIndex == 0ul ? 1ul : 0ul));
const auto precisions = precisionsAttribute == nullptr ?
getDefaultPrecisions() :
defaultPrecisions :
precisionsAttribute.as<PrecisionsAttribute>().value();
weightsPrecision = precisions[0];
}
@@ -191,7 +191,7 @@ bool MultiplyToGroupConvolutionTransformation::canBeTransformed(const Transforma
return false;
}
const auto dequantization = NetworkHelper::getDequantization(operation, inputIndex);
const auto dequantization = NetworkHelper::getDequantization(operation, defaultPrecisions, inputIndex);
const element::Type parentPrecision = dequantization.data.get_element_type();
if (std::find(availablePreisions.begin(), availablePreisions.end(), parentPrecision) == availablePreisions.end()) {
return false;
@@ -201,7 +201,8 @@ bool MultiplyToGroupConvolutionTransformation::canBeTransformed(const Transforma
return true;
}
bool MultiplyToGroupConvolutionTransformation::isQuantized(const std::shared_ptr<const Node>& layer) const {
bool MultiplyToGroupConvolutionTransformation::isQuantized(const std::shared_ptr<const Node>& layer,
const std::vector<ngraph::element::Type>& defaultPrecisions) const {
return MultiplyToGroupConvolutionTransformation::canBeTransformedToGroupConvolution(layer);
}
@@ -65,7 +65,7 @@ bool MVNTransformation::canBeTransformed(const TransformationContext& context, s
return false;
}
const auto dequantization = NetworkHelper::getDequantization(operation);
const auto dequantization = NetworkHelper::getDequantization(operation, defaultPrecisions);
if (dequantization.empty() || dequantization.subtract != nullptr) {
return false;
}
@@ -124,7 +124,7 @@ bool MVNTransformation::transform(TransformationContext &context, ngraph::patter
normalizeVariance = ov::as_type_ptr<opset6::MVN>(mvn)->get_normalize_variance();
}
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(mvn);
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(mvn, defaultPrecisions);
const auto scalesConst = dequantization.multiplyConstant;
const auto type = scalesConst->get_element_type();
@@ -509,8 +509,11 @@ std::shared_ptr<Node> NetworkHelper::fold_fake_quantize(
return foldFakeQuantize(fq, roundValues, true, outChannelsShapeIndex);
}
FakeQuantizeDequantization NetworkHelper::foldDequantization(const std::shared_ptr<Node>& node, const size_t branchIndex, const bool inPlace) {
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(node, branchIndex, inPlace);
FakeQuantizeDequantization NetworkHelper::foldDequantization(const std::shared_ptr<Node>& node,
const size_t branchIndex,
const std::vector<ngraph::element::Type>& defaultPrecisions,
const bool inPlace) {
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(node, defaultPrecisions, branchIndex, inPlace);
if (dequantization.empty() || (dequantization.multiply == nullptr)) {
return dequantization;
}
@@ -522,7 +525,7 @@ FakeQuantizeDequantization NetworkHelper::foldDequantization(const std::shared_p
copyInfo(dequantization.convert, result);
}
replace_node(dequantization.convert, result);
dequantization = NetworkHelper::getDequantization(node, branchIndex, inPlace);
dequantization = NetworkHelper::getDequantization(node, defaultPrecisions, branchIndex, inPlace);
}
}
@@ -537,7 +540,7 @@ FakeQuantizeDequantization NetworkHelper::foldDequantization(const std::shared_p
dequantization.subtractConvert->get_element_type());
if (ov::is_type<opset1::Constant>(convertionResult)) {
replace_node(dequantization.subtractConvert, convertionResult);
dequantization = NetworkHelper::getDequantization(node, branchIndex, inPlace);
dequantization = NetworkHelper::getDequantization(node, defaultPrecisions, branchIndex, inPlace);
}
}
@@ -549,7 +552,7 @@ FakeQuantizeDequantization NetworkHelper::foldDequantization(const std::shared_p
copyInfo(dequantization.subtract, result);
}
replace_node(dequantization.subtract, result);
dequantization = NetworkHelper::getDequantization(node, branchIndex, inPlace);
dequantization = NetworkHelper::getDequantization(node, defaultPrecisions, branchIndex, inPlace);
} else {
return dequantization;
}
@@ -573,15 +576,16 @@ FakeQuantizeDequantization NetworkHelper::foldDequantization(const std::shared_p
copyInfo(dequantization.multiply, result);
}
replace_node(dequantization.multiply, result);
dequantization = NetworkHelper::getDequantization(node, branchIndex, inPlace);
dequantization = NetworkHelper::getDequantization(node, defaultPrecisions, branchIndex, inPlace);
}
return dequantization;
}
std::shared_ptr<ngraph::Node> NetworkHelper::separateInStandaloneBranch(std::shared_ptr<ngraph::Node> node) {
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(node);
std::shared_ptr<ngraph::Node> NetworkHelper::separateInStandaloneBranch(std::shared_ptr<ngraph::Node> node,
const std::vector<ngraph::element::Type>& defaultPrecisions) {
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(node, defaultPrecisions);
if (dequantization.isShared()) {
Output<Node> parent = dequantization.data;
if (dequantization.convert != nullptr) {
@@ -835,7 +839,8 @@ std::shared_ptr<Node> NetworkHelper::foldFakeQuantize(
return fq;
}
std::shared_ptr<opset1::FakeQuantize> NetworkHelper::composeFakeQuantize(const std::shared_ptr<opset1::FakeQuantize>& fakeQuantize) {
std::shared_ptr<opset1::FakeQuantize> NetworkHelper::composeFakeQuantize(const std::shared_ptr<opset1::FakeQuantize>& fakeQuantize,
const std::vector<ngraph::element::Type>& defaultPrecisions) {
std::shared_ptr<Node> parent = fakeQuantize;
auto targetInputs = parent->output(0).get_target_inputs();
if (targetInputs.size() != 1ul) {
@@ -865,7 +870,7 @@ std::shared_ptr<opset1::FakeQuantize> NetworkHelper::composeFakeQuantize(const s
parent = parent->output(0).get_target_inputs().begin()->get_node()->shared_from_this();
const size_t index = NetworkHelper::getChildInputIndex(prev, parent);
const FakeQuantizeDequantization dequantization = getDequantization(parent, index);
const FakeQuantizeDequantization dequantization = getDequantization(parent, defaultPrecisions, index);
if (dequantization.empty()) {
return nullptr;
}
@@ -1248,7 +1253,8 @@ FakeQuantizeDequantization NetworkHelper::createDequantizationFromFakeQuantize(
return FakeQuantizeDequantization(fq, convert, subtract, nullptr, shift, multiply, scale);
}
bool NetworkHelper::areQuantizeAndDequantizeSupportedForSubtract(const std::shared_ptr<const ngraph::Node>& node) {
bool NetworkHelper::areQuantizeAndDequantizeSupportedForSubtract(const std::shared_ptr<const ngraph::Node>& node,
const std::vector<ngraph::element::Type>& defaultPrecisions) {
if (!ov::is_type<opset1::Subtract>(node)) {
return false;
}
@@ -1259,16 +1265,17 @@ bool NetworkHelper::areQuantizeAndDequantizeSupportedForSubtract(const std::shar
}
const auto multiply = targetInputs.begin()->get_node()->shared_from_this();
return areQuantizeAndDequantizeSupportedForMultiply(multiply);
return areQuantizeAndDequantizeSupportedForMultiply(multiply, defaultPrecisions);
}
bool NetworkHelper::areQuantizeAndDequantizeSupportedForMultiply(const std::shared_ptr<const ngraph::Node>& node) {
bool NetworkHelper::areQuantizeAndDequantizeSupportedForMultiply(const std::shared_ptr<const ngraph::Node>& node,
const std::vector<ngraph::element::Type>& defaultPrecisions) {
if (!ov::is_type<opset1::Multiply>(node)) {
return false;
}
const std::shared_ptr<ngraph::Node> multiply = const_cast<ngraph::Node*>(node.get())->shared_from_this();
const auto dequantization = ngraph::pass::low_precision::NetworkHelper::getDequantization(multiply, 0, true);
const auto dequantization = ngraph::pass::low_precision::NetworkHelper::getDequantization(multiply, defaultPrecisions, 0, true);
if (dequantization.empty()) {
return false;
}
@@ -1292,7 +1299,10 @@ bool NetworkHelper::isQuantizeSupported(const std::shared_ptr<opset1::FakeQuanti
return QuantizationDetails::outputLayoutIsSupported(fakeQuantize) && QuantizationDetails::isSupportedLevel(fakeQuantize->get_levels());
}
FakeQuantizeDequantization NetworkHelper::getDequantization(const std::shared_ptr<const Node>& node, const size_t parentIndex, const bool inPlace) {
FakeQuantizeDequantization NetworkHelper::getDequantization(const std::shared_ptr<const Node>& node,
const std::vector<ngraph::element::Type> defaultPrecisions,
const size_t parentIndex,
const bool inPlace) {
auto getDataIndex = [](const std::shared_ptr<ngraph::Node>& node) {
if (ov::is_type<opset1::Constant>(node->get_input_node_ptr(1))) {
return 0ul;
@@ -1342,7 +1352,6 @@ FakeQuantizeDequantization NetworkHelper::getDequantization(const std::shared_pt
const std::shared_ptr<opset1::Convert> convert = ov::as_type_ptr<opset1::Convert>(dataNode.get_node_shared_ptr());
if (convert != nullptr) {
auto defaultPrecisions = LayerTransformation::getDefaultPrecisions();
auto el_type = convert->input(0).get_element_type();
auto foundIt = std::find(defaultPrecisions.begin(), defaultPrecisions.end(), el_type);
if (foundIt == defaultPrecisions.end() &&
@@ -1575,14 +1584,15 @@ NetworkHelper::InsertDequantizationResult NetworkHelper::moveDequantizationAfter
const std::shared_ptr<ngraph::Node>& operation,
const FakeQuantizeDequantization& dequantization,
const bool updatePrecision,
const bool moveSubtract) {
const bool moveSubtract,
const std::vector<ngraph::element::Type>& defaultPrecisions) {
assert(
(NetworkHelper::getDequantization(operation).subtractConstant == nullptr) ||
(NetworkHelper::getDequantization(operation).subtractConstant.get() == dequantization.subtractConstant.get()));
(NetworkHelper::getDequantization(operation, defaultPrecisions).subtractConstant == nullptr) ||
(NetworkHelper::getDequantization(operation, defaultPrecisions).subtractConstant.get() == dequantization.subtractConstant.get()));
assert(
(NetworkHelper::getDequantization(operation).multiplyConstant == nullptr) ||
(NetworkHelper::getDequantization(operation).multiplyConstant.get() == dequantization.multiplyConstant.get()));
(NetworkHelper::getDequantization(operation, defaultPrecisions).multiplyConstant == nullptr) ||
(NetworkHelper::getDequantization(operation, defaultPrecisions).multiplyConstant.get() == dequantization.multiplyConstant.get()));
assert(operation->get_output_size() == 1);
@@ -58,7 +58,7 @@ bool NormalizeL2Transformation::canBeTransformed(const TransformationContext& co
return false;
}
const auto dequantization = NetworkHelper::getDequantization(operation);
const auto dequantization = NetworkHelper::getDequantization(operation, defaultPrecisions);
if (dequantization.subtract != nullptr) {
return false;
}
@@ -100,10 +100,10 @@ bool NormalizeL2Transformation::transform(TransformationContext &context, ngraph
return false;
}
auto normalize = ov::as_type_ptr<opset1::NormalizeL2>(NetworkHelper::separateInStandaloneBranch(operation));
auto normalize = ov::as_type_ptr<opset1::NormalizeL2>(NetworkHelper::separateInStandaloneBranch(operation, defaultPrecisions));
const auto axes = ov::as_type_ptr<opset1::Constant>(normalize->get_input_node_shared_ptr(1));
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(normalize);
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(normalize, defaultPrecisions);
auto scalesConst = ov::as_type_ptr<opset1::Constant>(dequantization.multiply->get_input_node_shared_ptr(1));
if (scalesConst == nullptr) {
scalesConst = ov::as_type_ptr<opset1::Constant>(dequantization.multiply->get_input_node_shared_ptr(0));
@@ -40,7 +40,7 @@ bool PadTransformation::transform(TransformationContext& context, ngraph::patter
return false;
}
const auto pad = ov::as_type_ptr<opset1::Pad>(NetworkHelper::separateInStandaloneBranch(m.get_match_root()));
const auto pad = ov::as_type_ptr<opset1::Pad>(NetworkHelper::separateInStandaloneBranch(m.get_match_root(), defaultPrecisions));
const auto padConstant = ov::as_type_ptr<opset1::Constant>(pad->get_input_node_shared_ptr(3));
const auto padConstantValue = padConstant->cast_vector<float>()[0];
@@ -48,7 +48,7 @@ bool PadTransformation::transform(TransformationContext& context, ngraph::patter
const auto padsEnd = pad->get_pads_end();
const auto padMode = pad->get_pad_mode();
auto dequantization = NetworkHelper::getDequantization(pad);
auto dequantization = NetworkHelper::getDequantization(pad, defaultPrecisions);
if (padMode == op::PadMode::CONSTANT) {
auto bcastConstant = [&](const std::shared_ptr<opset1::Constant> &constant) {
@@ -162,7 +162,7 @@ bool PadTransformation::canBeTransformed(const TransformationContext& context, s
return false;
}
const auto dequantization = NetworkHelper::getDequantization(op);
const auto dequantization = NetworkHelper::getDequantization(op, defaultPrecisions);
if (dequantization.empty()) {
return false;
}
@@ -40,8 +40,8 @@ bool PReluTransformation::transform(TransformationContext& context, ngraph::patt
return false;
}
prelu = NetworkHelper::separateInStandaloneBranch(prelu);
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(prelu, 0);
prelu = NetworkHelper::separateInStandaloneBranch(prelu, defaultPrecisions);
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(prelu, defaultPrecisions, 0);
moveDequantizationAfter(context, prelu, dequantization, false, false);
return true;
}
@@ -55,7 +55,7 @@ bool PReluTransformation::canBeTransformed(const TransformationContext& context,
return false;
}
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(op, 0);
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(op, defaultPrecisions, 0);
if (dequantization.empty() || (dequantization.subtract != nullptr)) {
return false;
}
@@ -17,13 +17,15 @@ using namespace ngraph::pass::low_precision;
NGRAPH_RTTI_DEFINITION(ngraph::pass::low_precision::PropagatePrecisions, "PropagatePrecisions", 0);
ngraph::pass::low_precision::PropagatePrecisions::PropagatePrecisions(const AttributeParameters& params) : params(params) {}
bool ngraph::pass::low_precision::PropagatePrecisions::run_on_model(const std::shared_ptr<ngraph::Function>& f) {
ngraph::pass::Manager manager;
manager.set_per_pass_validation(false);
std::shared_ptr<ngraph::pass::GraphRewrite> precisionsPropagation = manager.register_pass<ngraph::pass::GraphRewrite>();
precisionsPropagation->add_matcher<low_precision::CreateAttribute<PrecisionsAttribute, opset1::FakeQuantize>>(AttributeSource::OutputPort);
precisionsPropagation->add_matcher<low_precision::PropagateThroughPrecisionPreserved<PrecisionsAttribute>>();
precisionsPropagation->add_matcher<low_precision::PropagateToInput<PrecisionsAttribute>>();
precisionsPropagation->add_matcher<low_precision::CreateAttribute<PrecisionsAttribute, opset1::FakeQuantize>>(params, AttributeSource::OutputPort);
precisionsPropagation->add_matcher<low_precision::PropagateThroughPrecisionPreserved<PrecisionsAttribute>>(params.defaultPrecisions);
precisionsPropagation->add_matcher<low_precision::PropagateToInput<PrecisionsAttribute>>(params.defaultPrecisions);
manager.run_passes(f);
return false;
}
@@ -18,8 +18,8 @@ bool ReduceBaseTransformation::transform(TransformationContext& context, ngraph:
return false;
}
const auto reduce = NetworkHelper::separateInStandaloneBranch(m.get_match_root());
auto dequantization = NetworkHelper::normalizeDequantization(NetworkHelper::getDequantization(reduce));
const auto reduce = NetworkHelper::separateInStandaloneBranch(m.get_match_root(), defaultPrecisions);
auto dequantization = NetworkHelper::normalizeDequantization(NetworkHelper::getDequantization(reduce, defaultPrecisions));
// prepare dequantization to propagate
changeDequantizationValues(reduce, dequantization);
@@ -31,7 +31,7 @@ bool ReduceBaseTransformation::transform(TransformationContext& context, ngraph:
}
bool ReduceBaseTransformation::canBeTransformed(const TransformationContext& context, std::shared_ptr<Node> reduce) const {
const auto dequantization = NetworkHelper::getDequantization(reduce);
const auto dequantization = NetworkHelper::getDequantization(reduce, defaultPrecisions);
if (dequantization.empty()) {
return false;
}
@@ -39,7 +39,7 @@ bool ReduceMaxTransformation::canBeTransformed(const TransformationContext& cont
return false;
}
const auto dequantization = NetworkHelper::getDequantization(reduce);
const auto dequantization = NetworkHelper::getDequantization(reduce, defaultPrecisions);
const std::vector<float> scales = ov::as_type_ptr<opset1::Constant>(dequantization.multiplyConstant)->cast_vector<float>();
if (std::any_of(scales.begin(), scales.end(), [](const float value) { return value < 0.0; })) {
return false;
@@ -39,7 +39,7 @@ bool ReduceMinTransformation::canBeTransformed(const TransformationContext& cont
return false;
}
const auto dequantization = NetworkHelper::getDequantization(reduce);
const auto dequantization = NetworkHelper::getDequantization(reduce, defaultPrecisions);
const std::vector<float> scales = ov::as_type_ptr<opset1::Constant>(dequantization.multiplyConstant)->cast_vector<float>();
if (std::any_of(scales.begin(), scales.end(), [](const float value) { return value < 0.0; })) {
return false;
@@ -36,7 +36,7 @@ bool ReduceSumTransformation::canBeTransformed(const TransformationContext& cont
return false;
}
const auto dequantization = NetworkHelper::getDequantization(reduce);
const auto dequantization = NetworkHelper::getDequantization(reduce, defaultPrecisions);
if (dequantization.subtract) {
const auto reductionAxes = reduceSum->get_reduction_axes();
const auto inputPShape = dequantization.data.get_partial_shape();
@@ -40,8 +40,8 @@ bool ReluTransformation::transform(TransformationContext& context, ngraph::patte
return false;
}
relu = NetworkHelper::separateInStandaloneBranch(relu);
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(relu, 0);
relu = NetworkHelper::separateInStandaloneBranch(relu, defaultPrecisions);
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(relu, defaultPrecisions, 0);
moveDequantizationAfter(context, relu, dequantization, false, false);
return true;
}
@@ -55,7 +55,7 @@ bool ReluTransformation::canBeTransformed(const TransformationContext& context,
return false;
}
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(op, 0);
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(op, defaultPrecisions, 0);
if (dequantization.empty() || (dequantization.subtract != nullptr)) {
return false;
}
@@ -56,7 +56,7 @@ ReshapeTransformation::ReshapeTransformation(const Params& params) : LayerTransf
namespace {
void reshapeDequantizationConstant(const std::shared_ptr<opset1::Reshape>& reshape) {
void reshapeDequantizationConstant(const std::shared_ptr<opset1::Reshape>& reshape, const std::vector<ngraph::element::Type>& defaultPrecisions) {
// Reshape dequantization operation Constant.
// 1. Calculate result dequantization Constant shape for broadcast based on original dequantization Constant shape and Reshape output.
// For example: dequantization shape {1, 3, 1, 1}, output Reshape shape {1, 12, 3, 3}, result for broadcast: {1, 3, 4, 1},
@@ -132,7 +132,7 @@ void reshapeDequantizationConstant(const std::shared_ptr<opset1::Reshape>& resha
replace_node(originalConstant, resultConstant);
};
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(reshape, 0);
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(reshape, defaultPrecisions, 0);
if (dequantization.subtract != nullptr) {
replaceConstant(reshape, dequantization.subtractConstant);
@@ -155,9 +155,9 @@ bool ReshapeTransformation::transform(TransformationContext& context, ngraph::pa
return false;
}
reshape = ov::as_type_ptr<opset1::Reshape>(NetworkHelper::separateInStandaloneBranch(reshape));
reshapeDequantizationConstant(reshape);
moveDequantizationAfter(context, reshape, NetworkHelper::getDequantization(reshape, 0), false);
reshape = ov::as_type_ptr<opset1::Reshape>(NetworkHelper::separateInStandaloneBranch(reshape, defaultPrecisions));
reshapeDequantizationConstant(reshape, defaultPrecisions);
moveDequantizationAfter(context, reshape, NetworkHelper::getDequantization(reshape, defaultPrecisions, 0), false);
return true;
}
@@ -190,7 +190,7 @@ bool ReshapeTransformation::canBeTransformed(const TransformationContext& contex
return false;
}
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(op);
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(op, defaultPrecisions);
if (dequantization.empty()) {
return false;
}
@@ -25,8 +25,7 @@ ov::Any PrecisionsAttribute::create(
const std::shared_ptr<ngraph::Node>& node,
const AttributeParameters& params) {
auto& rt = ov::is_type<opset1::FakeQuantize>(node) ? node->output(0).get_rt_info() : node->get_rt_info();
return (rt[PrecisionsAttribute::get_type_info_static()] = PrecisionsAttribute(
ngraph::pass::low_precision::LayerTransformation::getDefaultPrecisions()));
return (rt[PrecisionsAttribute::get_type_info_static()] = PrecisionsAttribute(params.defaultPrecisions));
}
void PrecisionsAttribute::merge(std::vector<ov::Any>& attributes) {
@@ -37,7 +37,7 @@ ov::Any QuantizationAlignmentAttribute::create(
const auto& input = node->input(index);
auto inputNode = input.get_source_output().get_node_shared_ptr();
const auto dequantization = NetworkHelper::getDequantization(node, index);
const auto dequantization = NetworkHelper::getDequantization(node, params.defaultPrecisions, index);
if (!dequantization.empty() &&
(ov::is_type<opset1::Convert>(dequantization.data.get_node())) &&
ov::is_type<opset1::FakeQuantize>(dequantization.data.get_node()->get_input_node_ptr(0))) {
@@ -38,8 +38,8 @@ bool ShuffleChannelsTransformation::transform(TransformationContext& context, ng
return false;
}
const auto shuffleChannels = ov::as_type_ptr<opset1::ShuffleChannels>(NetworkHelper::separateInStandaloneBranch(m.get_match_root()));
auto dequantization = NetworkHelper::getDequantization(shuffleChannels);
const auto shuffleChannels = ov::as_type_ptr<opset1::ShuffleChannels>(NetworkHelper::separateInStandaloneBranch(m.get_match_root(), defaultPrecisions));
auto dequantization = NetworkHelper::getDequantization(shuffleChannels, defaultPrecisions);
const auto shuffleDequantizationConstant = [&](const std::shared_ptr<Node>& eltwise) {
const auto normalizedConst = NetworkHelper::normalizeDequantizationShape(eltwise);
@@ -87,7 +87,7 @@ bool ShuffleChannelsTransformation::canBeTransformed(const TransformationContext
return false;
}
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(shuffleChannels);
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(shuffleChannels, defaultPrecisions);
if (dequantization.empty()) {
return false;
}
@@ -35,8 +35,8 @@ bool SplitTransformation::transform(TransformationContext& context, ngraph::patt
return false;
}
const auto split = NetworkHelper::separateInStandaloneBranch(m.get_match_root());
const auto dequantization = NetworkHelper::getDequantization(split);
const auto split = NetworkHelper::separateInStandaloneBranch(m.get_match_root(), defaultPrecisions);
const auto dequantization = NetworkHelper::getDequantization(split, defaultPrecisions);
OutputVector inputs = split->input_values();
inputs[0] = dequantization.data;
@@ -153,7 +153,7 @@ bool SplitTransformation::isPrecisionPreserved(std::shared_ptr<Node> layer) cons
}
bool SplitTransformation::canBeTransformed(const TransformationContext& context, std::shared_ptr<Node> layer) const {
if (!LayerTransformation::canBeTransformed(context, layer) || NetworkHelper::getDequantization(layer).empty()) {
if (!LayerTransformation::canBeTransformed(context, layer) || NetworkHelper::getDequantization(layer, defaultPrecisions).empty()) {
return false;
}
@@ -53,8 +53,8 @@ bool SqueezeTransformation::transform(TransformationContext& context, ngraph::pa
return dequantizationOpConstant;
};
const std::shared_ptr<Node> squeeze = NetworkHelper::separateInStandaloneBranch(m.get_match_root());
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(squeeze);
const std::shared_ptr<Node> squeeze = NetworkHelper::separateInStandaloneBranch(m.get_match_root(), defaultPrecisions);
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(squeeze, defaultPrecisions);
if (dequantization.multiply != nullptr) {
auto newConstant = squeezeOnConstant(squeeze, dequantization.multiplyConstant, dequantization.data.get_partial_shape());
@@ -66,7 +66,7 @@ bool SqueezeTransformation::transform(TransformationContext& context, ngraph::pa
replace_node(dequantization.subtractConstant, newConstant);
}
moveDequantizationAfter(context, squeeze, NetworkHelper::getDequantization(squeeze), false);
moveDequantizationAfter(context, squeeze, NetworkHelper::getDequantization(squeeze, defaultPrecisions), false);
return true;
}
@@ -75,7 +75,7 @@ bool SqueezeTransformation::isPrecisionPreserved(std::shared_ptr<Node> layer) co
}
bool SqueezeTransformation::canBeTransformed(const TransformationContext& context, std::shared_ptr<Node> layer) const {
return (!NetworkHelper::getDequantization(layer).empty()) && LayerTransformation::canBeTransformed(context, layer);
return (!NetworkHelper::getDequantization(layer, defaultPrecisions).empty()) && LayerTransformation::canBeTransformed(context, layer);
}
} // namespace low_precision
@@ -101,8 +101,8 @@ bool StridedSliceTransformation::transform(TransformationContext& context, ngrap
return false;
}
const auto stridedSlice = NetworkHelper::separateInStandaloneBranch(m.get_match_root());
auto dequantization = NetworkHelper::getDequantization(stridedSlice);
const auto stridedSlice = NetworkHelper::separateInStandaloneBranch(m.get_match_root(), defaultPrecisions);
auto dequantization = NetworkHelper::getDequantization(stridedSlice, defaultPrecisions);
if (dequantization.subtract) {
const auto newSubConst = stridedSliceDeqConstant(stridedSlice, dequantization.subtractConstant);
@@ -114,7 +114,7 @@ bool StridedSliceTransformation::transform(TransformationContext& context, ngrap
replace_node(dequantization.multiplyConstant, newMulConst);
dequantization.multiplyConstant = newMulConst;
moveDequantizationAfter(context, stridedSlice, NetworkHelper::getDequantization(stridedSlice), false);
moveDequantizationAfter(context, stridedSlice, NetworkHelper::getDequantization(stridedSlice, defaultPrecisions), false);
return true;
}
@@ -49,7 +49,7 @@ bool SubtractTransformation::transform(TransformationContext& context, ngraph::p
const ngraph::element::Type originalPrecision = subtract->get_output_element_type(0);
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(subtract);
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(subtract, defaultPrecisions);
if (dequantization.multiply != nullptr) {
// before: Y = X * SC - SH, after: Y = (X - SH') * SC
// X * SC - SH = X * SC - SH' * SC
@@ -19,8 +19,8 @@ bool TransparentBaseTransformation::transform(TransformationContext& context, ng
return false;
}
op = NetworkHelper::separateInStandaloneBranch(op);
moveDequantizationAfter(context, op, NetworkHelper::getDequantization(op), true);
op = NetworkHelper::separateInStandaloneBranch(op, defaultPrecisions);
moveDequantizationAfter(context, op, NetworkHelper::getDequantization(op, defaultPrecisions), true);
return true;
}
@@ -35,8 +35,8 @@ TransposeTransformation::TransposeTransformation(const Params& params) : LayerTr
namespace {
void transposeDequantizationConstant(std::shared_ptr<Node>& transpose) {
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(transpose);
void transposeDequantizationConstant(std::shared_ptr<Node>& transpose, const std::vector<ngraph::element::Type>& defaultPrecisions) {
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(transpose, defaultPrecisions);
const Shape subtractShape = dequantization.subtract == nullptr ? Shape{} : dequantization.subtractConstant->get_shape();
const Shape multiplyShape = dequantization.multiply == nullptr ? Shape{} : dequantization.multiplyConstant->get_shape();
@@ -89,9 +89,9 @@ bool TransposeTransformation::transform(TransformationContext& context, ngraph::
return false;
}
transpose = NetworkHelper::separateInStandaloneBranch(transpose);
transposeDequantizationConstant(transpose);
moveDequantizationAfter(context, transpose, NetworkHelper::getDequantization(transpose, 0), false);
transpose = NetworkHelper::separateInStandaloneBranch(transpose, defaultPrecisions);
transposeDequantizationConstant(transpose, defaultPrecisions);
moveDequantizationAfter(context, transpose, NetworkHelper::getDequantization(transpose, defaultPrecisions, 0), false);
return true;
}
@@ -109,7 +109,7 @@ bool TransposeTransformation::canBeTransformed(const TransformationContext& cont
return false;
}
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(op);
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(op, defaultPrecisions);
const bool isPerTensor = [&] {
if (dequantization.subtractConstant != nullptr) {
if (!NetworkHelper::isScalarLike(dequantization.subtractConstant)) {
@@ -55,8 +55,8 @@ bool UnsqueezeTransformation::transform(TransformationContext& context, ngraph::
};
const std::shared_ptr<Node> unsqueeze = NetworkHelper::separateInStandaloneBranch(m.get_match_root());
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(unsqueeze);
const std::shared_ptr<Node> unsqueeze = NetworkHelper::separateInStandaloneBranch(m.get_match_root(), defaultPrecisions);
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(unsqueeze, defaultPrecisions);
if (dequantization.multiply != nullptr) {
auto newConstant = unsqueezeOnConstant(unsqueeze, dequantization.multiplyConstant, dequantization.data.get_partial_shape());
@@ -68,7 +68,7 @@ bool UnsqueezeTransformation::transform(TransformationContext& context, ngraph::
replace_node(dequantization.subtractConstant, newConstant);
}
moveDequantizationAfter(context, unsqueeze, NetworkHelper::getDequantization(unsqueeze), false);
moveDequantizationAfter(context, unsqueeze, NetworkHelper::getDequantization(unsqueeze, defaultPrecisions), false);
return true;
}
@@ -77,7 +77,7 @@ bool UnsqueezeTransformation::isPrecisionPreserved(std::shared_ptr<Node> layer)
}
bool UnsqueezeTransformation::canBeTransformed(const TransformationContext& context, std::shared_ptr<Node> layer) const {
return (!NetworkHelper::getDequantization(layer).empty()) && LayerTransformation::canBeTransformed(context, layer);
return (!NetworkHelper::getDequantization(layer, defaultPrecisions).empty()) && LayerTransformation::canBeTransformed(context, layer);
}
@@ -16,12 +16,13 @@ namespace low_precision {
WeightableLayerTransformation::WeightableLayerTransformation(const Params& params) : LayerTransformation(params) {}
bool WeightableLayerTransformation::canConvolutionBeTransformed(const TransformationContext& context, std::shared_ptr<Node> layer) const {
bool WeightableLayerTransformation::canConvolutionBeTransformed(const TransformationContext& context, std::shared_ptr<Node> layer,
const std::vector<ngraph::element::Type>& defaultPrecisions) const {
if (!WeightableLayerTransformation::canBeTransformed(context, layer)) {
return false;
}
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(layer);
FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(layer, defaultPrecisions);
if (!canSubtractBeHandled(layer, dequantization)) {
return false;
}
@@ -36,12 +37,12 @@ bool WeightableLayerTransformation::canConvolutionBeTransformed(const Transforma
std::shared_ptr<opset1::Reshape> reshapeFromWeights = ov::as_type_ptr<opset1::Reshape>(layer->get_input_node_shared_ptr(1));
dequantization = reshapeFromWeights == nullptr ?
NetworkHelper::getDequantization(layer, 1ul) :
NetworkHelper::getDequantization(reshapeFromWeights);
NetworkHelper::getDequantization(layer, defaultPrecisions, 1ul) :
NetworkHelper::getDequantization(reshapeFromWeights, defaultPrecisions);
if (dequantization.empty()) {
const auto fqOnWeights = getFakeQuantizeOnWeights(layer);
const auto dataPrecision = getDataPrecisionOnWeights(layer);
const auto dataPrecision = getDataPrecisionOnWeights(layer, defaultPrecisions);
if ((dataPrecision.precision == ngraph::element::undefined) || (!NetworkHelper::checkZeroPoint(fqOnWeights, dataPrecision))) {
return false;
}
@@ -65,7 +66,7 @@ bool WeightableLayerTransformation::canBeTransformed(const TransformationContext
}
if (isGroup(layer)) {
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(layer);
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(layer, defaultPrecisions);
if (dequantization.empty()) {
return false;
}
@@ -101,7 +102,7 @@ bool WeightableLayerTransformation::canBeTransformed(const TransformationContext
}
}
} else {
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(layer);
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(layer, defaultPrecisions);
if (dequantization.multiply == nullptr) {
return false;
}
@@ -140,13 +141,13 @@ bool WeightableLayerTransformation::canBeTransformed(const TransformationContext
if (reshapeFromWeights == nullptr) {
fqFromWeights = ov::as_type_ptr<opset1::FakeQuantize>(layer->get_input_node_shared_ptr(1));
if (fqFromWeights == nullptr) {
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(layer, 1ul);
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(layer, defaultPrecisions, 1ul);
fqFromWeights = ov::as_type_ptr<opset1::FakeQuantize>(dequantization.data.get_node_shared_ptr());
}
} else {
fqFromWeights = ov::as_type_ptr<opset1::FakeQuantize>(reshapeFromWeights->get_input_node_shared_ptr(0));
if (fqFromWeights == nullptr) {
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(reshapeFromWeights, 0ul);
const FakeQuantizeDequantization dequantization = NetworkHelper::getDequantization(reshapeFromWeights, defaultPrecisions, 0ul);
fqFromWeights = ov::as_type_ptr<opset1::FakeQuantize>(dequantization.data.get_node_shared_ptr());
}
}
@@ -182,8 +183,8 @@ bool WeightableLayerTransformation::canBeTransformed(const TransformationContext
} else {
// TODO: LPT: is it possible to share with isQuantized?
const FakeQuantizeDequantization dequantizationOnWeights = reshapeFromWeights == nullptr ?
NetworkHelper::getDequantization(layer, 1ul) :
NetworkHelper::getDequantization(reshapeFromWeights, 0ul);
NetworkHelper::getDequantization(layer, defaultPrecisions, 1ul) :
NetworkHelper::getDequantization(reshapeFromWeights, defaultPrecisions, 0ul);
if (dequantizationOnWeights.empty()) {
return false;
}
@@ -223,7 +224,9 @@ bool WeightableLayerTransformation::canBeTransformed(const TransformationContext
return true;
}
bool WeightableLayerTransformation::isQuantizedStatic(const std::shared_ptr<const Node>& layer, const bool reshapeIsRequired) {
bool WeightableLayerTransformation::isQuantizedStatic(const std::shared_ptr<const Node>& layer,
const bool reshapeIsRequired,
const std::vector<ngraph::element::Type>& defaultPrecisions) {
FakeQuantizeDequantization dequantizationOnWeights;
if (reshapeIsRequired) {
const auto reshape = layer->get_input_node_shared_ptr(1);
@@ -236,14 +239,14 @@ bool WeightableLayerTransformation::isQuantizedStatic(const std::shared_ptr<cons
return NetworkHelper::isQuantizeSupported(fq);
}
dequantizationOnWeights = NetworkHelper::getDequantization(reshape, 0);
dequantizationOnWeights = NetworkHelper::getDequantization(reshape, defaultPrecisions, 0);
} else if (ov::is_type<opset1::FakeQuantize>(layer->get_input_node_shared_ptr(1))) {
const std::shared_ptr<opset1::FakeQuantize> fq = ov::as_type_ptr<opset1::FakeQuantize>(layer->get_input_node_shared_ptr(1));
return NetworkHelper::isQuantizeSupported(fq);
} else {
// TODO: update NetworkHelper API later
const std::shared_ptr<ngraph::Node> op = const_cast<ngraph::Node*>(layer.get())->shared_from_this();
dequantizationOnWeights = NetworkHelper::getDequantization(op, 1);
dequantizationOnWeights = NetworkHelper::getDequantization(op, defaultPrecisions, 1);
}
if (dequantizationOnWeights.empty()) {
@@ -300,7 +303,7 @@ bool WeightableLayerTransformation::decomposeFakeQuantizeForWeightsPath(const st
const QuantizationDetails quantizationDetails = QuantizationDetails::getDetails(fq);
const auto precisionsAttribute = getAttributeFromOutput<PrecisionsAttribute>(fq);
const auto precisions = precisionsAttribute.empty() ?
getDefaultPrecisions() :
defaultPrecisions :
precisionsAttribute.as<PrecisionsAttribute>().value();
const DataPrecision dataPrecision = getDataPrecision(fq, quantizationDetails, precisions);
@@ -361,7 +364,9 @@ std::shared_ptr<opset1::FakeQuantize> WeightableLayerTransformation::getFakeQuan
return fq;
}
DataPrecision WeightableLayerTransformation::getDataPrecisionOnWeights(const std::shared_ptr<Node>& node) {
DataPrecision WeightableLayerTransformation::getDataPrecisionOnWeights(
const std::shared_ptr<Node>& node,
const std::vector<ngraph::element::Type>& defaultPrecisions) {
const auto fq = getFakeQuantizeOnWeights(node);
const QuantizationDetails quantizationDetails = QuantizationDetails::getDetails(fq);
if (quantizationDetails.empty()) {
@@ -370,22 +375,24 @@ DataPrecision WeightableLayerTransformation::getDataPrecisionOnWeights(const std
const auto precisionsAttribute = getAttributeFromOutput<PrecisionsAttribute>(fq);
const auto precisions = precisionsAttribute.empty() ?
getDefaultPrecisions() :
defaultPrecisions :
precisionsAttribute.as<PrecisionsAttribute>().value();
return getDataPrecision(fq, quantizationDetails, precisions);
}
bool WeightableLayerTransformation::isAsymmetricOnWeights(const std::shared_ptr<const Node>& node) {
bool WeightableLayerTransformation::isAsymmetricOnWeights(
const std::shared_ptr<const Node>& node,
const std::vector<ngraph::element::Type>& defaultPrecisions) {
const auto n = const_cast<ngraph::Node*>(node.get())->shared_from_this();
const auto reshapeFromWeights = ngraph::as_type_ptr<ngraph::opset1::Reshape>(n->get_input_node_shared_ptr(1));
const auto dequantization = reshapeFromWeights == nullptr ?
NetworkHelper::getDequantization(n, 1ul) :
NetworkHelper::getDequantization(reshapeFromWeights);
NetworkHelper::getDequantization(n, defaultPrecisions, 1ul) :
NetworkHelper::getDequantization(reshapeFromWeights, defaultPrecisions);
if (dequantization.empty()) {
const auto dataPrecision = WeightableLayerTransformation::getDataPrecisionOnWeights(n);
const auto dataPrecision = WeightableLayerTransformation::getDataPrecisionOnWeights(n, defaultPrecisions);
if (dataPrecision.empty()) {
return false;
}