[LPT] AddTransformation fix (#17076)
* [LPT] AddTransformation: constants on 0's input support * AddTransformation: new test instances * codestyle
This commit is contained in:
parent
a3f14366d9
commit
f410658d32
@ -60,9 +60,9 @@ bool EltwiseBaseTransformation::canBeTransformed(const TransformationContext& co
|
||||
}
|
||||
|
||||
static bool isTargetType(const std::shared_ptr<Node> node) {
|
||||
return ov::is_type<opset1::Convolution>(node) ||
|
||||
ov::is_type<opset1::GroupConvolution>(node) ||
|
||||
ov::is_type<opset1::MatMul>(node);
|
||||
return node != nullptr && (ov::is_type<opset1::Convolution>(node) ||
|
||||
ov::is_type<opset1::GroupConvolution>(node) ||
|
||||
ov::is_type<opset1::MatMul>(node));
|
||||
}
|
||||
|
||||
static std::shared_ptr<Node> getDataParent(const std::shared_ptr<Node> branchData) {
|
||||
@ -72,30 +72,38 @@ static std::shared_ptr<Node> getDataParent(const std::shared_ptr<Node> branchDat
|
||||
}
|
||||
|
||||
if (ov::marked_as_bias(parent)) {
|
||||
const auto bias_parent = parent->get_input_node_shared_ptr(0);
|
||||
// target node just before bias
|
||||
if (isTargetType(bias_parent)) {
|
||||
return bias_parent;
|
||||
}
|
||||
// between target node and bias are placed some DQ operations
|
||||
const auto dq = NetworkHelper::getDequantization(parent->get_input_node_shared_ptr(0));
|
||||
const auto data_node = dq.data.get_node_shared_ptr();
|
||||
if (isTargetType(data_node)) {
|
||||
return data_node;
|
||||
// we need to check both inputs in order to handle the case with constant on 0's input
|
||||
for (size_t i = 0; i < parent->get_input_size(); ++i) {
|
||||
const auto bias_parent = parent->get_input_node_shared_ptr(i);
|
||||
// target node just before bias
|
||||
if (isTargetType(bias_parent)) {
|
||||
return bias_parent;
|
||||
}
|
||||
// between target node and bias are placed some DQ operations
|
||||
const auto dq = NetworkHelper::getDequantization(bias_parent);
|
||||
const auto data_node = dq.data.get_node_shared_ptr();
|
||||
if (isTargetType(data_node)) {
|
||||
return data_node;
|
||||
}
|
||||
}
|
||||
}
|
||||
return parent;
|
||||
}
|
||||
|
||||
static bool isBranchHaveMultipleConsumers(const std::shared_ptr<Node> branchData, const std::shared_ptr<Node> branchDataParent) {
|
||||
auto several_consumers = [](const std::shared_ptr<ov::Node>& node) {
|
||||
return node->get_output_size() != 1 || node->get_output_target_inputs(0).size() != 1;
|
||||
};
|
||||
|
||||
auto parent = branchData;
|
||||
while (parent != branchDataParent) {
|
||||
if ((parent->get_output_size() != 1ul) || (parent->get_output_target_inputs(0).size() != 1ul)) {
|
||||
if (several_consumers(parent)) {
|
||||
return true;
|
||||
}
|
||||
parent = parent->get_input_node_shared_ptr(0);
|
||||
const auto new_parent = parent->get_input_node_shared_ptr(0);
|
||||
parent = !ov::is_type<opset1::Constant>(new_parent) ? new_parent : parent->get_input_node_shared_ptr(1);
|
||||
}
|
||||
return (parent->get_output_size() != 1ul) || (parent->get_output_target_inputs(0).size() != 1ul);
|
||||
return several_consumers(parent);
|
||||
}
|
||||
|
||||
// return branch index with FP32 precision after eltwise transformation
|
||||
|
@ -69,6 +69,7 @@ public:
|
||||
Actual actual;
|
||||
Expected expected;
|
||||
std::string additionalLayer;
|
||||
std::string postops_configuration;
|
||||
};
|
||||
|
||||
typedef std::tuple<ngraph::element::Type,
|
||||
@ -94,7 +95,8 @@ public:
|
||||
testValues.actual.dequantization2,
|
||||
testValues.constInput,
|
||||
testValues.actual.constValues,
|
||||
testValues.additionalLayer);
|
||||
testValues.additionalLayer,
|
||||
testValues.postops_configuration);
|
||||
|
||||
SimpleLowPrecisionTransformer transform;
|
||||
transform.add<ngraph::pass::low_precision::AddTransformation, ngraph::opset1::Add>(testValues.params);
|
||||
@ -120,7 +122,8 @@ public:
|
||||
testValues.constInput == -1 ? -1 : 1,
|
||||
testValues.expected.constValues,
|
||||
testValues.additionalLayer,
|
||||
testValues.expected.operationType);
|
||||
testValues.expected.operationType,
|
||||
testValues.postops_configuration);
|
||||
}
|
||||
|
||||
static std::string getTestCaseName(testing::TestParamInfo<AddTransformationParams> obj) {
|
||||
@ -133,7 +136,8 @@ public:
|
||||
<< "_" << testValues.actual.precision1 << "_" << testValues.actual.dequantization1 << "_"
|
||||
<< testValues.actual.precision2 << "_" << testValues.actual.dequantization2 << "_"
|
||||
<< testValues.constInput << "_" << testValues.actual.constValues << "_" << testValues.additionalLayer
|
||||
<< "_" << (testValues.params.updatePrecisions ? "true" : "false");
|
||||
<< "_" << testValues.postops_configuration << "_"
|
||||
<< (testValues.params.updatePrecisions ? "true" : "false");
|
||||
return result.str();
|
||||
}
|
||||
};
|
||||
@ -439,6 +443,23 @@ const std::vector<AddTransformationTestValues> testValuesWithoutConstantBranches
|
||||
{{}, {}, {10.f}},
|
||||
{}},
|
||||
"convolution"},
|
||||
// convolution before FQ
|
||||
{false,
|
||||
-1,
|
||||
LayerTransformation::createParamsU8I8(),
|
||||
{ngraph::element::u8,
|
||||
{{ngraph::element::f32}, {7.f}, {10.f}},
|
||||
ngraph::element::u8,
|
||||
{{ngraph::element::f32}, {3.f}, {5.f}},
|
||||
{}},
|
||||
{ngraph::element::u8,
|
||||
{{}, {}, {}},
|
||||
ngraph::element::u8,
|
||||
{{ngraph::element::f32}, {17.f}, {0.5f}},
|
||||
{{}, {}, {10.f}},
|
||||
{}},
|
||||
"convolution",
|
||||
"bias_on_zero_input"},
|
||||
// convolution with multiple consumers before FQ ( FP32 on other branch due to possible quantize fusing )
|
||||
{false,
|
||||
-1,
|
||||
|
@ -70,7 +70,8 @@ public:
|
||||
const ngraph::builder::subgraph::DequantizationOperations& dequantization2,
|
||||
const int constInput,
|
||||
const std::vector<float>& constValues,
|
||||
const std::string& additionalLayer);
|
||||
const std::string& additionalLayer,
|
||||
const std::string& postops_configuration = "");
|
||||
|
||||
static std::shared_ptr<ngraph::Function> getOriginal(
|
||||
const ngraph::element::Type precision,
|
||||
@ -93,7 +94,8 @@ public:
|
||||
const int constInput,
|
||||
const std::vector<float>& constValues,
|
||||
const std::string& additionalLayer,
|
||||
const std::string& operationType);
|
||||
const std::string& operationType,
|
||||
const std::string& postops_configuration = "");
|
||||
};
|
||||
|
||||
} // namespace subgraph
|
||||
|
@ -18,6 +18,28 @@ namespace ngraph {
|
||||
namespace builder {
|
||||
namespace subgraph {
|
||||
|
||||
namespace {
|
||||
std::shared_ptr<Node> configure_postops(const std::shared_ptr<Node>& parent,
|
||||
const ov::element::Type& precision,
|
||||
const std::string& postops_configuration) {
|
||||
std::shared_ptr<Node> res = parent;
|
||||
if (postops_configuration.empty() || postops_configuration == "bias") {
|
||||
auto bias = opset1::Constant::create(precision, { 1, 1, 1, 1 }, {1.f});
|
||||
res = std::make_shared<opset1::Add>(res, bias);
|
||||
} else if (postops_configuration == "bias_on_zero_input") {
|
||||
auto bias = opset1::Constant::create(precision, { 1, 1, 1, 1 }, {1.f});
|
||||
res = std::make_shared<opset1::Add>(bias, res);
|
||||
} else {
|
||||
return parent;
|
||||
}
|
||||
|
||||
return ngraph::builder::subgraph::makeFakeQuantizeTypeRelaxed(
|
||||
res,
|
||||
precision,
|
||||
{256, Shape{}, { 0 }, { 255 }, { 0 }, { 255 }, element::u8});
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::shared_ptr<ngraph::Function> AddFunction::getOriginal(
|
||||
const ngraph::element::Type precision,
|
||||
const ngraph::PartialShape& inputShape1,
|
||||
@ -30,7 +52,8 @@ std::shared_ptr<ngraph::Function> AddFunction::getOriginal(
|
||||
const ngraph::builder::subgraph::DequantizationOperations& dequantization2,
|
||||
const int constInput,
|
||||
const std::vector<float>& constValues,
|
||||
const std::string& additionalLayer) {
|
||||
const std::string& additionalLayer,
|
||||
const std::string& postops_configuration) {
|
||||
std::shared_ptr<ngraph::Node> input1;
|
||||
std::shared_ptr<ngraph::Node> parent1;
|
||||
if (constInput == 0) {
|
||||
@ -113,13 +136,7 @@ std::shared_ptr<ngraph::Function> AddFunction::getOriginal(
|
||||
ngraph::Strides{ 1, 1 });
|
||||
}
|
||||
if (additionalLayer != "") {
|
||||
parent = std::make_shared<ngraph::opset1::Add>(
|
||||
parent,
|
||||
std::make_shared<ngraph::opset1::Constant>(precision, Shape{ 1, 1, 1, 1 }, std::vector<float>{1.f}));
|
||||
parent = ngraph::builder::subgraph::makeFakeQuantizeTypeRelaxed(
|
||||
parent,
|
||||
precision,
|
||||
{256, Shape{}, { 0 }, { 255 }, { 0 }, { 255 }, element::u8});
|
||||
parent = configure_postops(parent, precision, postops_configuration);
|
||||
}
|
||||
|
||||
auto dequantizationStructure2 = dequantization2;
|
||||
@ -203,7 +220,8 @@ std::shared_ptr<ngraph::Function> AddFunction::getReference(
|
||||
const int constInputIndex,
|
||||
const std::vector<float>& constValues,
|
||||
const std::string& additionalLayer,
|
||||
const std::string& operationType) {
|
||||
const std::string& operationType,
|
||||
const std::string& postops_configuration) {
|
||||
std::shared_ptr<ngraph::Node> input1;
|
||||
std::shared_ptr<ngraph::Node> parent1;
|
||||
if (constInputIndex == 0) {
|
||||
@ -282,13 +300,7 @@ std::shared_ptr<ngraph::Function> AddFunction::getReference(
|
||||
ngraph::Strides{ 1, 1 });
|
||||
}
|
||||
if (additionalLayer != "") {
|
||||
parent = std::make_shared<ngraph::opset1::Add>(
|
||||
parent,
|
||||
std::make_shared<ngraph::opset1::Constant>(precision, Shape{ 1, 1, 1, 1 }, std::vector<float>{1.f}));
|
||||
parent = ngraph::builder::subgraph::makeFakeQuantizeTypeRelaxed(
|
||||
parent,
|
||||
precision,
|
||||
{256, Shape{}, { 0 }, { 255 }, { 0 }, { 255 }, element::u8});
|
||||
parent = configure_postops(parent, precision, postops_configuration);
|
||||
}
|
||||
|
||||
auto dequantizationStructure2 = dequantization2;
|
||||
|
Loading…
Reference in New Issue
Block a user