[LPT] MoveFakeQuantize parent output fix & refactoring (#9872)

* [LPT] MoveFakeQuantize parent output fix & refactoring

* [LPT] tests extending
This commit is contained in:
Edward Shogulin 2022-01-29 10:04:07 +03:00 committed by GitHub
parent e3ec1ac9b3
commit 1176b0f1f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 205 additions and 184 deletions

View File

@ -55,11 +55,12 @@ MoveFakeQuantize::MoveFakeQuantize(const Params& params) : LayerTransformation(p
}
bool MoveFakeQuantize::transform(TransformationContext& context, ngraph::pattern::Matcher& m) {
auto fq = m.get_match_root();
const auto fq = m.get_match_root();
if (!canBeTransformed(context, fq)) {
return false;
}
auto operation = fq->get_input_node_shared_ptr(0);
const auto operation = fq->get_input_node_shared_ptr(0);
std::shared_ptr<ngraph::Node> concat;
bool without_operation = true;
const std::string fq_original_name = fq->get_friendly_name();
@ -71,63 +72,72 @@ bool MoveFakeQuantize::transform(TransformationContext& context, ngraph::pattern
concat = operation->get_input_node_shared_ptr(0);
without_operation = false;
}
if (!ConcatTransformation::isQuantizedStatic(concat)) {
return false;
}
const auto convert_q = fq->output(0).get_target_inputs().begin()->get_node()->shared_from_this();
bool q_dq = is_type<opset1::Convert>(convert_q);
std::vector<std::shared_ptr<opset1::Constant>> currConstants(4);
std::vector<std::shared_ptr<opset1::Constant>> curr_constants(4);
bool multi_chanels = false;
const auto number_of_concat_inputs = concat->get_input_size();
const auto concatNode = as_type_ptr<opset1::Concat>(concat);
const auto concat_axis = concatNode->get_concatenation_axis();
const auto concat_node = as_type_ptr<opset1::Concat>(concat);
if (concat_node == nullptr) {
return false;
}
const auto concat_axis = concat_node->get_concatenation_axis();
for (size_t i = 0; i < 4; i++) {
currConstants[i] = as_type_ptr<opset1::Constant>(fq->get_input_node_shared_ptr(i + 1));
if (!multi_chanels && currConstants[i]->get_shape().size() > (concat_axis + 1ul) && currConstants[i]->get_shape()[concat_axis] != 1) {
curr_constants[i] = as_type_ptr<opset1::Constant>(fq->get_input_node_shared_ptr(i + 1));
if (!multi_chanels && curr_constants[i]->get_shape().size() > (concat_axis + 1ul) && curr_constants[i]->get_shape()[concat_axis] != 1) {
multi_chanels = true;
}
}
std::vector<std::vector<std::shared_ptr<ngraph::opset1::Constant>>> newConstants;
std::vector<std::vector<std::shared_ptr<ngraph::opset1::Constant>>> new_constants;
if (multi_chanels) {
newConstants = NetworkHelper::splitConstantsBeforeConcat(concat, currConstants);
new_constants = NetworkHelper::splitConstantsBeforeConcat(concat, curr_constants);
}
const auto convert_q = fq->get_output_target_inputs(0).begin()->get_node()->shared_from_this();
if (convert_q == nullptr) {
return false;
}
const bool q_dq = is_type<opset1::Convert>(convert_q);
std::vector<std::shared_ptr<ngraph::Node>> newNodes;
for (size_t i{ 0 }; i < number_of_concat_inputs; ++i) {
std::shared_ptr<ngraph::Node> fq_input;
for (size_t i = 0; i < concat->get_input_size(); ++i) {
ov::Output<ov::Node> parent_output;
if (without_operation) {
fq_input = concat->get_input_node_shared_ptr(i);
parent_output = concat->get_input_source_output(i);
} else {
auto input = concat->get_input_node_shared_ptr(i);
fq_input = operation->clone_with_new_inputs({ input });
auto fq_input = operation->clone_with_new_inputs({concat->get_input_source_output(i)});
fq_input->set_friendly_name(operation_original_name + "_" + std::to_string(i + 1));
parent_output = fq_input->output(0);
}
std::shared_ptr<ngraph::Node> newFq;
if (multi_chanels) {
newFq = fq->clone_with_new_inputs({ fq_input,
newConstants[0][newConstants[0].size() == 1 ? 0 : i],
newConstants[1][newConstants[1].size() == 1 ? 0 : i],
newConstants[2][newConstants[2].size() == 1 ? 0 : i],
newConstants[3][newConstants[3].size() == 1 ? 0 : i] });
} else {
newFq = fq->clone_with_new_inputs({ fq_input,
const std::shared_ptr<ngraph::Node> new_fq = multi_chanels ?
fq->clone_with_new_inputs({parent_output,
new_constants[0][new_constants[0].size() == 1 ? 0 : i],
new_constants[1][new_constants[1].size() == 1 ? 0 : i],
new_constants[2][new_constants[2].size() == 1 ? 0 : i],
new_constants[3][new_constants[3].size() == 1 ? 0 : i] }) :
fq->clone_with_new_inputs({parent_output,
fq->get_input_node_ptr(1)->clone_with_new_inputs({}),
fq->get_input_node_ptr(2)->clone_with_new_inputs({}),
fq->get_input_node_ptr(3)->clone_with_new_inputs({}),
fq->get_input_node_ptr(4)->clone_with_new_inputs({}) });
}
ngraph::copy_runtime_info(fq, newFq);
newFq->set_friendly_name(fq_original_name + "_" + std::to_string(i + 1));
ngraph::copy_runtime_info(fq, new_fq);
new_fq->set_friendly_name(fq_original_name + "_" + std::to_string(i + 1));
if (q_dq) {
auto newConvert_q = convert_q->clone_with_new_inputs({ newFq });
ngraph::copy_runtime_info(convert_q, newConvert_q);
newConvert_q->set_friendly_name(convert_q->get_friendly_name() + "_" + std::to_string(i + 1));
newNodes.push_back(newConvert_q);
auto new_convert_q = convert_q->clone_with_new_inputs({new_fq});
ngraph::copy_runtime_info(convert_q, new_convert_q);
new_convert_q->set_friendly_name(convert_q->get_friendly_name() + "_" + std::to_string(i + 1));
newNodes.push_back(new_convert_q);
} else {
newNodes.push_back(newFq);
newNodes.push_back(new_fq);
}
}
auto newConcat = concat->clone_with_new_inputs(ngraph::OutputVector(newNodes.begin(), newNodes.end()));
auto newConcat = concat->clone_with_new_inputs(ngraph::OutputVector(newNodes.begin(), newNodes.end()));
newConcat->set_friendly_name(concat->get_friendly_name());
NetworkHelper::copyInfo(concat, newConcat);
if (q_dq) {
@ -137,6 +147,7 @@ bool MoveFakeQuantize::transform(TransformationContext& context, ngraph::pattern
}
replace_node(fq, newConcat);
updateOutput(context, newConcat, fq);
return true;
}

View File

@ -114,16 +114,18 @@ inline std::ostream& operator<<(std::ostream& out, const MoveFakeQuantizeTransfo
typedef std::tuple <
ngraph::element::Type,
std::vector<ngraph::PartialShape>,
MoveFakeQuantizeTransformationTestValues
MoveFakeQuantizeTransformationTestValues,
bool
> MoveFakeQuantizeTransformationParams;
class MoveFakeQuantizeTransformation : public LayerTransformation, public testing::WithParamInterface<MoveFakeQuantizeTransformationParams> {
public:
void SetUp() override {
const ngraph::element::Type precision = std::get<0>(GetParam());
const std::vector<ngraph::PartialShape> shape = std::get<1>(GetParam());
std::vector<ngraph::PartialShape> inputShapes = std::get<1>(GetParam());
//const auto shape = std::get<1>(GetParam());
MoveFakeQuantizeTransformationTestValues testValues = std::get<2>(GetParam());
const bool oneInputWithSplit = std::get<3>(GetParam());
// dequantization output precision depends on input precision
// to avoid huge amount of tests cases let's define dequantization output precision as input precision
if (!testValues.actual.dequantizationBefore.multiply.empty()) {
@ -134,7 +136,7 @@ public:
actualFunction = ngraph::builder::subgraph::MoveFakeQuantize::get(
precision,
shape,
inputShapes,
testValues.actual.number_of_operations,
testValues.actual.fakeQuantizeBefore,
testValues.actual.convertBefore,
@ -149,7 +151,9 @@ public:
QuantizationAlignmentAttribute(false)
},
ngraph::element::undefined,
testValues.axis);
testValues.axis,
oneInputWithSplit);
auto supportedPrecisionsOnActivation = std::vector<ngraph::pass::low_precision::OperationPrecisionRestriction>({
ngraph::pass::low_precision::OperationPrecisionRestriction::create<ngraph::opset1::AvgPool>({{0, testValues.params.precisionsOnActivations}})
});
@ -179,7 +183,7 @@ public:
referenceFunction = ngraph::builder::subgraph::MoveFakeQuantize::get(
precision,
shape,
inputShapes,
testValues.result.number_of_operations,
testValues.result.fakeQuantizeBefore,
testValues.result.convertBefore,
@ -194,12 +198,14 @@ public:
QuantizationAlignmentAttribute(false)
},
testValues.result.precisionAfterOperation,
testValues.axis);
testValues.axis,
oneInputWithSplit);
}
static std::string getTestCaseName(testing::TestParamInfo<MoveFakeQuantizeTransformationParams> obj) {
const ngraph::element::Type precision = std::get<0>(obj.param);
const std::vector<ngraph::PartialShape> shape = std::get<1>(obj.param);
const MoveFakeQuantizeTransformationTestValues testValues = std::get<2>(obj.param);
const bool oneInputWithSplit = std::get<3>(obj.param);
std::ostringstream result;
result <<
@ -207,7 +213,8 @@ public:
(testValues.multiChannels ? "multiChannels_" : "notMultiChannels_") <<
"axis_" << testValues.axis << "_" <<
testValues.actual << "_" <<
testValues.result << "_";
testValues.result << "_" <<
oneInputWithSplit;
return result.str();
}
};
@ -231,10 +238,14 @@ const std::vector<ngraph::element::Type> precisions = {
namespace testValues1 {
const std::vector<std::vector<ngraph::PartialShape>> shapes = {
{{ 1, 3, 9, 9 }},
{{ 4, 3, 9, 9 }},
{{ Dimension::dynamic(), 3, Dimension::dynamic(), Dimension::dynamic() }}
{{ 1, 1, 9, 9 }, { 1, 1, 9, 9 }},
{{ 4, 3, 9, 9 }, { 4, 3, 9, 9 }},
{
{ Dimension::dynamic(), 1, Dimension::dynamic(), Dimension::dynamic() },
{ Dimension::dynamic(), 1, Dimension::dynamic(), Dimension::dynamic() }
}
};
const std::vector<MoveFakeQuantizeTransformationTestValues> testValues = {
// without operation
{
@ -424,19 +435,22 @@ INSTANTIATE_TEST_SUITE_P(
::testing::Combine(
::testing::ValuesIn(precisions),
::testing::ValuesIn(shapes),
::testing::ValuesIn(testValues)),
::testing::ValuesIn(testValues),
::testing::ValuesIn({ false, true })),
MoveFakeQuantizeTransformation::getTestCaseName);
} // namespace testValues1
namespace testValues2 {
const std::vector<ngraph::element::Type> precisions = {
ngraph::element::f32,
ngraph::element::f16
ngraph::element::f32,
ngraph::element::f16
};
const std::vector<std::vector<ngraph::PartialShape>> shapes = {
{{ 1, 1, 224, 224 }, { 1, 2, 224, 224 }},
{{ 4, 1, 9, 9 }, { 4, 2, 9, 9 }}
};
const std::vector<MoveFakeQuantizeTransformationTestValues> testValues = {
// multi-chanels
{
@ -560,13 +574,15 @@ const std::vector<MoveFakeQuantizeTransformationTestValues> testValues = {
}
},
};
INSTANTIATE_TEST_SUITE_P(
smoke_LPT,
MoveFakeQuantizeTransformation,
::testing::Combine(
::testing::ValuesIn(precisions),
::testing::ValuesIn(shapes),
::testing::ValuesIn(testValues)),
::testing::ValuesIn(testValues),
::testing::ValuesIn({ false })),
MoveFakeQuantizeTransformation::getTestCaseName);
} // namespace testValues2
} // namespace

View File

@ -24,9 +24,6 @@ const std::vector<LayerTestsDefinitions::MoveFakeQuantizeTransformationParam> pa
// without operation
{
3,
{},
{},
{},
"",
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f}},
{},
@ -38,9 +35,6 @@ const std::vector<LayerTestsDefinitions::MoveFakeQuantizeTransformationParam> pa
// with ReLU operation
{
3,
{},
{},
{},
"relu",
{ 256ul, {}, { -12.7f }, { 12.7f }, { -12.7f }, { 12.7f }},
{},
@ -52,9 +46,6 @@ const std::vector<LayerTestsDefinitions::MoveFakeQuantizeTransformationParam> pa
// Q/DQ
{
3,
{},
{},
{},
"",
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {255.f} },
{ ngraph::element::u8 },
@ -70,9 +61,6 @@ const std::vector<LayerTestsDefinitions::MoveFakeQuantizeTransformationParam> pa
// Q/DQ with ReLU
{
3,
{},
{},
{},
"relu",
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {255.f} },
{ ngraph::element::u8 },
@ -88,9 +76,6 @@ const std::vector<LayerTestsDefinitions::MoveFakeQuantizeTransformationParam> pa
// multi-chanels
{
3,
{},
{},
{},
"relu",
{
256ul,
@ -109,9 +94,6 @@ const std::vector<LayerTestsDefinitions::MoveFakeQuantizeTransformationParam> pa
// Q/DQ with multi-channels multiply
{
3,
{},
{},
{},
"",
{
256ul,
@ -134,9 +116,6 @@ const std::vector<LayerTestsDefinitions::MoveFakeQuantizeTransformationParam> pa
// Q/DQ with multi-channels subtract
{
3,
{},
{},
{},
"",
{
256ul,
@ -159,7 +138,8 @@ const std::vector<LayerTestsDefinitions::MoveFakeQuantizeTransformationParam> pa
};
const std::vector<std::vector<ngraph::PartialShape>> shapes = {
{{ 1, 1, 16, 16 }, { 1, 2, 16, 16 }, { 1, 3, 16, 16 }}
{{ 1, 1, 16, 16 }, { 1, 2, 16, 16 }, { 1, 3, 16, 16 }},
{{ 4, 1, 16, 16 }, { 4, 2, 16, 16 }, { 4, 3, 16, 16 }}
};
INSTANTIATE_TEST_SUITE_P(smoke_LPT, MoveFakeQuantizeTransformation,
@ -168,6 +148,7 @@ INSTANTIATE_TEST_SUITE_P(smoke_LPT, MoveFakeQuantizeTransformation,
::testing::ValuesIn(shapes),
::testing::Values(CommonTestUtils::DEVICE_CPU),
::testing::ValuesIn(trasformationParamValues),
::testing::ValuesIn({false, true}),
::testing::ValuesIn(params)),
MoveFakeQuantizeTransformation::getTestCaseName);
} // namespace testValues1
@ -178,9 +159,6 @@ namespace testValues2 {
// negative axis
{
3,
{},
{},
{},
"",
{256ul, {}, {-1.28f}, {1.27f}, {-1.28f}, {1.27f}},
{},
@ -191,7 +169,8 @@ namespace testValues2 {
},
};
const std::vector<std::vector<ngraph::PartialShape>> shapes = {
{{ 1, 1, 16, 16 }}
{{ 1, 1, 16, 16 }, { 1, 1, 16, 16 }, { 1, 1, 16, 16 }},
{{ 4, 1, 16, 16 }, { 4, 1, 16, 16 }, { 4, 1, 16, 16 }}
};
INSTANTIATE_TEST_SUITE_P(smoke_LPT, MoveFakeQuantizeTransformation,
@ -200,6 +179,7 @@ namespace testValues2 {
::testing::ValuesIn(shapes),
::testing::Values(CommonTestUtils::DEVICE_CPU),
::testing::ValuesIn(trasformationParamValues),
::testing::ValuesIn({false}),
::testing::ValuesIn(params)),
MoveFakeQuantizeTransformation::getTestCaseName);
} // namespace testValues2

View File

@ -20,12 +20,9 @@ const std::vector<ngraph::pass::low_precision::LayerTransformation::Params> tras
};
const std::vector<LayerTestsDefinitions::MoveFakeQuantizeTransformationParam> params = {
// without operation
// without operation
{
2,
{},
{},
{},
3,
"",
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {2.55f}},
{},
@ -36,10 +33,7 @@ const std::vector<LayerTestsDefinitions::MoveFakeQuantizeTransformationParam> pa
},
// with ReLU operation
{
2,
{},
{},
{},
3,
"relu",
{ 256ul, {}, { -12.7f }, { 12.7f }, { -12.7f }, { 12.7f }},
{},
@ -48,12 +42,9 @@ const std::vector<LayerTestsDefinitions::MoveFakeQuantizeTransformationParam> pa
"U8",
1
},
// negative axis
// negative axis
{
2,
{},
{},
{},
3,
"",
{256ul, {}, {-1.28f}, {1.27f}, {-1.28f}, {1.27f}},
{},
@ -64,10 +55,7 @@ const std::vector<LayerTestsDefinitions::MoveFakeQuantizeTransformationParam> pa
},
// Q/DQ
{
2,
{},
{},
{},
3,
"",
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {255.f} },
{ ngraph::element::u8 },
@ -82,10 +70,7 @@ const std::vector<LayerTestsDefinitions::MoveFakeQuantizeTransformationParam> pa
},
// Q/DQ with ReLU
{
2,
{},
{},
{},
3,
"relu",
{ 256ul, {}, {0.f}, {2.55f}, {0.f}, {255.f} },
{ ngraph::element::u8 },
@ -101,9 +86,6 @@ const std::vector<LayerTestsDefinitions::MoveFakeQuantizeTransformationParam> pa
// multi chanel
{
3,
{},
{},
{},
"relu",
{ 256ul,
{{1, 1, 1, 1}, {1, 1, 1, 1}, {1, 3, 1, 1}, {1, 3, 1, 1}},
@ -119,59 +101,53 @@ const std::vector<LayerTestsDefinitions::MoveFakeQuantizeTransformationParam> pa
},
// Q/DQ with multi-channels
{
3,
{},
{},
{},
"",
{
256ul,
{{1, 3, 1, 1}, {1, 3, 1, 1}, {1, 3, 1, 1}, {1, 3, 1, 1}},
{0.f, 0.f, 0.f},
{2.55f, 2.55f, 2.55f},
{0.f, 0.f, 0.f},
{255.f, 255.f, 255.f}
},
{ ngraph::element::u8 },
{
{ ngraph::element::f32 },
{},
{ {0.01f, 0.01f, 0.01f}, ngraph::element::f32, {1, 3, 1, 1} }
},
"Concat",
"U8",
1
3,
"",
{
256ul,
{{1, 3, 1, 1}, {1, 3, 1, 1}, {1, 3, 1, 1}, {1, 3, 1, 1}},
{0.f, 0.f, 0.f},
{2.55f, 2.55f, 2.55f},
{0.f, 0.f, 0.f},
{255.f, 255.f, 255.f}
},
{ ngraph::element::u8 },
{
{ ngraph::element::f32 },
{},
{ {0.01f, 0.01f, 0.01f}, ngraph::element::f32, {1, 3, 1, 1} }
},
"Concat",
"U8",
1
},
// Q/DQ with multi-channels subtruct
{
3,
{},
{},
{},
"",
{
256ul,
{{1, 3, 1, 1}, {1, 3, 1, 1}, {1, 3, 1, 1}, {1, 3, 1, 1}},
{0.f, 0.f, 0.f},
{2.55f, 2.55f, 2.55f},
{0.f, 0.f, 0.f},
{255.f, 255.f, 255.f}
},
{ ngraph::element::u8 },
{
{ ngraph::element::f32 },
{ {0.01f, 0.01f, 0.01f}, ngraph::element::f32, {1, 3, 1, 1} },
{ 0.01f }
},
"Concat",
"U8",
1
3,
"",
{
256ul,
{{1, 3, 1, 1}, {1, 3, 1, 1}, {1, 3, 1, 1}, {1, 3, 1, 1}},
{0.f, 0.f, 0.f},
{2.55f, 2.55f, 2.55f},
{0.f, 0.f, 0.f},
{255.f, 255.f, 255.f}
},
{ ngraph::element::u8 },
{
{ ngraph::element::f32 },
{ {0.01f, 0.01f, 0.01f}, ngraph::element::f32, {1, 3, 1, 1} },
{ 0.01f }
},
"Concat",
"U8",
1
},
};
const std::vector<std::vector<ngraph::PartialShape>> shapes = {
{{ 1, 1, 16, 16 }},
{{ 4, 1, 16, 16 }}
{{ 1, 1, 16, 16 }, { 1, 1, 16, 16 }, { 1, 1, 16, 16 }},
{{ 4, 1, 16, 16 }, { 4, 1, 16, 16 }, { 4, 1, 16, 16 }}
};
INSTANTIATE_TEST_SUITE_P(smoke_LPT, MoveFakeQuantizeTransformation,
@ -180,6 +156,7 @@ INSTANTIATE_TEST_SUITE_P(smoke_LPT, MoveFakeQuantizeTransformation,
::testing::ValuesIn(shapes),
::testing::Values(CommonTestUtils::DEVICE_GPU),
::testing::ValuesIn(trasformationParamValues),
::testing::ValuesIn({false, true}),
::testing::ValuesIn(params)),
MoveFakeQuantizeTransformation::getTestCaseName);
} // namespace

View File

@ -19,10 +19,7 @@ namespace LayerTestsDefinitions {
class MoveFakeQuantizeTransformationParam {
public:
size_t number_of_operations;
std::vector<ngraph::builder::subgraph::FakeQuantizeOnDataWithConstant> fakeQuantizeBefore;
ngraph::builder::subgraph::DequantizationOperations::Convert convertBefore;
ngraph::builder::subgraph::DequantizationOperations dequantizationBefore;
size_t concatInputsCount;
std::string operation;
ngraph::builder::subgraph::FakeQuantizeOnDataWithConstant fakeQuantizeAfter;
ngraph::builder::subgraph::DequantizationOperations::Convert convertAfter;
@ -37,6 +34,7 @@ typedef std::tuple <
std::vector<ngraph::PartialShape>,
std::string,
ngraph::pass::low_precision::LayerTransformation::Params,
bool,
MoveFakeQuantizeTransformationParam
> MoveFakeQuantizeTransformationParams;

View File

@ -23,42 +23,48 @@ std::string MoveFakeQuantizeTransformation::getTestCaseName(testing::TestParamIn
std::vector<ngraph::PartialShape> inputShape;
std::string targetDevice;
ngraph::pass::low_precision::LayerTransformation::Params params;
bool oneInputWithSplit;
MoveFakeQuantizeTransformationParam param;
std::tie(netPrecision, inputShape, targetDevice, params, param) = obj.param;
std::tie(netPrecision, inputShape, targetDevice, params, oneInputWithSplit, param) = obj.param;
std::ostringstream result;
result << getTestCaseNameByParams(netPrecision, inputShape[0], targetDevice, params) <<
param.operation << param.fakeQuantizeAfter << param.dequantizationAfter;
"SPLIT:" << oneInputWithSplit << "_" <<
"OP:" << param.operation << "_" <<
"FQ:" << param.fakeQuantizeAfter << "_" <<
"DQ:" << param.dequantizationAfter;
return result.str();
}
void MoveFakeQuantizeTransformation::SetUp() {
ngraph::element::Type netPrecision;
std::vector<ngraph::PartialShape> inputShape;
std::vector<ngraph::PartialShape> inputShapes;
ngraph::pass::low_precision::LayerTransformation::Params params;
bool oneInputWithSplit;
MoveFakeQuantizeTransformationParam param;
std::tie(netPrecision, inputShape, targetDevice, params, param) = this->GetParam();
std::tie(netPrecision, inputShapes, targetDevice, params, oneInputWithSplit, param) = this->GetParam();
function = ngraph::builder::subgraph::MoveFakeQuantize::get(
netPrecision,
inputShape,
param.number_of_operations,
param.fakeQuantizeBefore,
param.convertBefore,
param.dequantizationBefore,
inputShapes,
param.concatInputsCount,
{},
{},
{},
param.operation,
param.fakeQuantizeAfter,
param.convertAfter,
param.dequantizationAfter,
{},
{},
param.axis);
param.axis,
oneInputWithSplit);
}
void MoveFakeQuantizeTransformation::Run() {
LayerTestsCommon::Run();
const auto params = std::get<4>(GetParam());
const auto params = std::get<5>(GetParam());
const auto actualPrecision = getRuntimePrecisionByType(params.layerName);
auto expectedPrecision = params.expectedKernelType;
if (expectedPrecision == "FP32" && std::get<0>(GetParam()) == ngraph::element::f16) {

View File

@ -20,7 +20,7 @@ public:
static std::shared_ptr<ngraph::Function> get(
const ngraph::element::Type inputPrecision,
const std::vector<ngraph::PartialShape>& inputShape,
const size_t number_of_operations,
const size_t concatInputsCount,
const std::vector<FakeQuantizeOnDataWithConstant>& fqBefore,
const DequantizationOperations::Convert& convertBefore,
const DequantizationOperations& dequantizationBefore,
@ -30,7 +30,8 @@ public:
const DequantizationOperations& dequantizationAfter,
const std::vector<ov::Any>& concatAttributes,
const ngraph::element::Type precisionAfterOperation,
const std::int64_t& axis);
const std::int64_t& axis,
const bool oneInputWithSplit);
};
} // namespace subgraph

View File

@ -21,8 +21,8 @@ using namespace ngraph::pass;
std::shared_ptr<ngraph::Function> MoveFakeQuantize::get(
const ngraph::element::Type inputPrecision,
const std::vector<ngraph::PartialShape>& inputShape,
const size_t number_of_operations,
const std::vector<ngraph::PartialShape>& inputShapes,
const size_t concatInputsCount,
const std::vector<FakeQuantizeOnDataWithConstant>& fqOnDataBefore,
const DequantizationOperations::Convert& convertBefore,
const DequantizationOperations& dequantizationBefore,
@ -32,41 +32,73 @@ std::shared_ptr<ngraph::Function> MoveFakeQuantize::get(
const DequantizationOperations& dequantizationAfter,
const std::vector<ov::Any>& concatAttributes,
const ngraph::element::Type precisionAfterOperation,
const std::int64_t& axis) {
std::vector <std::shared_ptr<ngraph::opset1::Parameter>> inputs(number_of_operations);
std::vector <std::shared_ptr<ngraph::Node>> parents(number_of_operations);
for (size_t i = 0; i < number_of_operations; i++) {
auto ind = 0;
if (inputShape.size() != 1) {
ind = i;
const std::int64_t& axis,
const bool oneInputWithSplit) {
std::vector<std::shared_ptr<ngraph::opset1::Parameter>> inputs(oneInputWithSplit ? 1 : concatInputsCount);
std::vector<ov::Output<ov::Node>> concatParents(concatInputsCount);
if (oneInputWithSplit) {
auto newInputShape = inputShapes[0];
int channels = 0;
bool channelsWasIdentified = false;
for (const auto inputShape : inputShapes) {
if (inputShape[axis].is_static()) {
channels += inputShape[axis].get_length();
channelsWasIdentified = true;
}
}
if (channelsWasIdentified) {
newInputShape[axis] = channels;
}
inputs[0] = std::make_shared<ngraph::opset1::Parameter>(inputPrecision, newInputShape);
inputs[0]->set_friendly_name("input");
const auto axis_constant = std::make_shared<ngraph::opset1::Constant>(element::i32, Shape{}, std::vector<int64_t>({axis}));
std::vector<int> split_lengths_values(inputShapes.size(), 1);
split_lengths_values[split_lengths_values.size() - 1] = channels - (split_lengths_values.size() - 1);
const auto split_lengths = std::make_shared<ngraph::opset1::Constant>(element::i32, Shape{split_lengths_values.size()}, split_lengths_values);
const auto split = std::make_shared<ngraph::opset1::VariadicSplit>(inputs[0], axis_constant, split_lengths);
for (size_t i = 0; i < concatInputsCount; i++) {
concatParents[i] = split->output(i);
}
} else {
for (size_t i = 0; i < concatInputsCount; i++) {
auto ind = 0;
if (inputShapes.size() != 1) {
ind = i;
}
inputs[i] = std::make_shared<ngraph::opset1::Parameter>(inputPrecision, inputShapes[ind]);
inputs[i]->set_friendly_name(std::string("input") + "_" + std::to_string(i + 1));
concatParents[i] = inputs[i];
}
inputs[i] = std::make_shared<ngraph::opset1::Parameter>(inputPrecision, inputShape[ind]);
inputs[i]->set_friendly_name(std::string("input") + "_" + std::to_string(i + 1));
parents[i] = inputs[i];
}
if (!fqOnDataBefore.empty()) {
for (size_t i = 0; i < number_of_operations; i++) {
for (size_t i = 0; i < concatInputsCount; i++) {
size_t ind = i;
if (fqOnDataBefore.size() == 1) {
ind = 0;
}
if (operation == "relu") {
auto relu = std::make_shared<ngraph::opset1::Relu>(parents[i]->output(0));
parents[i] = makeFakeQuantize(relu, inputPrecision, fqOnDataBefore[ind]);
auto relu = std::make_shared<ngraph::opset1::Relu>(concatParents[i]);
concatParents[i] = makeFakeQuantize(relu, inputPrecision, fqOnDataBefore[ind]);
} else {
parents[i] = makeFakeQuantize(parents[i], inputPrecision, fqOnDataBefore[ind]);
concatParents[i] = makeFakeQuantize(concatParents[i], inputPrecision, fqOnDataBefore[ind]);
}
parents[i]->set_friendly_name(std::string("concat_fq") + "_" + std::to_string(i + 1));
concatParents[i].get_node()->set_friendly_name(std::string("concat_fq") + "_" + std::to_string(i + 1));
if (!convertBefore.empty()) {
parents[i] = std::make_shared<opset1::Convert>(parents[i], convertBefore.outPrecision);
concatParents[i] = std::make_shared<opset1::Convert>(concatParents[i], convertBefore.outPrecision);
}
if (!dequantizationBefore.empty()) {
parents[i] = makeDequantization(parents[i], dequantizationBefore);
concatParents[i] = makeDequantization(concatParents[i], dequantizationBefore);
}
}
}
const std::shared_ptr<ngraph::opset1::Concat> concat = std::make_shared<ngraph::opset1::Concat>(ngraph::OutputVector(parents.begin(), parents.end()), axis);
const auto concat = std::make_shared<ngraph::opset1::Concat>(
ngraph::OutputVector(concatParents.begin(), concatParents.end()),
axis);
concat->set_friendly_name("concat");
std::shared_ptr<ngraph::Node> parent = concat;
addAttributes({ parent }, concatAttributes);