[LPT] FQ reference implementation reused in foldFakeQuantize function (#17096)
* [LPT] reused reference FQ implementation in fold_fake_quantize * [LPT] Removed legacy parameters * Added plugin tests with per-channel FQ for GrConv wo reshape * Apply folding only in the case when FQ data input is constant * EliminateFQ fix
This commit is contained in:
1 parent
43a42fa9cd
commit
a8278ba4a6
10 files changed
+243
-181
No files matched your search
@@ -199,7 +199,7 @@ public:
|
||||
static std::shared_ptr<Node> toScalarIfPossible(std::shared_ptr<Node> node);
|
||||
|
||||
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 std::shared_ptr<Node> fold_fake_quantize(const std::shared_ptr<opset1::FakeQuantize>& fq, const bool roundValues);
|
||||
|
||||
static FakeQuantizeDequantization foldDequantization(const std::shared_ptr<Node>& node,
|
||||
const size_t branchIndex,
|
||||
@@ -256,8 +256,7 @@ private:
|
||||
static std::shared_ptr<Node> foldFakeQuantize(
|
||||
const std::shared_ptr<opset1::FakeQuantize>& fq,
|
||||
const bool roundValues,
|
||||
const bool roundValuesWasSet,
|
||||
int outChannelsShapeIndex = 0);
|
||||
const bool roundValuesWasSet);
|
||||
|
||||
// 1 - on weights
|
||||
// 0 - weightable layer was not found
|
||||
|
||||
@@ -214,9 +214,8 @@ bool ConvolutionTransformation::transform(TransformationContext &context, ngraph
|
||||
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());
|
||||
std::shared_ptr<ngraph::Node> newFQ = NetworkHelper::fold_fake_quantize(fq, true);
|
||||
if (const auto fq = ov::as_type_ptr<opset1::FakeQuantize>(dequantization.data.get_node_shared_ptr())) {
|
||||
const auto newFQ = NetworkHelper::fold_fake_quantize(fq, true);
|
||||
NetworkHelper::copyInfo(fq, newFQ);
|
||||
replace_node(fq, newFQ);
|
||||
}
|
||||
|
||||
@@ -87,10 +87,7 @@ bool ConvolutionBackpropDataTransformation::transform(TransformationContext &con
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<ngraph::Node> resultConstant = NetworkHelper::fold_fake_quantize(
|
||||
fqOnWeights,
|
||||
false,
|
||||
(constantShape.rank().get_length() < 2) || constantShape[1] != 1ul ? 1ul : 0ul);
|
||||
auto resultConstant = NetworkHelper::fold_fake_quantize(fqOnWeights, false);
|
||||
if (reshapeFromWeights != nullptr) {
|
||||
resultConstant = fold_reshape<opset1::Reshape>(
|
||||
resultConstant,
|
||||
@@ -147,16 +144,14 @@ bool ConvolutionBackpropDataTransformation::transform(TransformationContext &con
|
||||
decomposeFakeQuantizeForWeightsPath(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());
|
||||
std::shared_ptr<ngraph::Node> newFQ = NetworkHelper::fold_fake_quantize(fq, true, 1);
|
||||
if (const auto fq = ov::as_type_ptr<opset1::FakeQuantize>(dequantization.data.get_node_shared_ptr())) {
|
||||
const auto newFQ = NetworkHelper::fold_fake_quantize(fq, true);
|
||||
NetworkHelper::copyInfo(fq, newFQ);
|
||||
replace_node(fq, newFQ);
|
||||
}
|
||||
|
||||
std::shared_ptr<opset1::Multiply> multiplyFromWeights = ov::as_type_ptr<opset1::Multiply>(
|
||||
convolutionBackpropData->input_value(1).get_node_shared_ptr());
|
||||
std::shared_ptr<opset1::Subtract> subtractFromWeights = ov::as_type_ptr<opset1::Subtract>(multiplyFromWeights->get_input_node_shared_ptr(0));
|
||||
const auto multiplyFromWeights = convolutionBackpropData->get_input_node_shared_ptr(1);
|
||||
auto subtractFromWeights = ov::as_type_ptr<opset1::Subtract>(multiplyFromWeights->get_input_node_shared_ptr(0));
|
||||
|
||||
{
|
||||
const auto newScalePShape = multiplyFromWeights->get_input_partial_shape(1);
|
||||
|
||||
@@ -73,7 +73,7 @@ bool check_interval(const std::shared_ptr<opset1::FakeQuantize>& fq,
|
||||
fq->get_input_node_shared_ptr(2),
|
||||
fq->get_input_node_shared_ptr(3),
|
||||
fq->get_input_node_shared_ptr(4)}));
|
||||
auto result = NetworkHelper::fold_fake_quantize(tmp_fq, false, 1);
|
||||
auto result = NetworkHelper::fold_fake_quantize(tmp_fq, false);
|
||||
const auto result_constant = as_type_ptr<opset1::Constant>(result);
|
||||
if (result_constant == nullptr) {
|
||||
return false;
|
||||
|
||||
@@ -48,10 +48,7 @@ bool FoldFakeQuantizeTransformation::transform(TransformationContext& context, n
|
||||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<ngraph::Node> resultConstant = NetworkHelper::fold_fake_quantize(
|
||||
fakeQuantize,
|
||||
false,
|
||||
((constantShape.rank().get_length() >= 2) && (constantShape[1] != 1ul)) ? 1ul : 0ul);
|
||||
const auto resultConstant = NetworkHelper::fold_fake_quantize(fakeQuantize, false);
|
||||
if (ov::is_type<opset1::Constant>(resultConstant)) {
|
||||
replace_node(fakeQuantize, resultConstant);
|
||||
return true;
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "low_precision/rt_info/quantization_alignment_attribute.hpp"
|
||||
#include "ngraph/opsets/opset3.hpp"
|
||||
#include "ngraph/opsets/opset6.hpp"
|
||||
#include "transformations/utils/utils.hpp"
|
||||
|
||||
namespace ngraph {
|
||||
namespace pass {
|
||||
@@ -503,11 +504,9 @@ std::shared_ptr<Node> NetworkHelper::fold_fake_quantize(const std::shared_ptr<op
|
||||
return foldFakeQuantize(fq, false, false);
|
||||
}
|
||||
|
||||
std::shared_ptr<Node> NetworkHelper::fold_fake_quantize(
|
||||
const std::shared_ptr<opset1::FakeQuantize>& fq,
|
||||
const bool roundValues,
|
||||
const int outChannelsShapeIndex) {
|
||||
return foldFakeQuantize(fq, roundValues, true, outChannelsShapeIndex);
|
||||
std::shared_ptr<Node> NetworkHelper::fold_fake_quantize(const std::shared_ptr<opset1::FakeQuantize>& fq,
|
||||
const bool roundValues) {
|
||||
return foldFakeQuantize(fq, roundValues, true);
|
||||
}
|
||||
|
||||
FakeQuantizeDequantization NetworkHelper::foldDequantization(const std::shared_ptr<Node>& node,
|
||||
@@ -711,37 +710,8 @@ size_t NetworkHelper::calculateLevels(
|
||||
std::shared_ptr<Node> NetworkHelper::foldFakeQuantize(
|
||||
const std::shared_ptr<opset1::FakeQuantize>& fq,
|
||||
const bool roundValuesArg,
|
||||
const bool roundValuesWasSet,
|
||||
const int outChannelsShapeIndex) {
|
||||
if (ov::is_type<opset1::Constant>(fq->get_input_node_shared_ptr(0)) &&
|
||||
ov::is_type<opset1::Constant>(fq->get_input_node_shared_ptr(1)) &&
|
||||
ov::is_type<opset1::Constant>(fq->get_input_node_shared_ptr(2)) &&
|
||||
ov::is_type<opset1::Constant>(fq->get_input_node_shared_ptr(3)) &&
|
||||
ov::is_type<opset1::Constant>(fq->get_input_node_shared_ptr(4)) &&
|
||||
ov::op::util::constantIsEqualTo(ov::as_type_ptr<opset1::Constant>(fq->get_input_node_shared_ptr(1)), 0.f) &&
|
||||
ov::op::util::constantIsEqualTo(ov::as_type_ptr<opset1::Constant>(fq->get_input_node_shared_ptr(2)), 254.f) &&
|
||||
ov::op::util::constantIsEqualTo(ov::as_type_ptr<opset1::Constant>(fq->get_input_node_shared_ptr(3)), -127.f) &&
|
||||
ov::op::util::constantIsEqualTo(ov::as_type_ptr<opset1::Constant>(fq->get_input_node_shared_ptr(4)), 127.f)) {
|
||||
const auto type1 = fq->input_value(0).get_element_type();
|
||||
const auto type2 = fq->input_value(3).get_element_type();
|
||||
if (type1.is_real() && type2.is_real()) {
|
||||
return fold<opset1::Add>(fq->input_value(0), fq->input_value(3));
|
||||
}
|
||||
if (type1.is_real() && !type2.is_real()) {
|
||||
return fold<opset1::Add>(
|
||||
fq->input_value(0),
|
||||
foldConvert(fq->input_value(3), type1));
|
||||
}
|
||||
if (!type1.is_real() && type2.is_real()) {
|
||||
return fold<opset1::Add>(
|
||||
foldConvert(fq->input_value(0), type2),
|
||||
fq->input_value(3));
|
||||
}
|
||||
return fold<opset1::Add>(
|
||||
foldConvert(fq->input_value(0), element::f32),
|
||||
foldConvert(fq->input_value(3), element::f32));
|
||||
}
|
||||
|
||||
const bool roundValuesWasSet) {
|
||||
// Corner case
|
||||
// y = FakeQuantize(x, inputLow, inputHigh, outputLow, outputHigh)
|
||||
// given:
|
||||
// outputLow is const
|
||||
@@ -762,99 +732,20 @@ std::shared_ptr<Node> NetworkHelper::foldFakeQuantize(
|
||||
}
|
||||
}
|
||||
|
||||
auto constant = ov::as_type_ptr<opset1::Constant>(fq->get_input_node_shared_ptr(0));
|
||||
|
||||
if (constant) {
|
||||
const bool roundValues = roundValuesWasSet ? roundValuesArg : fq->get_output_element_type(0).is_integral();
|
||||
|
||||
const auto constPShape = fq->get_output_partial_shape(0);
|
||||
assert(constPShape.is_static());
|
||||
const Shape constShape = constPShape.to_shape();
|
||||
|
||||
if (constShape.size() > 5lu) {
|
||||
THROW_IE_LPT_EXCEPTION(*fq) << "Unexpected dimensions count " << constShape.size();
|
||||
}
|
||||
if (outChannelsShapeIndex != 0 && outChannelsShapeIndex != 1) {
|
||||
THROW_IE_LPT_EXCEPTION(*fq) << "Unexpected outChannelsShapeIndex " << outChannelsShapeIndex;
|
||||
if (ov::is_type<opset1::Constant>(fq->get_input_node_shared_ptr(0))) {
|
||||
std::shared_ptr<Node> subgraph = std::make_shared<ov::op::TypeRelaxed<opset1::FakeQuantize>>(*fq, element::f32);
|
||||
const auto& original_et = fq->get_output_element_type(0);
|
||||
const bool roundValues = roundValuesWasSet ? roundValuesArg : original_et.is_integral();
|
||||
if (roundValues) {
|
||||
subgraph = std::make_shared<opset6::Round>(subgraph, opset6::Round::RoundMode::HALF_TO_EVEN);
|
||||
}
|
||||
|
||||
size_t OC;
|
||||
size_t IC;
|
||||
// OIDHW or IODHW
|
||||
if (constShape.size() <= 1) {
|
||||
OC = constShape.empty() ? 1ul : constShape[0];
|
||||
IC = 1;
|
||||
} else {
|
||||
OC = constShape[outChannelsShapeIndex];
|
||||
IC = constShape[outChannelsShapeIndex == 0 ? 1 : 0];
|
||||
OPENVINO_SUPPRESS_DEPRECATED_START
|
||||
const auto result = ov::get_constant_from_source(subgraph);
|
||||
OPENVINO_SUPPRESS_DEPRECATED_END
|
||||
if (result != nullptr) {
|
||||
return foldConvert(result, original_et);
|
||||
}
|
||||
const size_t D = constShape.size() > 4lu ? constShape[constShape.size() - 3] : 1;
|
||||
const size_t H = constShape.size() > 2lu ? constShape.size() == 3lu ? constShape[2] : constShape[constShape.size() - 2] : 1;
|
||||
const size_t W = constShape.size() > 3lu ? constShape[constShape.size() - 1] : 1;
|
||||
|
||||
const auto inputLowValues = ov::as_type_ptr<opset1::Constant>(fq->get_input_node_shared_ptr(1))->cast_vector<float>();
|
||||
const auto inputHighValues = ov::as_type_ptr<opset1::Constant>(fq->get_input_node_shared_ptr(2))->cast_vector<float>();
|
||||
const auto outputLowValues = ov::as_type_ptr<opset1::Constant>(fq->get_input_node_shared_ptr(3))->cast_vector<float>();
|
||||
const auto outputHighValues = ov::as_type_ptr<opset1::Constant>(fq->get_input_node_shared_ptr(4))->cast_vector<float>();
|
||||
|
||||
const size_t inputLowSize = inputLowValues.size();
|
||||
const size_t inputHighSize = inputHighValues.size();
|
||||
const size_t outputLowSize = outputLowValues.size();
|
||||
const size_t outputHighSize = outputHighValues.size();
|
||||
|
||||
const bool isInputLowBroadcasted = inputLowSize != OC;
|
||||
if ((inputLowSize != 1) && (inputLowSize != OC)) {
|
||||
THROW_IE_LPT_EXCEPTION(*fq) << "Unexpected input low values count " << inputLowSize << " for " << OC << " channels";
|
||||
}
|
||||
const bool isInputHighBroadcasted = inputHighSize != OC;
|
||||
if ((inputHighSize != 1) && (inputHighSize != OC)) {
|
||||
THROW_IE_LPT_EXCEPTION(*fq) << "Unexpected input high values count " << inputHighSize << " for " << OC << " channels";
|
||||
}
|
||||
const bool isOutputLowBroadcasted = outputLowSize != OC;
|
||||
if ((outputLowSize != 1) && (outputLowSize != OC)) {
|
||||
THROW_IE_LPT_EXCEPTION(*fq) << "Unexpected output low values count " << outputLowSize << " for " << OC << " channels";
|
||||
}
|
||||
const bool isOutputHighBroadcasted = outputHighSize != OC;
|
||||
if ((outputHighSize != 1) && (outputHighSize != OC)) {
|
||||
THROW_IE_LPT_EXCEPTION(*fq) << "Unexpected output high values count " << outputHighSize << " for " << OC << " channels";
|
||||
}
|
||||
|
||||
auto levels_1 = fq->get_levels() - 1.f;
|
||||
|
||||
const size_t DHW = D * H * W;
|
||||
const size_t IDHW = outChannelsShapeIndex == 0 ? IC * D * H * W : OC * D * H * W;
|
||||
|
||||
const auto values = constant->cast_vector<float>();
|
||||
std::vector<float> quantizedValues(OC * IC * D * H * W);
|
||||
|
||||
for (size_t oc = 0; oc < OC; ++oc) {
|
||||
const float inputLow = inputLowValues[isInputLowBroadcasted ? 0 : oc];
|
||||
const float inputHigh = inputHighValues[isInputHighBroadcasted ? 0 : oc];
|
||||
const float outputLow = outputLowValues[isOutputLowBroadcasted ? 0 : oc];
|
||||
const float outputHigh = outputHighValues[isOutputHighBroadcasted ? 0 : oc];
|
||||
for (size_t ic = 0; ic < IC; ++ic) {
|
||||
for (size_t iidx = 0; iidx < DHW; ++iidx) {
|
||||
size_t idx;
|
||||
if (outChannelsShapeIndex == 0) {
|
||||
idx = oc * IDHW + ic * DHW + iidx;
|
||||
} else {
|
||||
idx = ic * IDHW + oc * DHW + iidx;
|
||||
}
|
||||
|
||||
if (values[idx] <= inputLow) {
|
||||
quantizedValues[idx] = roundValues ? std::roundf(outputLow) : outputLow;
|
||||
} else if (values[idx] > inputHigh) {
|
||||
quantizedValues[idx] = roundValues ? std::roundf(outputHigh) : outputHigh;
|
||||
} else {
|
||||
const float value = std::roundf((values[idx] - inputLow) / (inputHigh - inputLow) * levels_1) /
|
||||
levels_1 * (outputHigh - outputLow) + outputLow;
|
||||
quantizedValues[idx] = roundValues ? std::roundf(value) : value;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return std::make_shared<opset1::Constant>(fq->get_output_element_type(0), constShape, quantizedValues);
|
||||
}
|
||||
|
||||
return fq;
|
||||
@@ -1086,8 +977,7 @@ std::tuple<std::shared_ptr<Node>, std::shared_ptr<Node>> NetworkHelper::decompos
|
||||
newMax->output(0),
|
||||
fq->get_levels(),
|
||||
fq->get_auto_broadcast()),
|
||||
true,
|
||||
static_cast<int>(outChannelsShapeIndex));
|
||||
true);
|
||||
NetworkHelper::copyInfo(fq, newFQ);
|
||||
|
||||
std::shared_ptr<ngraph::Node> convert2;
|
||||
|
||||
+1
-1
@@ -133,7 +133,7 @@ const std::vector<FoldFakeQuantizeInTransformationsTestValues> testValues = {
|
||||
{255ul, {}, {0.f}, {254.f}, {-127.f}, {127.f}},
|
||||
ngraph::element::i8,
|
||||
},
|
||||
{{-126, -127, -50, -2, 127, -27, -127, 0, -127, -63, -126, 127, -120, -127, -118, -127}, ngraph::element::f32},
|
||||
{{-126, -127, -50, -2, 127, -27, -127, 0, -127, -63, -126, 127, -120, -127, -118, -127}, ngraph::element::i8},
|
||||
},
|
||||
{
|
||||
Shape{2, 2, 2, 2},
|
||||
|
||||
+109
-6
@@ -70,18 +70,18 @@ const std::vector<LayerTestsDefinitions::GroupConvolutionTransformationParam> pa
|
||||
},
|
||||
{ 255ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 254.f }, { -127.f }, { 127.f } },
|
||||
true,
|
||||
"",
|
||||
""
|
||||
"Convolution",
|
||||
"U8"
|
||||
},
|
||||
// group convolution, per-channel weights quantization
|
||||
// group convolution without reshape, tensor quantization
|
||||
{
|
||||
3ul,
|
||||
-1,
|
||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 25.5f }, { 0.f }, { 25.5f } },
|
||||
{ 255ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 254.f }, { -127.f }, { 127.f } },
|
||||
false,
|
||||
"",
|
||||
""
|
||||
"Convolution",
|
||||
"U8"
|
||||
}
|
||||
};
|
||||
|
||||
@@ -95,6 +95,110 @@ INSTANTIATE_TEST_SUITE_P(smoke_LPT, GroupConvolutionTransformation,
|
||||
::testing::ValuesIn(addPrecisionPreserved)),
|
||||
GroupConvolutionTransformation::getTestCaseName);
|
||||
|
||||
namespace test_values_4d {
|
||||
const std::vector<std::pair<ngraph::PartialShape, ngraph::Shape>> inputShapes = {
|
||||
{{ 1, 6, 24, 24 }, { 1, 24, 18, 18 }},
|
||||
};
|
||||
|
||||
const std::vector<LayerTestsDefinitions::GroupConvolutionTransformationParam> params = {
|
||||
// group convolution without reshape, per channel quantization
|
||||
{
|
||||
3ul,
|
||||
-1,
|
||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 25.5f }, { 0.f }, { 25.5f } },
|
||||
{ 255ul, ngraph::Shape { 3, 8, 1, 1, 1 }, { -127.f }, { 127.f }, { -127.f }, { 127.f } },
|
||||
false,
|
||||
"Convolution",
|
||||
"U8"
|
||||
},
|
||||
// group convolution without reshape, per channel quantization with different values
|
||||
{
|
||||
3ul,
|
||||
-1,
|
||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 25.5f }, { 0.f }, { 25.5f } },
|
||||
{ 255ul, ngraph::Shape { 3, 8, 1, 1, 1 },
|
||||
{-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f,
|
||||
-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f,
|
||||
-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f},
|
||||
{127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f,
|
||||
127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f,
|
||||
127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f},
|
||||
{-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f,
|
||||
-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f,
|
||||
-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f},
|
||||
{127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f,
|
||||
127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f,
|
||||
127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f}
|
||||
},
|
||||
false,
|
||||
"Convolution",
|
||||
"U8"
|
||||
},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_LPT, GroupConvolutionTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU),
|
||||
::testing::ValuesIn(trasformationParamValues),
|
||||
::testing::ValuesIn(inputShapes),
|
||||
::testing::ValuesIn(params),
|
||||
::testing::Values(false)),
|
||||
GroupConvolutionTransformation::getTestCaseName);
|
||||
} // namespace test_values_4d
|
||||
|
||||
namespace test_values_3d {
|
||||
const std::vector<std::pair<ngraph::PartialShape, ngraph::Shape>> inputShapes = {
|
||||
{{ 1, 6, 24 }, { 1, 24, 18 }},
|
||||
};
|
||||
|
||||
const std::vector<LayerTestsDefinitions::GroupConvolutionTransformationParam> params = {
|
||||
// group convolution without reshape, per channel quantization
|
||||
{
|
||||
3ul,
|
||||
-1,
|
||||
{ 256ul, ngraph::Shape { 1, 1, 1 }, { 0.f }, { 25.5f }, { 0.f }, { 25.5f } },
|
||||
{ 255ul, ngraph::Shape { 3, 8, 1, 1 }, { -127.f }, { 127.f }, { -127.f }, { 127.f } },
|
||||
false,
|
||||
"Convolution",
|
||||
"U8"
|
||||
},
|
||||
// group convolution without reshape, per channel quantization with different values
|
||||
{
|
||||
3ul,
|
||||
-1,
|
||||
{ 256ul, ngraph::Shape { 1, 1, 1 }, { 0.f }, { 25.5f }, { 0.f }, { 25.5f } },
|
||||
{ 255ul, ngraph::Shape { 3, 8, 1, 1 },
|
||||
{-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f,
|
||||
-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f,
|
||||
-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f},
|
||||
{127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f,
|
||||
127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f,
|
||||
127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f},
|
||||
{-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f,
|
||||
-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f,
|
||||
-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f},
|
||||
{127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f,
|
||||
127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f,
|
||||
127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f}
|
||||
},
|
||||
false,
|
||||
"Convolution",
|
||||
"U8"
|
||||
},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_LPT, GroupConvolutionTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU),
|
||||
::testing::ValuesIn(trasformationParamValues),
|
||||
::testing::ValuesIn(inputShapes),
|
||||
::testing::ValuesIn(params),
|
||||
::testing::Values(false)),
|
||||
GroupConvolutionTransformation::getTestCaseName);
|
||||
} // namespace test_values_3d
|
||||
|
||||
namespace depthwise {
|
||||
const std::vector<std::pair<ngraph::PartialShape, ngraph::Shape>> inputShapes = {
|
||||
{{ 1, 6, 24, 24 }, { 1, 6, 18, 18 }},
|
||||
@@ -158,5 +262,4 @@ INSTANTIATE_TEST_SUITE_P(smoke_LPT, GroupConvolutionTransformation,
|
||||
::testing::ValuesIn(addPrecisionPreserved)),
|
||||
GroupConvolutionTransformation::getTestCaseName);
|
||||
} // namespace depthwise
|
||||
|
||||
} // namespace
|
||||
+104
@@ -93,6 +93,110 @@ INSTANTIATE_TEST_SUITE_P(smoke_LPT, GroupConvolutionTransformation,
|
||||
::testing::ValuesIn(addPrecisionPreserved)),
|
||||
GroupConvolutionTransformation::getTestCaseName);
|
||||
|
||||
namespace test_values_4d {
|
||||
const std::vector<std::pair<ngraph::PartialShape, ngraph::Shape>> inputShapes = {
|
||||
{{ 1, 6, 24, 24 }, { 1, 24, 18, 18 }},
|
||||
};
|
||||
|
||||
const std::vector<LayerTestsDefinitions::GroupConvolutionTransformationParam> params = {
|
||||
// group convolution without reshape, per channel quantization
|
||||
{
|
||||
3ul,
|
||||
-1,
|
||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 25.5f }, { 0.f }, { 25.5f } },
|
||||
{ 255ul, ngraph::Shape { 3, 8, 1, 1, 1 }, { -127.f }, { 127.f }, { -127.f }, { 127.f } },
|
||||
false,
|
||||
"Convolution",
|
||||
"U8"
|
||||
},
|
||||
// group convolution without reshape, per channel quantization with different values
|
||||
{
|
||||
3ul,
|
||||
-1,
|
||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 25.5f }, { 0.f }, { 25.5f } },
|
||||
{ 255ul, ngraph::Shape { 3, 8, 1, 1, 1 },
|
||||
{-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f,
|
||||
-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f,
|
||||
-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f},
|
||||
{127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f,
|
||||
127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f,
|
||||
127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f},
|
||||
{-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f,
|
||||
-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f,
|
||||
-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f},
|
||||
{127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f,
|
||||
127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f,
|
||||
127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f}
|
||||
},
|
||||
false,
|
||||
"Convolution",
|
||||
"U8"
|
||||
},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_LPT, GroupConvolutionTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU),
|
||||
::testing::ValuesIn(trasformationParamValues),
|
||||
::testing::ValuesIn(inputShapes),
|
||||
::testing::ValuesIn(params),
|
||||
::testing::Values(false)),
|
||||
GroupConvolutionTransformation::getTestCaseName);
|
||||
} // namespace test_values_4d
|
||||
|
||||
namespace test_values_3d {
|
||||
const std::vector<std::pair<ngraph::PartialShape, ngraph::Shape>> inputShapes = {
|
||||
{{ 1, 6, 24 }, { 1, 24, 18 }},
|
||||
};
|
||||
|
||||
const std::vector<LayerTestsDefinitions::GroupConvolutionTransformationParam> params = {
|
||||
// group convolution without reshape, per channel quantization
|
||||
{
|
||||
3ul,
|
||||
-1,
|
||||
{ 256ul, ngraph::Shape { 1, 1, 1 }, { 0.f }, { 25.5f }, { 0.f }, { 25.5f } },
|
||||
{ 255ul, ngraph::Shape { 3, 8, 1, 1 }, { -127.f }, { 127.f }, { -127.f }, { 127.f } },
|
||||
false,
|
||||
"Convolution",
|
||||
"U8"
|
||||
},
|
||||
// group convolution without reshape, per channel quantization with different values
|
||||
{
|
||||
3ul,
|
||||
-1,
|
||||
{ 256ul, ngraph::Shape { 1, 1, 1 }, { 0.f }, { 25.5f }, { 0.f }, { 25.5f } },
|
||||
{ 255ul, ngraph::Shape { 3, 8, 1, 1 },
|
||||
{-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f,
|
||||
-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f,
|
||||
-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f},
|
||||
{127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f,
|
||||
127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f,
|
||||
127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f},
|
||||
{-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f,
|
||||
-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f,
|
||||
-127.f, -12.7f, -1.27f, -127.f, -12.7f, -1.27f, -127.f, -12.7f},
|
||||
{127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f,
|
||||
127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f,
|
||||
127.f, 12.7f, 1.27f, 127.f, 12.7f, 1.27f, 127.f, 12.7f}
|
||||
},
|
||||
false,
|
||||
"Convolution",
|
||||
"U8"
|
||||
},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(smoke_LPT, GroupConvolutionTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU),
|
||||
::testing::ValuesIn(trasformationParamValues),
|
||||
::testing::ValuesIn(inputShapes),
|
||||
::testing::ValuesIn(params),
|
||||
::testing::Values(false)),
|
||||
GroupConvolutionTransformation::getTestCaseName);
|
||||
} // namespace test_values_3d
|
||||
|
||||
namespace depthwise {
|
||||
const std::vector<std::pair<ngraph::PartialShape, ngraph::Shape>> inputShapes = {
|
||||
{{ 1, 6, 24, 24 }, { 1, 6, 18, 18 }}
|
||||
|
||||
-25
@@ -19,29 +19,6 @@
|
||||
#include "lpt_ngraph_functions/group_convolution_function.hpp"
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
namespace {
|
||||
std::shared_ptr<ov::Model> replaceFQConstantsOnScalars(const std::shared_ptr<ov::Model>& m) {
|
||||
auto model = ngraph::clone_function(*m);
|
||||
for (const auto& op : model->get_ordered_ops()) {
|
||||
if (!ov::is_type<ov::opset10::FakeQuantize>(op))
|
||||
continue;
|
||||
for (size_t i = 1; i < op->get_input_size(); ++i) {
|
||||
if (auto constant = ov::as_type_ptr<ov::opset10::Constant>(op->get_input_node_shared_ptr(i))) {
|
||||
const auto& shape = constant->get_shape();
|
||||
if (ov::shape_size(shape) > 1) {
|
||||
const auto values = constant->cast_vector<float>();
|
||||
if (std::all_of(values.begin(), values.end(), [&](float x) { return x == values[0]; })) {
|
||||
const auto scalar_constant = ov::opset10::Constant::create(constant->get_element_type(), {}, &values[0]);
|
||||
ov::replace_node(constant, scalar_constant);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return model;
|
||||
}
|
||||
} // namespace
|
||||
|
||||
std::string GroupConvolutionTransformation::getTestCaseName(const testing::TestParamInfo<GroupConvolutionTransformationParams>& obj) {
|
||||
ngraph::element::Type netPrecision;
|
||||
std::string targetDevice;
|
||||
@@ -89,8 +66,6 @@ void GroupConvolutionTransformation::SetUp() {
|
||||
param.fakeQuantizeOnWeights,
|
||||
param.addReshape,
|
||||
addPrecisionPreserved);
|
||||
// WA for issue #107400
|
||||
functionRefs = replaceFQConstantsOnScalars(function);
|
||||
}
|
||||
|
||||
void GroupConvolutionTransformation::Run() {
|
||||
|
||||
Reference in new issue
Block a user