[CPU] Optimize quantization scheme for SPR/ATS (#7549)
* [CPU] Optimize quantization scheme for SPR/ATS * [CPU] [LPT] plugin tests * [GPU] [LPT] plugin tests * [CPU] limitation was removed * [CPU] optimization FP32 old way support * [LPT] comment fix * [LPT] Multiply plugin test improvement * [LPT] Multiply support * [LPT] GPU tests fix * [LPT] test quick fix * [LPT] new ppi fix * look like spent time for tests refactoring
This commit is contained in:
parent
abee3ea4d4
commit
37ad512d98
@ -1134,8 +1134,38 @@ void MKLDNNGraphOptimizer::FuseConvolutionSumAndConvolutionSumActivation(MKLDNNG
|
|||||||
if (!isSuitableParent1 && !isSuitableParent2)
|
if (!isSuitableParent1 && !isSuitableParent2)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto mergedConv = isSuitableParent1 ? parent1 : parent2;
|
std::shared_ptr<MKLDNNNode> mergedConv;
|
||||||
auto peerNode = isSuitableParent1 ? parent2 : parent1;
|
std::shared_ptr<MKLDNNNode> peerNode;
|
||||||
|
|
||||||
|
if (isSuitableParent1 && isSuitableParent2) {
|
||||||
|
// not merged operation (peerNode) has to be in low precision
|
||||||
|
const auto isBranchQuantized = [](const MKLDNNNodePtr& branchParent) {
|
||||||
|
const auto& fused = branchParent->getFusedWith();
|
||||||
|
const auto branchPrecision = fused.empty() ?
|
||||||
|
branchParent->getOriginalOutputPrecisionAtPort(0) :
|
||||||
|
fused[fused.size() - 1]->getOriginalOutputPrecisionAtPort(0);
|
||||||
|
return (branchPrecision == Precision::I8) || (branchPrecision == Precision::U8);
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto isBranch1Quantized = isBranchQuantized(graphNode->getParentEdgesAtPort(0)[0]->getParent());
|
||||||
|
const auto isBranch2Quantized = isBranchQuantized(graphNode->getParentEdgesAtPort(1)[0]->getParent());
|
||||||
|
if (isBranch1Quantized || isBranch2Quantized) {
|
||||||
|
// INT8
|
||||||
|
const auto parent1CanBeMerged = parent1->getChildEdges().size() == 1ul;
|
||||||
|
|
||||||
|
// if both branches are quantized, then parent1 is selected (result is not changed)
|
||||||
|
mergedConv = isBranch2Quantized && parent1CanBeMerged ? parent1 : parent2;
|
||||||
|
peerNode = isBranch2Quantized && parent1CanBeMerged ? parent2 : parent1;
|
||||||
|
} else {
|
||||||
|
// original FP32
|
||||||
|
mergedConv = isSuitableParent1 ? parent1 : parent2;
|
||||||
|
peerNode = isSuitableParent1 ? parent2 : parent1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
mergedConv = isSuitableParent1 ? parent1 : parent2;
|
||||||
|
peerNode = isSuitableParent1 ? parent2 : parent1;
|
||||||
|
}
|
||||||
|
|
||||||
if (isSuitableParent1 && isSuitableParent2) {
|
if (isSuitableParent1 && isSuitableParent2) {
|
||||||
if ((peerNode->getType() == Convolution || peerNode->getType() == BinaryConvolution) &&
|
if ((peerNode->getType() == Convolution || peerNode->getType() == BinaryConvolution) &&
|
||||||
mergedConv->getChildEdges().size() != 1) {
|
mergedConv->getChildEdges().size() != 1) {
|
||||||
|
@ -97,18 +97,14 @@ bool MultiplyTransformation::transform(TransformationContext& context, ngraph::p
|
|||||||
} else {
|
} else {
|
||||||
const int emptyPathIndex = fullPathIndex == 0 ? 1 : 0;
|
const int emptyPathIndex = fullPathIndex == 0 ? 1 : 0;
|
||||||
|
|
||||||
FakeQuantizeDequantization dequantizationEmptyPath = NetworkHelper::getDequantization(multiply, emptyPathIndex);
|
if (updatePrecisions) {
|
||||||
if ((updatePrecisions && !dequantizationEmptyPath.empty() && !dequantizationEmptyPath.isLowPrecision()) ||
|
const FakeQuantizeDequantization dequantizationEmptyPath = NetworkHelper::getDequantization(multiply, emptyPathIndex);
|
||||||
(dequantizationEmptyPath.multiply == nullptr && dequantizationEmptyPath.subtract == nullptr)) {
|
if (!dequantizationEmptyPath.empty() && !dequantizationEmptyPath.isLowPrecision()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
FakeQuantizeDequantization dequantizationFullPath = NetworkHelper::getDequantization(multiply, fullPathIndex);
|
|
||||||
if (updatePrecisions && !dequantizationFullPath.empty() && !dequantizationFullPath.isLowPrecision()) {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
dequantizationEmptyPath = NetworkHelper::foldDequantization(multiply, emptyPathIndex);
|
FakeQuantizeDequantization dequantizationEmptyPath = NetworkHelper::foldDequantization(multiply, emptyPathIndex);
|
||||||
std::shared_ptr<Node> subtractValuesEmptyPath;
|
std::shared_ptr<Node> subtractValuesEmptyPath;
|
||||||
std::shared_ptr<Node> multiplyValuesEmptyPath;
|
std::shared_ptr<Node> multiplyValuesEmptyPath;
|
||||||
std::tie(subtractValuesEmptyPath, multiplyValuesEmptyPath) = NetworkHelper::createEmptyValues(dequantizationEmptyPath, deqPrecision);
|
std::tie(subtractValuesEmptyPath, multiplyValuesEmptyPath) = NetworkHelper::createEmptyValues(dequantizationEmptyPath, deqPrecision);
|
||||||
@ -118,7 +114,7 @@ bool MultiplyTransformation::transform(TransformationContext& context, ngraph::p
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
dequantizationFullPath = NetworkHelper::foldDequantization(multiply, fullPathIndex);
|
FakeQuantizeDequantization dequantizationFullPath = NetworkHelper::foldDequantization(multiply, fullPathIndex);
|
||||||
std::shared_ptr<Node> subtractValuesFullPath;
|
std::shared_ptr<Node> subtractValuesFullPath;
|
||||||
std::shared_ptr<Node> multiplyValuesFullPath;
|
std::shared_ptr<Node> multiplyValuesFullPath;
|
||||||
std::tie(subtractValuesFullPath, multiplyValuesFullPath) = NetworkHelper::createEmptyValues(dequantizationFullPath, deqPrecision);
|
std::tie(subtractValuesFullPath, multiplyValuesFullPath) = NetworkHelper::createEmptyValues(dequantizationFullPath, deqPrecision);
|
||||||
|
@ -0,0 +1,100 @@
|
|||||||
|
// Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "low_precision_transformations/elementwise_branch_selection_transformation.hpp"
|
||||||
|
#include "common_test_utils/test_constants.hpp"
|
||||||
|
|
||||||
|
using namespace LayerTestsDefinitions;
|
||||||
|
using namespace InferenceEngine::details;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const std::vector<ngraph::element::Type> netPrecisions = {
|
||||||
|
ngraph::element::f32,
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::vector<std::string> elementwiseTypes = {
|
||||||
|
"add",
|
||||||
|
"multiply"
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::vector<LayerTestsDefinitions::ElementwiseBranchSelectionTestValues> params = {
|
||||||
|
{
|
||||||
|
{
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
{
|
||||||
|
{},
|
||||||
|
{ std::vector<float>(9, 1.f), ngraph::element::i8, {3, 3, 1, 1} },
|
||||||
|
{ {ngraph::element::f32}, {}, {std::vector<float>(3, 1.f), ngraph::element::f32, {3, 1, 1, 1}} }
|
||||||
|
},
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
{
|
||||||
|
{},
|
||||||
|
{ std::vector<float>(9, 1.f), ngraph::element::i8, {3, 3, 1, 1} },
|
||||||
|
{ {ngraph::element::f32}, {}, {std::vector<float>(3, 1.f), ngraph::element::f32, {3, 1, 1, 1}} }
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
},
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
{
|
||||||
|
{"Constant", "convolution1"},
|
||||||
|
{"Constant", "convolution2"},
|
||||||
|
{"fakeQuantizeBefore1", "convolution1"},
|
||||||
|
{"fakeQuantizeBefore2", "convolution2"},
|
||||||
|
{"maxPool", "result"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{"convolution1", "U8"},
|
||||||
|
{"convolution2", "U8"},
|
||||||
|
{"eltwise", "U8"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
{
|
||||||
|
{},
|
||||||
|
{ std::vector<float>(9, 1.f), ngraph::element::i8, {3, 3, 1, 1} },
|
||||||
|
{ {ngraph::element::f32}, {}, {std::vector<float>(3, 1.f), ngraph::element::f32, {3, 1, 1, 1}} }
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
{
|
||||||
|
{},
|
||||||
|
{ std::vector<float>(9, 1.f), ngraph::element::i8, {3, 3, 1, 1} },
|
||||||
|
{ {ngraph::element::f32}, {}, {std::vector<float>(3, 1.f), ngraph::element::f32, {3, 1, 1, 1}} }
|
||||||
|
},
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
},
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
{
|
||||||
|
{"Constant", "convolution1"},
|
||||||
|
{"Constant", "convolution2"},
|
||||||
|
{"fakeQuantizeBefore1", "convolution1"},
|
||||||
|
{"fakeQuantizeBefore2", "convolution2"},
|
||||||
|
{"maxPool", "result"}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{"convolution1", "U8"},
|
||||||
|
{"convolution2", "U8"},
|
||||||
|
{"eltwise", "U8"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(smoke_LPT, ElementwiseBranchSelectionTransformation,
|
||||||
|
::testing::Combine(
|
||||||
|
::testing::ValuesIn(netPrecisions),
|
||||||
|
::testing::Values(ngraph::PartialShape({ 1, 3, 16, 16 })),
|
||||||
|
::testing::Values(CommonTestUtils::DEVICE_CPU),
|
||||||
|
::testing::ValuesIn(params),
|
||||||
|
::testing::ValuesIn(elementwiseTypes)),
|
||||||
|
ElementwiseBranchSelectionTransformation::getTestCaseName);
|
||||||
|
} // namespace
|
@ -17,54 +17,63 @@ const std::vector<ngraph::element::Type> netPrecisions = {
|
|||||||
|
|
||||||
const std::vector<LayerTestsDefinitions::MultiplyTestValues> params = {
|
const std::vector<LayerTestsDefinitions::MultiplyTestValues> params = {
|
||||||
{
|
{
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { 0.f }, { 255.f } },
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { -128.f }, { 127.f } },
|
|
||||||
false,
|
false,
|
||||||
{ngraph::element::i8}, {ngraph::element::f32, ngraph::element::i8}
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
},
|
|
||||||
{
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -128.f }, { 127.f }, { -128.f }, { 127.f } },
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { 0.f }, { 255.f } },
|
|
||||||
false,
|
false,
|
||||||
{ngraph::element::i8}, {ngraph::element::f32, ngraph::element::f32}
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -1.28f }, { 1.27f }, { -1.28f }, { 1.27f } },
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -1.28f }, { 1.27f }, { -1.28f }, { 1.27f } },
|
||||||
|
ngraph::element::i8
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { 0.f }, { 255.f } },
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { -128.f }, { 127.f } },
|
|
||||||
true,
|
|
||||||
{ngraph::element::i8}, {ngraph::element::f32, ngraph::element::f32}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -128.f }, { 127.f }, { -128.f }, { 127.f } },
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { 0.f }, { 255.f } },
|
|
||||||
true,
|
|
||||||
{ngraph::element::i8}, {ngraph::element::i8, ngraph::element::f32}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { 0.f }, { 255.f } },
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { -127.f }, { 128.f } },
|
|
||||||
false,
|
false,
|
||||||
{ngraph::element::u8}, {ngraph::element::f32, ngraph::element::f32}
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
},
|
|
||||||
{
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -128.f }, { 127.f }, { -128.f }, { 127.f } },
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { 0.f }, { 255.f } },
|
|
||||||
false,
|
false,
|
||||||
{ngraph::element::u8}, {ngraph::element::f32, ngraph::element::u8}
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
ngraph::element::u8
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { 0.f }, { 255.f } },
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { -127.f }, { 128.f } },
|
|
||||||
true,
|
true,
|
||||||
{ngraph::element::u8}, {ngraph::element::u8, ngraph::element::f32}
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -1.28f }, { 1.27f }, { -1.28f }, { 1.27f } },
|
||||||
|
false,
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
ngraph::element::u8
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -128.f }, { 127.f }, { -128.f }, { 127.f } },
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { 0.f }, { 255.f } },
|
|
||||||
true,
|
true,
|
||||||
{ngraph::element::u8}, {ngraph::element::f32, ngraph::element::f32}
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
false,
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -1.28f }, { 1.27f }, { -1.28f }, { 1.27f } },
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -1.28f }, { 1.27f }, { -1.28f }, { 1.27f } },
|
||||||
|
ngraph::element::i8
|
||||||
},
|
},
|
||||||
{ {}, {}, false }, { {}, {}, true },
|
{
|
||||||
|
false,
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -1.28f }, { 1.27f }, { -1.28f }, { 1.27f } },
|
||||||
|
true,
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -1.28f }, { 1.27f }, { -1.28f }, { 1.27f } },
|
||||||
|
ngraph::element::i8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
false,
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -1.28f }, { 1.27f }, { -128.f }, { 1.27f } },
|
||||||
|
false,
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
ngraph::element::u8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
false,
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
true,
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -1.27f }, { 1.28f }, { -1.27f }, { 1.28f } },
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
ngraph::element::u8
|
||||||
|
},
|
||||||
|
{ false, {}, false, {}, {}, ngraph::element::f32 },
|
||||||
|
{ true, {}, true, {}, {}, ngraph::element::f32 },
|
||||||
};
|
};
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(smoke_LPT, MultiplyTransformation,
|
INSTANTIATE_TEST_SUITE_P(smoke_LPT, MultiplyTransformation,
|
||||||
|
@ -0,0 +1,88 @@
|
|||||||
|
// Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include "low_precision_transformations/elementwise_branch_selection_transformation.hpp"
|
||||||
|
#include "common_test_utils/test_constants.hpp"
|
||||||
|
|
||||||
|
using namespace LayerTestsDefinitions;
|
||||||
|
using namespace InferenceEngine::details;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
const std::vector<ngraph::element::Type> netPrecisions = {
|
||||||
|
ngraph::element::f32,
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::vector<std::string> elementwiseTypes = {
|
||||||
|
"add",
|
||||||
|
"multiply"
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::vector<LayerTestsDefinitions::ElementwiseBranchSelectionTestValues> params = {
|
||||||
|
{
|
||||||
|
{
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
{
|
||||||
|
{},
|
||||||
|
{ std::vector<float>(9, 1.f), ngraph::element::i8, {3, 3, 1, 1} },
|
||||||
|
{ {ngraph::element::f32}, {}, {std::vector<float>(3, 1.f), ngraph::element::f32, {3, 1, 1, 1}} }
|
||||||
|
},
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
{
|
||||||
|
{},
|
||||||
|
{ std::vector<float>(9, 1.f), ngraph::element::i8, {3, 3, 1, 1} },
|
||||||
|
{ {ngraph::element::f32}, {}, {std::vector<float>(3, 1.f), ngraph::element::f32, {3, 1, 1, 1}} }
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
},
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
{}, // GPU doesn't returns Reorders in performance counters
|
||||||
|
{
|
||||||
|
{"convolution1", "U8"},
|
||||||
|
{"convolution2", "U8"},
|
||||||
|
{"eltwise", "U8"}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
{
|
||||||
|
{},
|
||||||
|
{ std::vector<float>(9, 1.f), ngraph::element::i8, {3, 3, 1, 1} },
|
||||||
|
{ {ngraph::element::f32}, {}, {std::vector<float>(3, 1.f), ngraph::element::f32, {3, 1, 1, 1}} }
|
||||||
|
},
|
||||||
|
{}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
{
|
||||||
|
{},
|
||||||
|
{ std::vector<float>(9, 1.f), ngraph::element::i8, {3, 3, 1, 1} },
|
||||||
|
{ {ngraph::element::f32}, {}, {std::vector<float>(3, 1.f), ngraph::element::f32, {3, 1, 1, 1}} }
|
||||||
|
},
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
},
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
{}, // GPU doesn't returns Reorders in performance counters
|
||||||
|
{
|
||||||
|
{"convolution1", "U8"},
|
||||||
|
{"convolution2", "U8"},
|
||||||
|
{"eltwise", "U8"}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_SUITE_P(smoke_LPT, ElementwiseBranchSelectionTransformation,
|
||||||
|
::testing::Combine(
|
||||||
|
::testing::ValuesIn(netPrecisions),
|
||||||
|
::testing::Values(ngraph::PartialShape({ 1, 3, 16, 16 })),
|
||||||
|
::testing::Values(CommonTestUtils::DEVICE_GPU),
|
||||||
|
::testing::ValuesIn(params),
|
||||||
|
::testing::ValuesIn(elementwiseTypes)),
|
||||||
|
ElementwiseBranchSelectionTransformation::getTestCaseName);
|
||||||
|
} // namespace
|
@ -12,59 +12,68 @@ using namespace LayerTestsDefinitions;
|
|||||||
namespace {
|
namespace {
|
||||||
const std::vector<ngraph::element::Type> netPrecisions = {
|
const std::vector<ngraph::element::Type> netPrecisions = {
|
||||||
ngraph::element::f32,
|
ngraph::element::f32,
|
||||||
ngraph::element::f16
|
//ngraph::element::f16
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::vector<LayerTestsDefinitions::MultiplyTestValues> params = {
|
const std::vector<LayerTestsDefinitions::MultiplyTestValues> params = {
|
||||||
{
|
{
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { 0.f }, { 255.f } },
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { -128.f }, { 127.f } },
|
|
||||||
false,
|
false,
|
||||||
{ngraph::element::i8}, {ngraph::element::f32, ngraph::element::i8}
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
},
|
|
||||||
{
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -128.f }, { 127.f }, { -128.f }, { 127.f } },
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { 0.f }, { 255.f } },
|
|
||||||
false,
|
false,
|
||||||
{ngraph::element::i8}, {ngraph::element::f32, ngraph::element::f32}
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -1.28f }, { 1.27f }, { -1.28f }, { 1.27f } },
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -1.28f }, { 1.27f }, { -1.28f }, { 1.27f } },
|
||||||
|
ngraph::element::undefined // ngraph::element::i8
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { 0.f }, { 255.f } },
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { -128.f }, { 127.f } },
|
|
||||||
true,
|
|
||||||
{ngraph::element::i8}, {ngraph::element::f32, ngraph::element::f32}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -128.f }, { 127.f }, { -128.f }, { 127.f } },
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { 0.f }, { 255.f } },
|
|
||||||
true,
|
|
||||||
{ngraph::element::i8}, {ngraph::element::i8, ngraph::element::f32}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { 0.f }, { 255.f } },
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { -127.f }, { 128.f } },
|
|
||||||
false,
|
false,
|
||||||
{ngraph::element::u8}, {ngraph::element::f32, ngraph::element::f32}
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
},
|
|
||||||
{
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -128.f }, { 127.f }, { -128.f }, { 127.f } },
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { 0.f }, { 255.f } },
|
|
||||||
false,
|
false,
|
||||||
{ngraph::element::u8}, {ngraph::element::f32, ngraph::element::u8}
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
ngraph::element::undefined // ngraph::element::u8
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { 0.f }, { 255.f } },
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { -127.f }, { 128.f } },
|
|
||||||
true,
|
true,
|
||||||
{ngraph::element::u8}, {ngraph::element::u8, ngraph::element::f32}
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -1.28f }, { 1.27f }, { -1.28f }, { 1.27f } },
|
||||||
|
false,
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
ngraph::element::undefined //ngraph::element::u8
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -128.f }, { 127.f }, { -128.f }, { 127.f } },
|
|
||||||
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 255.f }, { 0.f }, { 255.f } },
|
|
||||||
true,
|
true,
|
||||||
{ngraph::element::u8}, {ngraph::element::f32, ngraph::element::f32}
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
false,
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -1.28f }, { 1.27f }, { -1.28f }, { 1.27f } },
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -1.28f }, { 1.27f }, { -1.28f }, { 1.27f } },
|
||||||
|
ngraph::element::undefined // ngraph::element::i8
|
||||||
},
|
},
|
||||||
{ {}, {}, false }, { {}, {}, true },
|
{
|
||||||
|
false,
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -1.28f }, { 1.27f }, { -1.28f }, { 1.27f } },
|
||||||
|
true,
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -1.28f }, { 1.27f }, { -1.28f }, { 1.27f } },
|
||||||
|
ngraph::element::undefined // ngraph::element::i8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
false,
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -1.28f }, { 1.27f }, { -128.f }, { 1.27f } },
|
||||||
|
false,
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
ngraph::element::undefined // ngraph::element::u8
|
||||||
|
},
|
||||||
|
{
|
||||||
|
false,
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
true,
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { -1.27f }, { 1.28f }, { -1.27f }, { 1.28f } },
|
||||||
|
{ 256ul, ngraph::Shape { 1, 1, 1, 1 }, { 0.f }, { 2.55f }, { 0.f }, { 2.55f } },
|
||||||
|
ngraph::element::undefined // ngraph::element::u8
|
||||||
|
},
|
||||||
|
{ false, {}, false, {}, {}, ngraph::element::undefined /* ngraph::element::f32 */ },
|
||||||
|
{ true, {}, true, {}, {}, ngraph::element::undefined /* ngraph::element::f32 */ },
|
||||||
};
|
};
|
||||||
|
|
||||||
INSTANTIATE_TEST_SUITE_P(smoke_LPT, MultiplyTransformation,
|
INSTANTIATE_TEST_SUITE_P(smoke_LPT, MultiplyTransformation,
|
||||||
|
@ -0,0 +1,51 @@
|
|||||||
|
// Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include "shared_test_classes/base/low_precision_transformations/layer_transformation.hpp"
|
||||||
|
#include "lpt_ngraph_functions/common/convolution.hpp"
|
||||||
|
#include "lpt_ngraph_functions/common/fake_quantize_on_data.hpp"
|
||||||
|
|
||||||
|
namespace LayerTestsDefinitions {
|
||||||
|
|
||||||
|
class ElementwiseBranchSelectionTestValues{
|
||||||
|
public:
|
||||||
|
class Branch {
|
||||||
|
public:
|
||||||
|
ngraph::builder::subgraph::FakeQuantizeOnData fakeQuantizeBefore;
|
||||||
|
ngraph::builder::subgraph::Convolution convolution;
|
||||||
|
ngraph::builder::subgraph::FakeQuantizeOnData fakeQuantizeAfter;
|
||||||
|
};
|
||||||
|
|
||||||
|
Branch branch1;
|
||||||
|
Branch branch2;
|
||||||
|
ngraph::builder::subgraph::FakeQuantizeOnData fakeQuantizeAfter;
|
||||||
|
std::vector<std::pair<std::string, std::string>> expectedReorders;
|
||||||
|
// expected operation name + expected operation precision
|
||||||
|
std::vector<std::pair<std::string, std::string>> expectedPrecisions;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::tuple<
|
||||||
|
ngraph::element::Type,
|
||||||
|
ngraph::PartialShape,
|
||||||
|
std::string,
|
||||||
|
ElementwiseBranchSelectionTestValues,
|
||||||
|
std::string
|
||||||
|
> ElementwiseBranchSelectionTransformationParams;
|
||||||
|
|
||||||
|
class ElementwiseBranchSelectionTransformation :
|
||||||
|
public testing::WithParamInterface<ElementwiseBranchSelectionTransformationParams>,
|
||||||
|
public LayerTestsUtils::LayerTransformation {
|
||||||
|
public:
|
||||||
|
static std::string getTestCaseName(const testing::TestParamInfo<ElementwiseBranchSelectionTransformationParams>& obj);
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void SetUp() override;
|
||||||
|
void Run() override;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LayerTestsDefinitions
|
@ -14,11 +14,12 @@ namespace LayerTestsDefinitions {
|
|||||||
|
|
||||||
class MultiplyTestValues {
|
class MultiplyTestValues {
|
||||||
public:
|
public:
|
||||||
|
bool broadcast1;
|
||||||
ngraph::builder::subgraph::FakeQuantizeOnData fakeQuantize1;
|
ngraph::builder::subgraph::FakeQuantizeOnData fakeQuantize1;
|
||||||
|
bool broadcast2;
|
||||||
ngraph::builder::subgraph::FakeQuantizeOnData fakeQuantize2;
|
ngraph::builder::subgraph::FakeQuantizeOnData fakeQuantize2;
|
||||||
bool broadcast;
|
ngraph::builder::subgraph::FakeQuantizeOnData fakeQuantizeAfter;
|
||||||
std::vector<ngraph::element::Type> precisionOnActivations;
|
ngraph::element::Type expectedPrecisions;
|
||||||
std::vector<ngraph::element::Type> expectedPrecisions;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::tuple<
|
typedef std::tuple<
|
||||||
@ -36,6 +37,7 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
void SetUp() override;
|
void SetUp() override;
|
||||||
|
void Run() override;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace LayerTestsDefinitions
|
} // namespace LayerTestsDefinitions
|
||||||
|
@ -0,0 +1,120 @@
|
|||||||
|
// Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "low_precision_transformations/elementwise_branch_selection_transformation.hpp"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <tuple>
|
||||||
|
|
||||||
|
#include <transformations/init_node_info.hpp>
|
||||||
|
#include "lpt_ngraph_functions/add_function.hpp"
|
||||||
|
|
||||||
|
namespace LayerTestsDefinitions {
|
||||||
|
|
||||||
|
std::string ElementwiseBranchSelectionTransformation::getTestCaseName(const testing::TestParamInfo<ElementwiseBranchSelectionTransformationParams>& obj) {
|
||||||
|
ngraph::element::Type netPrecision;
|
||||||
|
ngraph::PartialShape inputShapes;
|
||||||
|
std::string targetDevice;
|
||||||
|
auto params = LayerTestsUtils::LayerTransformationParamsNGraphFactory::createParamsU8I8();
|
||||||
|
ElementwiseBranchSelectionTestValues param;
|
||||||
|
std::string elementwiseType;
|
||||||
|
std::tie(netPrecision, inputShapes, targetDevice, param, elementwiseType) = obj.param;
|
||||||
|
|
||||||
|
std::ostringstream result;
|
||||||
|
result << getTestCaseNameByParams(netPrecision, inputShapes, targetDevice, params) <<
|
||||||
|
"_elementwiseType_" << elementwiseType;
|
||||||
|
|
||||||
|
auto toString = [](const ngraph::builder::subgraph::FakeQuantizeOnData& fqOnData) -> std::string {
|
||||||
|
if (fqOnData.empty()) {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::stringstream ss;
|
||||||
|
ss << "_on_branch1_" <<
|
||||||
|
fqOnData.inputLowValues[0] << "_" <<
|
||||||
|
fqOnData.inputHighValues[0] << "_" <<
|
||||||
|
fqOnData.outputLowValues[0] << "_" <<
|
||||||
|
fqOnData.outputHighValues[0];
|
||||||
|
return ss.str();
|
||||||
|
};
|
||||||
|
|
||||||
|
result <<
|
||||||
|
"_on_branch1_" << toString(param.branch1.fakeQuantizeBefore) << toString(param.branch1.fakeQuantizeAfter) <<
|
||||||
|
"_on_branch1_" << toString(param.branch1.fakeQuantizeBefore) << toString(param.branch1.fakeQuantizeAfter) <<
|
||||||
|
"_" << toString(param.fakeQuantizeAfter);
|
||||||
|
|
||||||
|
return result.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElementwiseBranchSelectionTransformation::SetUp() {
|
||||||
|
ngraph::element::Type precision;
|
||||||
|
ngraph::PartialShape inputShape;
|
||||||
|
ElementwiseBranchSelectionTestValues param;
|
||||||
|
std::string elementwiseType;
|
||||||
|
std::tie(precision, inputShape, targetDevice, param, elementwiseType) = this->GetParam();
|
||||||
|
|
||||||
|
function = ngraph::builder::subgraph::AddFunction::getOriginalSubgraphWithConvolutions(
|
||||||
|
precision,
|
||||||
|
inputShape,
|
||||||
|
false,
|
||||||
|
elementwiseType,
|
||||||
|
param.branch1.fakeQuantizeBefore,
|
||||||
|
param.branch1.convolution,
|
||||||
|
param.branch1.fakeQuantizeAfter,
|
||||||
|
param.branch2.fakeQuantizeBefore,
|
||||||
|
param.branch2.convolution,
|
||||||
|
param.branch2.fakeQuantizeAfter,
|
||||||
|
param.fakeQuantizeAfter);
|
||||||
|
|
||||||
|
ngraph::pass::InitNodeInfo().run_on_function(function);
|
||||||
|
}
|
||||||
|
|
||||||
|
void ElementwiseBranchSelectionTransformation::Run() {
|
||||||
|
LayerTestsCommon::Run();
|
||||||
|
|
||||||
|
const auto params = std::get<3>(GetParam());
|
||||||
|
const auto elementwiseType = std::get<4>(GetParam());
|
||||||
|
|
||||||
|
std::vector<std::pair<std::string, std::string>> expectedReorders = params.expectedReorders;
|
||||||
|
if (!expectedReorders.empty()) {
|
||||||
|
auto rtInfo = LayerTestsCommon::getRuntimeInfo();
|
||||||
|
for (auto it : rtInfo) {
|
||||||
|
const auto& typeIt = it.second.find("layerType");
|
||||||
|
const auto type = typeIt->second.as<std::string>();
|
||||||
|
if (type == "Reorder") {
|
||||||
|
const auto name = it.first;
|
||||||
|
bool wasFound = false;
|
||||||
|
for (auto it = expectedReorders.begin(); it != expectedReorders.end(); ++it) {
|
||||||
|
auto pair = *it;
|
||||||
|
const std::string parent = name.substr(0, name.find("_"));
|
||||||
|
const std::string child = name.substr(name.rfind("_") + 1, name.size() - name.rfind("_") - 1);
|
||||||
|
if ((pair.first == parent) && (pair.second == child)) {
|
||||||
|
expectedReorders.erase(it);
|
||||||
|
wasFound = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT_TRUE(wasFound) << it.first << " was not found in expected list";
|
||||||
|
} else if (type == "Convolution") {
|
||||||
|
const auto& precisionIt = it.second.find("runtimePrecision");
|
||||||
|
const auto precision = precisionIt->second.as<std::string>();
|
||||||
|
ASSERT_EQ("U8", precision);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ASSERT_TRUE(expectedReorders.empty()) << "Some Reorder operations were not found in execution graph";
|
||||||
|
}
|
||||||
|
|
||||||
|
for (auto it : params.expectedPrecisions) {
|
||||||
|
const auto actualPrecision = getRuntimePrecisionByFusedName(it.first == "eltwise" ? elementwiseType : it.first);
|
||||||
|
ASSERT_EQ(it.second, actualPrecision) << "actual precision for operation '" << it.first << "' is not correct";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_P(ElementwiseBranchSelectionTransformation, CompareWithRefImpl) {
|
||||||
|
Run();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace LayerTestsDefinitions
|
@ -27,14 +27,10 @@ std::string MultiplyTransformation::getTestCaseName(const testing::TestParamInfo
|
|||||||
|
|
||||||
std::ostringstream result;
|
std::ostringstream result;
|
||||||
result << getTestCaseNameByParams(precision, inputShapes, targetDevice, params) <<
|
result << getTestCaseNameByParams(precision, inputShapes, targetDevice, params) <<
|
||||||
(param.broadcast ? "_broadcast" : "");
|
(param.broadcast1 ? "_broadcast1" : "") <<
|
||||||
for (const auto& elem : param.precisionOnActivations) {
|
(param.broadcast2 ? "_broadcast2" : "");
|
||||||
result << "_" << elem << "_";
|
|
||||||
}
|
result << "_" << param.expectedPrecisions << "_";
|
||||||
result << "expected_precisions_";
|
|
||||||
for (const auto& elem : param.expectedPrecisions) {
|
|
||||||
result << "_" << elem << "_";
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!param.fakeQuantize1.empty()) {
|
if (!param.fakeQuantize1.empty()) {
|
||||||
result << "_on_branch1_" <<
|
result << "_on_branch1_" <<
|
||||||
@ -62,13 +58,42 @@ void MultiplyTransformation::SetUp() {
|
|||||||
function = ngraph::builder::subgraph::MultiplyFunction::getOriginal(
|
function = ngraph::builder::subgraph::MultiplyFunction::getOriginal(
|
||||||
precision,
|
precision,
|
||||||
inputShape,
|
inputShape,
|
||||||
param.broadcast,
|
param.broadcast1,
|
||||||
param.fakeQuantize1,
|
param.fakeQuantize1,
|
||||||
param.fakeQuantize2);
|
param.broadcast2,
|
||||||
|
param.fakeQuantize2,
|
||||||
|
param.fakeQuantizeAfter);
|
||||||
|
|
||||||
ngraph::pass::InitNodeInfo().run_on_function(function);
|
ngraph::pass::InitNodeInfo().run_on_function(function);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void MultiplyTransformation::Run() {
|
||||||
|
LayerTestsCommon::Run();
|
||||||
|
|
||||||
|
const auto params = std::get<3>(GetParam());
|
||||||
|
|
||||||
|
auto to_string = [](const ngraph::element::Type& precision) -> std::string {
|
||||||
|
switch (precision) {
|
||||||
|
case ngraph::element::f32: {
|
||||||
|
return "FP32";
|
||||||
|
}
|
||||||
|
case ngraph::element::i8: {
|
||||||
|
return "I8";
|
||||||
|
}
|
||||||
|
case ngraph::element::u8: {
|
||||||
|
return "U8";
|
||||||
|
}
|
||||||
|
default: {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto expectedFqPrecision = to_string(params.expectedPrecisions);
|
||||||
|
const auto actualFqPrecision = getRuntimePrecision("multiply");
|
||||||
|
EXPECT_EQ(expectedFqPrecision, actualFqPrecision);
|
||||||
|
}
|
||||||
|
|
||||||
TEST_P(MultiplyTransformation, CompareWithRefImpl) {
|
TEST_P(MultiplyTransformation, CompareWithRefImpl) {
|
||||||
Run();
|
Run();
|
||||||
};
|
};
|
||||||
|
@ -85,9 +85,17 @@ public:
|
|||||||
|
|
||||||
std::map<std::string, std::string>& GetConfiguration();
|
std::map<std::string, std::string>& GetConfiguration();
|
||||||
|
|
||||||
|
// get runtime precision by operation friendly name
|
||||||
std::string getRuntimePrecision(const std::string& layerName);
|
std::string getRuntimePrecision(const std::string& layerName);
|
||||||
|
|
||||||
|
// get runtime precision by operation type
|
||||||
std::string getRuntimePrecisionByType(const std::string& layerType);
|
std::string getRuntimePrecisionByType(const std::string& layerType);
|
||||||
|
|
||||||
|
// get runtime precision by operation friendly name which can be fused
|
||||||
|
std::string getRuntimePrecisionByFusedName(const std::string& layerName);
|
||||||
|
|
||||||
|
std::map<std::string, ngraph::Node::RTMap> getRuntimeInfo();
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
void showRuntimePrecisions();
|
void showRuntimePrecisions();
|
||||||
#endif
|
#endif
|
||||||
|
@ -516,6 +516,54 @@ std::string LayerTestsCommon::getRuntimePrecisionByType(const std::string& layer
|
|||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string LayerTestsCommon::getRuntimePrecisionByFusedName(const std::string& layerName) {
|
||||||
|
const auto execGraph = executableNetwork.GetExecGraphInfo();
|
||||||
|
const auto execFunction = execGraph.getFunction();
|
||||||
|
|
||||||
|
const auto parse = [](const std::string& originalLayersNames) -> std::set<std::string> {
|
||||||
|
std::set<std::string> names;
|
||||||
|
|
||||||
|
std::string tmp = originalLayersNames;
|
||||||
|
size_t beginPosition = 0ul;
|
||||||
|
size_t endPosition;
|
||||||
|
while ((endPosition = tmp.find(",", beginPosition)) != std::string::npos) {
|
||||||
|
names.insert(tmp.substr(beginPosition, endPosition - beginPosition));
|
||||||
|
beginPosition = endPosition + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
names.insert(tmp.substr(beginPosition, endPosition - beginPosition));
|
||||||
|
return names;
|
||||||
|
};
|
||||||
|
|
||||||
|
for (const auto& op : execFunction->get_ops()) {
|
||||||
|
const auto& rtInfo = op->get_rt_info();
|
||||||
|
|
||||||
|
const auto& nameIt = rtInfo.find("originalLayersNames");
|
||||||
|
IE_ASSERT(nameIt != rtInfo.end()) << "originalLayersNames is not found for node: " << layerName;
|
||||||
|
const auto fusedName = parse(nameIt->second.as<std::string>());
|
||||||
|
if (fusedName.find(layerName) == fusedName.end()) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
const auto& it = rtInfo.find("runtimePrecision");
|
||||||
|
IE_ASSERT(it != rtInfo.end()) << "runtimePrecision is not found for node: " << layerName;
|
||||||
|
const auto rtPrecisionPtr = it->second.as<std::string>();
|
||||||
|
return rtPrecisionPtr;
|
||||||
|
}
|
||||||
|
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::map<std::string, ngraph::Node::RTMap> LayerTestsCommon::getRuntimeInfo() {
|
||||||
|
const auto execGraph = executableNetwork.GetExecGraphInfo();
|
||||||
|
const auto function = execGraph.getFunction();
|
||||||
|
std::map<std::string, ngraph::Node::RTMap> runtimeInfo;
|
||||||
|
for (const auto& op : function->get_ops()) {
|
||||||
|
runtimeInfo[op->get_friendly_name()] = op->get_rt_info();
|
||||||
|
}
|
||||||
|
return runtimeInfo;
|
||||||
|
}
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
void LayerTestsCommon::showRuntimePrecisions() {
|
void LayerTestsCommon::showRuntimePrecisions() {
|
||||||
const auto execGraph = executableNetwork.GetExecGraphInfo();
|
const auto execGraph = executableNetwork.GetExecGraphInfo();
|
||||||
@ -523,13 +571,17 @@ void LayerTestsCommon::showRuntimePrecisions() {
|
|||||||
|
|
||||||
for (const auto& op : execFunction->get_ops()) {
|
for (const auto& op : execFunction->get_ops()) {
|
||||||
const auto& rtInfo = op->get_rt_info();
|
const auto& rtInfo = op->get_rt_info();
|
||||||
|
|
||||||
|
const auto& nameIt = rtInfo.find("originalLayersNames");
|
||||||
|
const auto name = nameIt->second.as<std::string>();
|
||||||
|
|
||||||
const auto& typeIt = rtInfo.find("layerType");
|
const auto& typeIt = rtInfo.find("layerType");
|
||||||
|
|
||||||
const auto type = typeIt->second.as<std::string>();
|
const auto type = typeIt->second.as<std::string>();
|
||||||
const auto& it = rtInfo.find("runtimePrecision");
|
|
||||||
|
|
||||||
|
const auto& it = rtInfo.find("runtimePrecision");
|
||||||
const auto rtPrecisionPtr = it->second.as<std::string>();
|
const auto rtPrecisionPtr = it->second.as<std::string>();
|
||||||
std::cout << type << ": " << rtPrecisionPtr << std::endl;
|
|
||||||
|
std::cout << type << "(" << name << "): " << rtPrecisionPtr << std::endl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
@ -8,8 +8,11 @@
|
|||||||
#include <ngraph/ngraph.hpp>
|
#include <ngraph/ngraph.hpp>
|
||||||
#include <low_precision/layer_transformation.hpp>
|
#include <low_precision/layer_transformation.hpp>
|
||||||
|
|
||||||
#include "lpt_ngraph_functions/common/dequantization_operations.hpp"
|
#include "elementwise_function.hpp"
|
||||||
#include "lpt_ngraph_functions/common/builders.hpp"
|
#include "lpt_ngraph_functions/common/builders.hpp"
|
||||||
|
#include "lpt_ngraph_functions/common/convolution.hpp"
|
||||||
|
#include "lpt_ngraph_functions/common/dequantization_operations.hpp"
|
||||||
|
#include "lpt_ngraph_functions/common/fake_quantize_on_data.hpp"
|
||||||
|
|
||||||
namespace ngraph {
|
namespace ngraph {
|
||||||
namespace builder {
|
namespace builder {
|
||||||
@ -53,7 +56,7 @@ inline std::ostream& operator<<(std::ostream& out, const AddExpectedValues& valu
|
|||||||
"_mutliply" << values.mutliplyValuesAfter.size();
|
"_mutliply" << values.mutliplyValuesAfter.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
class AddFunction {
|
class AddFunction : public ElementwiseFunction {
|
||||||
public:
|
public:
|
||||||
static std::shared_ptr<ngraph::Function> getOriginal(
|
static std::shared_ptr<ngraph::Function> getOriginal(
|
||||||
const ngraph::element::Type precision,
|
const ngraph::element::Type precision,
|
||||||
|
@ -15,8 +15,9 @@
|
|||||||
#include "low_precision/network_helper.hpp"
|
#include "low_precision/network_helper.hpp"
|
||||||
|
|
||||||
#include "lpt_ngraph_functions/common/add.hpp"
|
#include "lpt_ngraph_functions/common/add.hpp"
|
||||||
#include "lpt_ngraph_functions/common/fake_quantize_on_data.hpp"
|
#include "lpt_ngraph_functions/common/convolution.hpp"
|
||||||
#include "lpt_ngraph_functions/common/dequantization_operations.hpp"
|
#include "lpt_ngraph_functions/common/dequantization_operations.hpp"
|
||||||
|
#include "lpt_ngraph_functions/common/fake_quantize_on_data.hpp"
|
||||||
#include "lpt_ngraph_functions/common/reshape.hpp"
|
#include "lpt_ngraph_functions/common/reshape.hpp"
|
||||||
#include "lpt_ngraph_functions/common/transpose.hpp"
|
#include "lpt_ngraph_functions/common/transpose.hpp"
|
||||||
|
|
||||||
@ -78,6 +79,8 @@ std::shared_ptr<ngraph::opset1::FakeQuantize> makeFakeQuantize(
|
|||||||
const ngraph::element::Type precision,
|
const ngraph::element::Type precision,
|
||||||
const FakeQuantizeOnData& fqOnData);
|
const FakeQuantizeOnData& fqOnData);
|
||||||
|
|
||||||
|
std::shared_ptr<ngraph::opset1::Convolution> makeConvolution(const Output<Node>& output, const Convolution& convolution);
|
||||||
|
|
||||||
std::shared_ptr<ngraph::opset1::FakeQuantize> makeFakeQuantizeTypeRelaxed(
|
std::shared_ptr<ngraph::opset1::FakeQuantize> makeFakeQuantizeTypeRelaxed(
|
||||||
const Output<ngraph::Node>& output,
|
const Output<ngraph::Node>& output,
|
||||||
const ngraph::element::Type precision,
|
const ngraph::element::Type precision,
|
||||||
|
@ -0,0 +1,36 @@
|
|||||||
|
// Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
#include <ngraph/ngraph.hpp>
|
||||||
|
|
||||||
|
#include "constant.hpp"
|
||||||
|
#include "dequantization_operations.hpp"
|
||||||
|
|
||||||
|
namespace ngraph {
|
||||||
|
namespace builder {
|
||||||
|
namespace subgraph {
|
||||||
|
|
||||||
|
class Convolution {
|
||||||
|
public:
|
||||||
|
Convolution();
|
||||||
|
|
||||||
|
Convolution(
|
||||||
|
const DequantizationOperations::Subtract zeroPointOnActivations,
|
||||||
|
const Constant& constantOnWeights,
|
||||||
|
const DequantizationOperations& dequantizationOnWeights);
|
||||||
|
|
||||||
|
bool empty() const;
|
||||||
|
|
||||||
|
DequantizationOperations::Subtract zeroPointOnActivations;
|
||||||
|
Constant constantOnWeights;
|
||||||
|
DequantizationOperations dequantizationOnWeights;
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace subgraph
|
||||||
|
} // namespace builder
|
||||||
|
} // namespace ngraph
|
@ -0,0 +1,38 @@
|
|||||||
|
// Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <ngraph/ngraph.hpp>
|
||||||
|
#include <low_precision/layer_transformation.hpp>
|
||||||
|
|
||||||
|
#include "lpt_ngraph_functions/common/builders.hpp"
|
||||||
|
#include "lpt_ngraph_functions/common/convolution.hpp"
|
||||||
|
#include "lpt_ngraph_functions/common/dequantization_operations.hpp"
|
||||||
|
#include "lpt_ngraph_functions/common/fake_quantize_on_data.hpp"
|
||||||
|
|
||||||
|
namespace ngraph {
|
||||||
|
namespace builder {
|
||||||
|
namespace subgraph {
|
||||||
|
|
||||||
|
class ElementwiseFunction {
|
||||||
|
public:
|
||||||
|
static std::shared_ptr<ngraph::Function> getOriginalSubgraphWithConvolutions(
|
||||||
|
const ngraph::element::Type precision,
|
||||||
|
const ngraph::PartialShape& inputShape,
|
||||||
|
const bool broadcast,
|
||||||
|
const std::string& elementWiseType,
|
||||||
|
const ngraph::builder::subgraph::FakeQuantizeOnData& fqOnDataBefore1,
|
||||||
|
const ngraph::builder::subgraph::Convolution& convolution1,
|
||||||
|
const ngraph::builder::subgraph::FakeQuantizeOnData& fqOnDataAfter1,
|
||||||
|
const ngraph::builder::subgraph::FakeQuantizeOnData& fqOnDataBefore2,
|
||||||
|
const ngraph::builder::subgraph::Convolution& convolution2,
|
||||||
|
const ngraph::builder::subgraph::FakeQuantizeOnData& fqOnDataAfter2,
|
||||||
|
const ngraph::builder::subgraph::FakeQuantizeOnData& fqOnDataAfter);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace subgraph
|
||||||
|
} // namespace builder
|
||||||
|
} // namespace ngraph
|
@ -7,6 +7,7 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <ngraph/ngraph.hpp>
|
#include <ngraph/ngraph.hpp>
|
||||||
|
|
||||||
|
#include "elementwise_function.hpp"
|
||||||
#include "lpt_ngraph_functions/common/constant.hpp"
|
#include "lpt_ngraph_functions/common/constant.hpp"
|
||||||
#include "lpt_ngraph_functions/common/dequantization_operations.hpp"
|
#include "lpt_ngraph_functions/common/dequantization_operations.hpp"
|
||||||
|
|
||||||
@ -37,7 +38,7 @@ inline std::ostream& operator<<(std::ostream& out, const MultiplyValues& values)
|
|||||||
return out << "_" << values.branch1 << "_" << values.branch2 << (values.isDequantization ? "_isDequantization" : "");
|
return out << "_" << values.branch1 << "_" << values.branch2 << (values.isDequantization ? "_isDequantization" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
class MultiplyFunction {
|
class MultiplyFunction : public ElementwiseFunction {
|
||||||
public:
|
public:
|
||||||
static std::shared_ptr<ngraph::Function> get(
|
static std::shared_ptr<ngraph::Function> get(
|
||||||
const element::Type precision,
|
const element::Type precision,
|
||||||
@ -46,9 +47,11 @@ public:
|
|||||||
static std::shared_ptr<ngraph::Function> getOriginal(
|
static std::shared_ptr<ngraph::Function> getOriginal(
|
||||||
const ngraph::element::Type precision,
|
const ngraph::element::Type precision,
|
||||||
const ngraph::PartialShape& inputShape,
|
const ngraph::PartialShape& inputShape,
|
||||||
const bool broadcast,
|
const bool broadcast1,
|
||||||
const ngraph::builder::subgraph::FakeQuantizeOnData& fqOnData1,
|
const ngraph::builder::subgraph::FakeQuantizeOnData& fq1,
|
||||||
const ngraph::builder::subgraph::FakeQuantizeOnData& fqOnData2);
|
const bool broadcast2,
|
||||||
|
const ngraph::builder::subgraph::FakeQuantizeOnData& fq2,
|
||||||
|
const ngraph::builder::subgraph::FakeQuantizeOnData& fqAfter);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace subgraph
|
} // namespace subgraph
|
||||||
|
@ -2,6 +2,8 @@
|
|||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
|
||||||
|
#include "lpt_ngraph_functions/add_function.hpp"
|
||||||
|
|
||||||
#include "low_precision/network_helper.hpp"
|
#include "low_precision/network_helper.hpp"
|
||||||
#include "low_precision/layer_transformation.hpp"
|
#include "low_precision/layer_transformation.hpp"
|
||||||
|
|
||||||
@ -9,7 +11,6 @@
|
|||||||
|
|
||||||
#include "lpt_ngraph_functions/common/dequantization_operations.hpp"
|
#include "lpt_ngraph_functions/common/dequantization_operations.hpp"
|
||||||
#include "ngraph_functions/subgraph_builders.hpp"
|
#include "ngraph_functions/subgraph_builders.hpp"
|
||||||
#include "lpt_ngraph_functions/add_function.hpp"
|
|
||||||
|
|
||||||
using namespace ngraph::pass::low_precision;
|
using namespace ngraph::pass::low_precision;
|
||||||
|
|
||||||
|
@ -205,6 +205,36 @@ std::shared_ptr<ngraph::opset1::FakeQuantize> makeFakeQuantize(
|
|||||||
fqOnData.outputHighValues));
|
fqOnData.outputHighValues));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<ngraph::opset1::Convolution> makeConvolution(const Output<Node>& output, const Convolution& convolution) {
|
||||||
|
auto parentOnActivations = output;
|
||||||
|
if (!convolution.zeroPointOnActivations.empty()) {
|
||||||
|
auto constant = std::make_shared<ngraph::opset1::Constant>(
|
||||||
|
convolution.zeroPointOnActivations.outPrecision,
|
||||||
|
convolution.zeroPointOnActivations.constantShape,
|
||||||
|
convolution.zeroPointOnActivations.values);
|
||||||
|
parentOnActivations = std::make_shared<ngraph::opset1::Subtract>(parentOnActivations, constant);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert(!convolution.constantOnWeights.empty());
|
||||||
|
|
||||||
|
ngraph::Output<ngraph::Node> weights = std::make_shared<ngraph::opset1::Constant>(
|
||||||
|
convolution.constantOnWeights.outPrecision,
|
||||||
|
convolution.constantOnWeights.shape,
|
||||||
|
convolution.constantOnWeights.values);
|
||||||
|
|
||||||
|
if (!convolution.dequantizationOnWeights.empty()) {
|
||||||
|
weights = makeDequantization(weights, convolution.dequantizationOnWeights);
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_shared<ngraph::opset1::Convolution>(
|
||||||
|
parentOnActivations,
|
||||||
|
weights,
|
||||||
|
ngraph::Strides{ 1, 1 },
|
||||||
|
ngraph::CoordinateDiff{ 0, 0 },
|
||||||
|
ngraph::CoordinateDiff{ 0, 0 },
|
||||||
|
ngraph::Strides{ 1, 1 });
|
||||||
|
}
|
||||||
|
|
||||||
std::shared_ptr<ngraph::opset1::FakeQuantize> makeFakeQuantizeTypeRelaxed(
|
std::shared_ptr<ngraph::opset1::FakeQuantize> makeFakeQuantizeTypeRelaxed(
|
||||||
const Output<ngraph::Node>& output,
|
const Output<ngraph::Node>& output,
|
||||||
const ngraph::element::Type precision,
|
const ngraph::element::Type precision,
|
||||||
|
@ -0,0 +1,29 @@
|
|||||||
|
// Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "lpt_ngraph_functions/common/convolution.hpp"
|
||||||
|
|
||||||
|
namespace ngraph {
|
||||||
|
namespace builder {
|
||||||
|
namespace subgraph {
|
||||||
|
|
||||||
|
Convolution::Convolution() {
|
||||||
|
}
|
||||||
|
|
||||||
|
Convolution::Convolution(
|
||||||
|
const DequantizationOperations::Subtract zeroPointOnActivations,
|
||||||
|
const Constant& constantOnWeights,
|
||||||
|
const DequantizationOperations& dequantizationOnWeights) :
|
||||||
|
zeroPointOnActivations(zeroPointOnActivations),
|
||||||
|
constantOnWeights(constantOnWeights),
|
||||||
|
dequantizationOnWeights(dequantizationOnWeights) {
|
||||||
|
}
|
||||||
|
|
||||||
|
bool Convolution::empty() const {
|
||||||
|
return zeroPointOnActivations.empty() && constantOnWeights.empty() && dequantizationOnWeights.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace subgraph
|
||||||
|
} // namespace builder
|
||||||
|
} // namespace ngraph
|
@ -0,0 +1,119 @@
|
|||||||
|
// Copyright (C) 2018-2021 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "lpt_ngraph_functions/elementwise_function.hpp"
|
||||||
|
|
||||||
|
#include "low_precision/layer_transformation.hpp"
|
||||||
|
#include "ngraph/opsets/opset1.hpp"
|
||||||
|
#include "lpt_ngraph_functions/common/dequantization_operations.hpp"
|
||||||
|
|
||||||
|
using namespace ngraph::pass::low_precision;
|
||||||
|
|
||||||
|
namespace ngraph {
|
||||||
|
namespace builder {
|
||||||
|
namespace subgraph {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
std::shared_ptr<ngraph::opset1::FakeQuantize> makeFakeQuantizeWithNames(
|
||||||
|
const Output<Node>& parent,
|
||||||
|
const ngraph::element::Type precision,
|
||||||
|
const ngraph::builder::subgraph::FakeQuantizeOnData& fqOnData,
|
||||||
|
const std::string name) {
|
||||||
|
auto fq = ngraph::builder::subgraph::makeFakeQuantize(parent, precision, fqOnData);
|
||||||
|
fq->set_friendly_name(name);
|
||||||
|
fq->get_input_node_ptr(1)->set_friendly_name(name + "/inputLow");
|
||||||
|
fq->get_input_node_ptr(2)->set_friendly_name(name + "/inputHigh");
|
||||||
|
fq->get_input_node_ptr(3)->set_friendly_name(name + "/outputLow");
|
||||||
|
fq->get_input_node_ptr(4)->set_friendly_name(name + "/outputHigh");
|
||||||
|
return fq;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
std::shared_ptr<ngraph::Function> ElementwiseFunction::getOriginalSubgraphWithConvolutions(
|
||||||
|
const ngraph::element::Type precision,
|
||||||
|
const ngraph::PartialShape& inputShape,
|
||||||
|
const bool broadcast,
|
||||||
|
const std::string& elementWiseType,
|
||||||
|
const ngraph::builder::subgraph::FakeQuantizeOnData& fqOnDataBefore1,
|
||||||
|
const ngraph::builder::subgraph::Convolution& convolution1,
|
||||||
|
const ngraph::builder::subgraph::FakeQuantizeOnData& fqOnDataAfter1,
|
||||||
|
const ngraph::builder::subgraph::FakeQuantizeOnData& fqOnDataBefore2,
|
||||||
|
const ngraph::builder::subgraph::Convolution& convolution2,
|
||||||
|
const ngraph::builder::subgraph::FakeQuantizeOnData& fqOnDataAfter2,
|
||||||
|
const ngraph::builder::subgraph::FakeQuantizeOnData& fqOnDataAfter) {
|
||||||
|
ngraph::PartialShape inputShape2 = inputShape;
|
||||||
|
|
||||||
|
if (broadcast) {
|
||||||
|
inputShape2[2] = 1;
|
||||||
|
inputShape2[3] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto makeBranch = [&](
|
||||||
|
const ngraph::element::Type precision,
|
||||||
|
const ngraph::PartialShape& inputShape,
|
||||||
|
const size_t index,
|
||||||
|
const ngraph::builder::subgraph::FakeQuantizeOnData& fqOnDataBefore,
|
||||||
|
const ngraph::builder::subgraph::Convolution& convolution,
|
||||||
|
const ngraph::builder::subgraph::FakeQuantizeOnData& fqOnDataAfter) ->
|
||||||
|
std::pair<std::shared_ptr<ngraph::opset1::Parameter>, std::shared_ptr<ngraph::Node>> {
|
||||||
|
const auto input = std::make_shared<ngraph::opset1::Parameter>(precision, inputShape);
|
||||||
|
input->set_friendly_name("input" + std::to_string(index));
|
||||||
|
std::shared_ptr<ngraph::Node> parent = input;
|
||||||
|
|
||||||
|
if (!fqOnDataBefore.empty()) {
|
||||||
|
parent = makeFakeQuantizeWithNames(parent, precision, fqOnDataBefore, "fakeQuantizeBefore" + std::to_string(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!convolution.empty()) {
|
||||||
|
parent = makeConvolution(parent, convolution);
|
||||||
|
parent->set_friendly_name("convolution" + std::to_string(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fqOnDataAfter.empty()) {
|
||||||
|
parent = makeFakeQuantizeWithNames(parent, precision, fqOnDataAfter, "fakeQuantizeAfter" + std::to_string(index));
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::make_pair(input, parent);
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto branch1 = makeBranch(precision, inputShape, 1, fqOnDataBefore1, convolution1, fqOnDataAfter1);
|
||||||
|
const auto branch2 = makeBranch(precision, inputShape, 2, fqOnDataBefore2, convolution2, fqOnDataAfter2);
|
||||||
|
|
||||||
|
std::shared_ptr<ngraph::Node> result;
|
||||||
|
if (elementWiseType == "add") {
|
||||||
|
result = std::make_shared<ngraph::opset1::Add>(branch1.second, branch2.second);
|
||||||
|
result->set_friendly_name("add");
|
||||||
|
} else if (elementWiseType == "multiply") {
|
||||||
|
result = std::make_shared<ngraph::opset1::Multiply>(branch1.second, branch2.second);
|
||||||
|
result->set_friendly_name("multiply");
|
||||||
|
} else {
|
||||||
|
THROW_TRANSFORMATION_EXCEPTION << "not supported element-wise operation type " << elementWiseType;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fqOnDataAfter.empty()) {
|
||||||
|
result = makeFakeQuantizeWithNames(result, precision, fqOnDataAfter, "fakeQuantizeAfter");
|
||||||
|
|
||||||
|
// we need a some operation to move dequantization operations away from FakeQuantize to avoid cleanup fuse
|
||||||
|
result = std::make_shared<ngraph::opset1::MaxPool>(
|
||||||
|
result,
|
||||||
|
Strides{ 1, 1 },
|
||||||
|
Shape{ 1, 1 },
|
||||||
|
Shape{ 0, 0 },
|
||||||
|
Shape{ 2, 2 },
|
||||||
|
op::RoundingType::FLOOR);
|
||||||
|
result->set_friendly_name("maxPool");
|
||||||
|
}
|
||||||
|
|
||||||
|
result = std::make_shared<ngraph::opset1::Result>(result);
|
||||||
|
result->set_friendly_name("result");
|
||||||
|
|
||||||
|
ngraph::ResultVector results{ std::dynamic_pointer_cast<ngraph::opset1::Result>(result) };
|
||||||
|
return std::make_shared<ngraph::Function>(results, ngraph::ParameterVector{ branch1.first, branch2.first }, "AddTransformation");
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace subgraph
|
||||||
|
} // namespace builder
|
||||||
|
} // namespace ngraph
|
@ -169,25 +169,25 @@ std::shared_ptr<ngraph::Function> GroupConvolutionFunction::getOriginal(
|
|||||||
if (!fakeQuantizeOnData.empty()) {
|
if (!fakeQuantizeOnData.empty()) {
|
||||||
parent = std::make_shared<ngraph::opset1::FakeQuantize>(
|
parent = std::make_shared<ngraph::opset1::FakeQuantize>(
|
||||||
input,
|
input,
|
||||||
std::make_shared<Constant>(
|
std::make_shared<ngraph::opset1::Constant>(
|
||||||
precision,
|
precision,
|
||||||
rankLength == 3 ?
|
rankLength == 3 ?
|
||||||
Shape{ 1, fakeQuantizeOnData.inputLowValues.size(), 1 } :
|
Shape{ 1, fakeQuantizeOnData.inputLowValues.size(), 1 } :
|
||||||
Shape{ 1, fakeQuantizeOnData.inputLowValues.size(), 1, 1 },
|
Shape{ 1, fakeQuantizeOnData.inputLowValues.size(), 1, 1 },
|
||||||
fakeQuantizeOnData.inputLowValues),
|
fakeQuantizeOnData.inputLowValues),
|
||||||
std::make_shared<Constant>(
|
std::make_shared<ngraph::opset1::Constant>(
|
||||||
precision,
|
precision,
|
||||||
rankLength == 3 ?
|
rankLength == 3 ?
|
||||||
Shape{ 1, fakeQuantizeOnData.inputHighValues.size(), 1 } :
|
Shape{ 1, fakeQuantizeOnData.inputHighValues.size(), 1 } :
|
||||||
Shape{ 1, fakeQuantizeOnData.inputHighValues.size(), 1, 1 },
|
Shape{ 1, fakeQuantizeOnData.inputHighValues.size(), 1, 1 },
|
||||||
fakeQuantizeOnData.inputHighValues),
|
fakeQuantizeOnData.inputHighValues),
|
||||||
std::make_shared<Constant>(
|
std::make_shared<ngraph::opset1::Constant>(
|
||||||
precision,
|
precision,
|
||||||
rankLength == 3 ?
|
rankLength == 3 ?
|
||||||
Shape{ 1, fakeQuantizeOnData.outputLowValues.size(), 1 } :
|
Shape{ 1, fakeQuantizeOnData.outputLowValues.size(), 1 } :
|
||||||
Shape{ 1, fakeQuantizeOnData.outputLowValues.size(), 1, 1 },
|
Shape{ 1, fakeQuantizeOnData.outputLowValues.size(), 1, 1 },
|
||||||
fakeQuantizeOnData.outputLowValues),
|
fakeQuantizeOnData.outputLowValues),
|
||||||
std::make_shared<Constant>(
|
std::make_shared<ngraph::opset1::Constant>(
|
||||||
precision,
|
precision,
|
||||||
rankLength == 3 ?
|
rankLength == 3 ?
|
||||||
Shape{ 1, fakeQuantizeOnData.outputHighValues.size(), 1 } :
|
Shape{ 1, fakeQuantizeOnData.outputHighValues.size(), 1 } :
|
||||||
|
@ -90,22 +90,32 @@ std::shared_ptr<ngraph::Function> MultiplyFunction::get(
|
|||||||
std::shared_ptr<ngraph::Function> MultiplyFunction::getOriginal(
|
std::shared_ptr<ngraph::Function> MultiplyFunction::getOriginal(
|
||||||
const ngraph::element::Type precision,
|
const ngraph::element::Type precision,
|
||||||
const ngraph::PartialShape& inputShape,
|
const ngraph::PartialShape& inputShape,
|
||||||
const bool broadcast,
|
const bool broadcast1,
|
||||||
const ngraph::builder::subgraph::FakeQuantizeOnData& fq1,
|
const ngraph::builder::subgraph::FakeQuantizeOnData& fq1,
|
||||||
const ngraph::builder::subgraph::FakeQuantizeOnData& fq2) {
|
const bool broadcast2,
|
||||||
auto inputShape2 = inputShape;
|
const ngraph::builder::subgraph::FakeQuantizeOnData& fq2,
|
||||||
|
const ngraph::builder::subgraph::FakeQuantizeOnData& fqAfter) {
|
||||||
|
auto inputShape1 = inputShape;
|
||||||
|
if (broadcast1) {
|
||||||
|
inputShape1[2] = 1;
|
||||||
|
inputShape1[3] = 1;
|
||||||
|
}
|
||||||
|
|
||||||
if (broadcast) {
|
auto inputShape2 = inputShape;
|
||||||
|
if (broadcast2) {
|
||||||
inputShape2[2] = 1;
|
inputShape2[2] = 1;
|
||||||
inputShape2[3] = 1;
|
inputShape2[3] = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto input1 = std::make_shared<ngraph::opset1::Parameter>(precision, inputShape);
|
const auto input1 = std::make_shared<ngraph::opset1::Parameter>(precision, inputShape1);
|
||||||
const auto fakeQuantize1 = fq1.empty() ?
|
const auto fakeQuantize1 = fq1.empty() ?
|
||||||
nullptr :
|
nullptr :
|
||||||
ngraph::builder::makeFakeQuantize(
|
ngraph::builder::makeFakeQuantize(
|
||||||
input1, precision, fq1.quantizationLevel, fq1.constantShape,
|
input1, precision, fq1.quantizationLevel, fq1.constantShape,
|
||||||
fq1.inputLowValues, fq1.inputHighValues, fq1.outputLowValues, fq1.outputHighValues);
|
fq1.inputLowValues, fq1.inputHighValues, fq1.outputLowValues, fq1.outputHighValues);
|
||||||
|
if (fakeQuantize1 != nullptr) {
|
||||||
|
fakeQuantize1->set_friendly_name("fakeQuantize1");
|
||||||
|
}
|
||||||
|
|
||||||
const auto input2 = std::make_shared<ngraph::opset1::Parameter>(precision, inputShape2);
|
const auto input2 = std::make_shared<ngraph::opset1::Parameter>(precision, inputShape2);
|
||||||
const auto fakeQuantize2 = fq2.empty() ?
|
const auto fakeQuantize2 = fq2.empty() ?
|
||||||
@ -113,12 +123,24 @@ std::shared_ptr<ngraph::Function> MultiplyFunction::getOriginal(
|
|||||||
ngraph::builder::makeFakeQuantize(
|
ngraph::builder::makeFakeQuantize(
|
||||||
input2, precision, fq2.quantizationLevel, fq2.constantShape,
|
input2, precision, fq2.quantizationLevel, fq2.constantShape,
|
||||||
fq2.inputLowValues, fq2.inputHighValues, fq2.outputLowValues, fq2.outputHighValues);
|
fq2.inputLowValues, fq2.inputHighValues, fq2.outputLowValues, fq2.outputHighValues);
|
||||||
|
if (fakeQuantize2 != nullptr) {
|
||||||
|
fakeQuantize2->set_friendly_name("fakeQuantize2");
|
||||||
|
}
|
||||||
|
|
||||||
const auto multiply = std::make_shared<ngraph::opset1::Multiply>(
|
const auto multiply = std::make_shared<ngraph::opset1::Multiply>(
|
||||||
fq1.empty() ? input1 : fakeQuantize1,
|
fq1.empty() ? input1 : fakeQuantize1,
|
||||||
fq2.empty() ? input2 : fakeQuantize2);
|
fq2.empty() ? input2 : fakeQuantize2);
|
||||||
|
multiply->set_friendly_name("multiply");
|
||||||
|
|
||||||
ngraph::ResultVector results{ std::make_shared<ngraph::opset1::Result>(multiply) };
|
auto const fakeQuantizeAfter = fqAfter.empty() ?
|
||||||
|
nullptr :
|
||||||
|
makeFakeQuantize(multiply, precision, fqAfter);
|
||||||
|
if (fakeQuantizeAfter != nullptr) {
|
||||||
|
fakeQuantizeAfter->set_friendly_name("fakeQuantizeAfter");
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::shared_ptr<Node> result = fakeQuantizeAfter == nullptr ? std::dynamic_pointer_cast<Node>(multiply) : fakeQuantizeAfter;
|
||||||
|
ngraph::ResultVector results{ std::make_shared<ngraph::opset1::Result>(result) };
|
||||||
std::shared_ptr<ngraph::Function> function = std::make_shared<ngraph::Function>(
|
std::shared_ptr<ngraph::Function> function = std::make_shared<ngraph::Function>(
|
||||||
results,
|
results,
|
||||||
ngraph::ParameterVector{ input1, input2 },
|
ngraph::ParameterVector{ input1, input2 },
|
||||||
|
Loading…
Reference in New Issue
Block a user