[LPT] PadTransformation (#5316)
* [nGraph] op::Pad: added RTTI macros * [LPT][TESTS] operator<< for std::vector moved to layer_transformation.hpp * [LPT] PadTransformation * [LPT][TESTS] PadTransformation functional tests * [LPT][TESTS] PadTransformation plugin tests * [TESTS] Added the ability to add test-cases with dynamic shapes * merge fixes * [LPT] PadTransfomation: dynamic shapes support * [LPT] PadTransformation added to the main LPT pass * [LPT] MarkupTransformations: added Pad to SupportOps list * [LPT] PadTransformation: added nonzero padValue support * [LPT] PadTransformation: plugin tests extending * compilation error fix * naming fix
This commit is contained in:
parent
e13ac4d9ac
commit
a4d2e1a9c5
@ -0,0 +1,26 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <memory>
|
||||
#include <ngraph/ngraph.hpp>
|
||||
#include "layer_transformation.hpp"
|
||||
|
||||
namespace ngraph {
|
||||
namespace pass {
|
||||
namespace low_precision {
|
||||
|
||||
class LP_TRANSFORMATIONS_API PadTransformation : public LayerTransformation {
|
||||
public:
|
||||
NGRAPH_RTTI_DECLARATION;
|
||||
PadTransformation(const Params& params = Params());
|
||||
bool transform(TransformationContext& context, pattern::Matcher& m) override;
|
||||
bool canBeTransformed(const TransformationContext& context, std::shared_ptr<Node> op) const override;
|
||||
bool isPrecisionPreserved(std::shared_ptr<Node> layer) const noexcept override;
|
||||
};
|
||||
|
||||
} // namespace low_precision
|
||||
} // namespace pass
|
||||
} // namespace ngraph
|
@ -50,6 +50,7 @@
|
||||
#include "low_precision/multiply.hpp"
|
||||
#include "low_precision/mvn.hpp"
|
||||
#include "low_precision/normalize_l2.hpp"
|
||||
#include "low_precision/pad.hpp"
|
||||
#include "low_precision/prelu.hpp"
|
||||
#include "low_precision/reduce_max.hpp"
|
||||
#include "low_precision/reduce_mean.hpp"
|
||||
@ -219,6 +220,7 @@ bool ngraph::pass::low_precision::LowPrecision::run_on_function(std::shared_ptr<
|
||||
common->add_matcher<ngraph::pass::low_precision::MultiplyTransformation>(params);
|
||||
common->add_matcher<ngraph::pass::low_precision::MVNTransformation>(params);
|
||||
common->add_matcher<ngraph::pass::low_precision::NormalizeL2Transformation>(params);
|
||||
common->add_matcher<ngraph::pass::low_precision::PadTransformation>(params);
|
||||
common->add_matcher<ngraph::pass::low_precision::PReluTransformation>(params);
|
||||
common->add_matcher<ngraph::pass::low_precision::ReduceMaxTransformation>(params);
|
||||
common->add_matcher<ngraph::pass::low_precision::ReduceMeanTransformation>(params);
|
||||
|
@ -141,6 +141,7 @@ bool ngraph::pass::low_precision::MarkupPrecisions::isPrecisionPreserved(const s
|
||||
{ name<opset1::ReduceMin>() },
|
||||
{ name<opset1::Relu>() },
|
||||
// TODO: there are conditions
|
||||
{ name<opset1::Pad>() },
|
||||
{ name<opset1::Reshape>() },
|
||||
{ name<opset1::Squeeze>() },
|
||||
{ name<opset1::Split>() },
|
||||
@ -194,6 +195,7 @@ bool ngraph::pass::low_precision::MarkupPrecisions::isSupported(const std::share
|
||||
{ name<ngraph::op::MVN>() },
|
||||
{ name<opset6::MVN>() },
|
||||
{ name<opset1::NormalizeL2>() },
|
||||
{ name<opset1::Pad>() },
|
||||
{ name<opset1::PRelu>() },
|
||||
{ name<opset1::ReduceMax>() },
|
||||
{ name<opset1::ReduceMean>() },
|
||||
|
277
inference-engine/src/low_precision_transformations/src/pad.cpp
Normal file
277
inference-engine/src/low_precision_transformations/src/pad.cpp
Normal file
@ -0,0 +1,277 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "low_precision/pad.hpp"
|
||||
|
||||
#include <memory>
|
||||
#include <ngraph/ngraph.hpp>
|
||||
|
||||
#include <ngraph/pattern/op/wrap_type.hpp>
|
||||
#include "low_precision/network_helper.hpp"
|
||||
|
||||
namespace ngraph {
|
||||
namespace pass {
|
||||
namespace low_precision {
|
||||
|
||||
NGRAPH_RTTI_DEFINITION(ngraph::pass::low_precision::PadTransformation, "PadTransformation", 0);
|
||||
|
||||
PadTransformation::PadTransformation(const Params& params) : LayerTransformation(params) {
|
||||
auto mul = pattern::wrap_type<opset1::Multiply>();
|
||||
auto padsBegin = pattern::wrap_type<opset1::Constant>();
|
||||
auto padsEnd = pattern::wrap_type<opset1::Constant>();
|
||||
auto padsValue = pattern::wrap_type<opset1::Constant>();
|
||||
auto matcher = pattern::wrap_type<opset1::Pad>({ mul, padsBegin, padsEnd, padsValue });
|
||||
|
||||
ngraph::graph_rewrite_callback callback = [this](pattern::Matcher& m) {
|
||||
auto op = m.get_match_root();
|
||||
if (transformation_callback(op)) {
|
||||
return false;
|
||||
}
|
||||
return transform(*context, m);
|
||||
};
|
||||
|
||||
auto m = std::make_shared<ngraph::pattern::Matcher>(matcher, "PadTransformation");
|
||||
this->register_matcher(m, callback);
|
||||
}
|
||||
|
||||
bool PadTransformation::transform(TransformationContext& context, ngraph::pattern::Matcher& m) {
|
||||
if (!canBeTransformed(context, m.get_match_root())) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto pad = as_type_ptr<opset1::Pad>(NetworkHelper::separateInStandaloneBranch(m.get_match_root()));
|
||||
const auto padConstant = as_type_ptr<opset1::Constant>(pad->get_input_node_shared_ptr(3));
|
||||
const auto padConstantValue = padConstant->cast_vector<float>()[0];
|
||||
|
||||
const auto padsBegin = pad->get_pads_begin();
|
||||
const auto padsEnd = pad->get_pads_end();
|
||||
const auto padMode = pad->get_pad_mode();
|
||||
|
||||
auto dequantization = NetworkHelper::getDequantization(pad);
|
||||
|
||||
if (padMode == op::PadMode::CONSTANT) {
|
||||
auto bcastConstant = [&](const std::shared_ptr<opset1::Constant> &constant) {
|
||||
size_t padIdx = 0;
|
||||
for (size_t i = 0; i < padsBegin.size(); ++i) {
|
||||
if (padsBegin[i] != 0 || padsEnd[i] != 0) {
|
||||
padIdx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const auto inputPShape = pad->get_input_partial_shape(0);
|
||||
assert(inputPShape[padIdx].is_static());
|
||||
assert(inputPShape.rank().is_static());
|
||||
auto bcastedShape = Shape(inputPShape.rank().get_length(), 1ul);
|
||||
bcastedShape[padIdx] = inputPShape[padIdx].get_length();
|
||||
|
||||
const auto bCastConst = opset1::Constant::create(element::i32, Shape{bcastedShape.size()}, bcastedShape);
|
||||
return as_type_ptr<opset1::Constant>(fold<opset1::Broadcast>(constant, bCastConst));
|
||||
};
|
||||
|
||||
if (dequantization.subtract && shape_size(dequantization.subtractConstant->get_shape()) == 1ul) {
|
||||
const auto broadcastedConstant = bcastConstant(dequantization.subtractConstant);
|
||||
replace_node(dequantization.subtractConstant, broadcastedConstant);
|
||||
dequantization.subtractConstant = broadcastedConstant;
|
||||
}
|
||||
|
||||
if (padConstantValue != 0.f && shape_size(dequantization.multiplyConstant->get_shape()) == 1ul) {
|
||||
const auto broadcastedConstant = bcastConstant(dequantization.multiplyConstant);
|
||||
replace_node(dequantization.multiplyConstant, broadcastedConstant);
|
||||
dequantization.multiplyConstant = broadcastedConstant;
|
||||
}
|
||||
}
|
||||
|
||||
auto foldConstantIfNecessary = [&padMode, &padsBegin, &padsEnd](
|
||||
const std::shared_ptr<opset1::Constant>& constant,
|
||||
const std::shared_ptr<opset1::Pad>& pad,
|
||||
float padVal) {
|
||||
const auto constantShape = constant->get_shape();
|
||||
if (shape_size(constantShape) == 1ul) {
|
||||
return NetworkHelper::toScalar(constant);
|
||||
}
|
||||
|
||||
std::vector<size_t> padsForConstantBegin(constantShape.size(), 0ul);
|
||||
std::vector<size_t> padsForConstantEnd(constantShape.size(), 0ul);
|
||||
bool foldingIsNecessary = false;
|
||||
|
||||
// folding is necessary when dequantization and padding by the same dimension
|
||||
for (size_t i = 0; i < constantShape.size(); ++i) {
|
||||
if (padsBegin[i] != 0ul && constantShape[i] != 1ul) {
|
||||
foldingIsNecessary = true;
|
||||
padsForConstantBegin[i] = padsBegin[i];
|
||||
}
|
||||
|
||||
if (padsEnd[i] != 0ul && constantShape[i] != 1ul) {
|
||||
foldingIsNecessary = true;
|
||||
padsForConstantEnd[i] = padsEnd[i];
|
||||
}
|
||||
}
|
||||
|
||||
if (foldingIsNecessary) {
|
||||
const auto beginConst = opset1::Constant::create(element::u32, { padsForConstantBegin.size() }, padsForConstantBegin);
|
||||
const auto endConst = opset1::Constant::create(element::u32, { padsForConstantEnd.size() }, padsForConstantEnd);
|
||||
const auto padValueConstant = opset1::Constant::create(constant->get_element_type(), Shape{}, { padVal });
|
||||
const auto foldedConstant = fold<opset1::Pad>(constant, beginConst, endConst, padValueConstant, padMode);
|
||||
return as_type_ptr<opset1::Constant>(foldedConstant);
|
||||
} else {
|
||||
return constant;
|
||||
}
|
||||
};
|
||||
|
||||
if (dequantization.subtract) {
|
||||
const auto normalizedSubConst = NetworkHelper::normalizeDequantizationShape(dequantization.subtract);
|
||||
float padValueForSub = padConstantValue;
|
||||
if (padMode == op::PadMode::CONSTANT) {
|
||||
padValueForSub = 0.f;
|
||||
}
|
||||
|
||||
const auto newSubConstant = foldConstantIfNecessary(normalizedSubConst, pad, padValueForSub);
|
||||
replace_node(normalizedSubConst, newSubConstant);
|
||||
dequantization.subtractConstant = newSubConstant;
|
||||
}
|
||||
|
||||
{
|
||||
const auto normalizedMulConst = NetworkHelper::normalizeDequantizationShape(dequantization.multiply);
|
||||
float padValueForMul = padConstantValue;
|
||||
if (padMode == op::PadMode::CONSTANT) {
|
||||
padValueForMul = 1.f;
|
||||
}
|
||||
|
||||
const auto newMulConstant = foldConstantIfNecessary(normalizedMulConst, pad, padValueForMul);
|
||||
replace_node(normalizedMulConst, newMulConstant);
|
||||
dequantization.multiplyConstant = newMulConstant;
|
||||
}
|
||||
|
||||
// we must convert pad value in low precision
|
||||
const auto convertedZero = opset1::Constant::create(dequantization.data.get_element_type(), Shape{}, { padConstantValue });
|
||||
pad->set_argument(3, convertedZero);
|
||||
|
||||
moveDequantizationAfter(context, pad, dequantization, true);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PadTransformation::canBeTransformed(const TransformationContext& context, std::shared_ptr<Node> op) const {
|
||||
if (!LayerTransformation::canBeTransformedSpatialDimension(context, op)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto pad = as_type_ptr<opset1::Pad>(op);
|
||||
if (!pad) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto dequantization = NetworkHelper::getDequantization(op);
|
||||
if (dequantization.empty()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto mode = pad->get_pad_mode();
|
||||
if (mode == op::PadMode::CONSTANT) {
|
||||
auto padAndDqByTheSameDimension = [&](const std::shared_ptr<opset1::Constant>& deqConst) {
|
||||
const auto padsBegin = pad->get_pads_begin();
|
||||
const auto padsEnd = pad->get_pads_end();
|
||||
|
||||
int beginNonZeroIdx = -1;
|
||||
for (size_t i = 0; i < padsBegin.size(); ++i) {
|
||||
const bool padDimensionNotUnique = (beginNonZeroIdx != -1) && (padsBegin[i] != 0);
|
||||
if (padDimensionNotUnique) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (padsBegin[i] != 0) {
|
||||
beginNonZeroIdx = i;
|
||||
}
|
||||
}
|
||||
|
||||
int endNonZeroIdx = -1;
|
||||
for (size_t i = 0; i < padsEnd.size(); ++i) {
|
||||
const bool padDimensionNotUnique = (endNonZeroIdx != -1) && (padsEnd[i] != 0);
|
||||
if (padDimensionNotUnique) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (padsEnd[i] != 0) {
|
||||
endNonZeroIdx = i;
|
||||
}
|
||||
}
|
||||
|
||||
if ((beginNonZeroIdx != endNonZeroIdx) && (beginNonZeroIdx != -1) && (endNonZeroIdx != -1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t paddingDimension = beginNonZeroIdx != -1 ? beginNonZeroIdx : endNonZeroIdx;
|
||||
const auto padInputPShape = pad->get_input_partial_shape(0);
|
||||
const auto padInputRank = padInputPShape.rank();
|
||||
if (padInputRank.is_dynamic() || padInputPShape[paddingDimension].is_dynamic()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
const size_t inputRankValue = padInputRank.get_length();
|
||||
auto deqShape = deqConst->get_shape();
|
||||
if (shape_size(deqShape) > 1ul) {
|
||||
while (deqShape.size() < inputRankValue) {
|
||||
deqShape.insert(deqShape.begin(), 1ul);
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < deqShape.size(); ++i) {
|
||||
const bool deqAndPadDimensionsMismatched = (deqShape[i] > 1ul) && (i != paddingDimension);
|
||||
if (deqAndPadDimensionsMismatched) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
};
|
||||
|
||||
if (dequantization.subtract && !padAndDqByTheSameDimension(dequantization.subtractConstant)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto constant = as_type_ptr<opset1::Constant>(pad->get_input_node_shared_ptr(3));
|
||||
const auto constantValue = constant->cast_vector<float>()[0];
|
||||
if (constantValue != 0.f && !padAndDqByTheSameDimension(dequantization.multiplyConstant)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
if (mode == op::PadMode::REFLECT) {
|
||||
auto deqShape = dequantization.multiplyConstant->get_shape();
|
||||
if (shape_size(deqShape) == 1ul) {
|
||||
return true;
|
||||
} else {
|
||||
const auto padInputRank = pad->get_input_partial_shape(0).rank();
|
||||
if (padInputRank.is_dynamic()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
const size_t inputRankValue = padInputRank.get_length();
|
||||
while (deqShape.size() < inputRankValue) {
|
||||
deqShape.insert(deqShape.begin(), 1ul);
|
||||
}
|
||||
|
||||
const auto padsBegin = pad->get_pads_begin();
|
||||
const auto padsEnd = pad->get_pads_end();
|
||||
|
||||
// PadTransformation with "REFLECT" mode doesn't support dequantization and padding by the same dimension
|
||||
for (size_t i = 0; i < deqShape.size(); ++i) {
|
||||
if (deqShape[i] != 1ul && (padsBegin[i] != 0ul || padsEnd[i] != 0ul)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PadTransformation::isPrecisionPreserved(std::shared_ptr<Node> layer) const noexcept {
|
||||
return true;
|
||||
}
|
||||
|
||||
} // namespace low_precision
|
||||
} // namespace pass
|
||||
} // namespace ngraph
|
@ -77,19 +77,6 @@ typedef std::tuple <
|
||||
AddTransformationTestValues
|
||||
> AddTransformationParams;
|
||||
|
||||
template <typename T>
|
||||
inline std::ostream& operator<<(std::ostream& os, const std::vector<T>& values) {
|
||||
os << "{ ";
|
||||
for (size_t i = 0; i < values.size(); ++i) {
|
||||
os << values[i];
|
||||
if (i != (values.size() - 1ul)) {
|
||||
os << ", ";
|
||||
}
|
||||
}
|
||||
os << " }";
|
||||
return os;
|
||||
}
|
||||
|
||||
class AddTransformation : public LayerTransformation, public testing::WithParamInterface<AddTransformationParams> {
|
||||
public:
|
||||
void SetUp() override {
|
||||
|
@ -50,19 +50,6 @@ public:
|
||||
Expected expected;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline std::ostream& operator<<(std::ostream& os, const std::vector<T>& values) {
|
||||
os << "{ ";
|
||||
for (size_t i = 0; i < values.size(); ++i) {
|
||||
os << values[i];
|
||||
if (i != (values.size() - 1ul)) {
|
||||
os << ", ";
|
||||
}
|
||||
}
|
||||
os << " }";
|
||||
return os;
|
||||
}
|
||||
|
||||
class ElementwiseWithMultiParentDequantizationTransformation :
|
||||
public LayerTransformation,
|
||||
public testing::WithParamInterface<ElementwiseWithMultiParentDequantizationTransformationTestValues> {
|
||||
|
@ -48,19 +48,6 @@ typedef std::tuple<
|
||||
ngraph::PartialShape,
|
||||
FuseConvertTransformationTestValues> FuseConvertTransformationParams;
|
||||
|
||||
template <typename T>
|
||||
inline std::ostream& operator<<(std::ostream& os, const std::vector<T>& values) {
|
||||
os << "{ ";
|
||||
for (size_t i = 0; i < values.size(); ++i) {
|
||||
os << values[i];
|
||||
if (i != (values.size() - 1ul)) {
|
||||
os << ", ";
|
||||
}
|
||||
}
|
||||
os << " }";
|
||||
return os;
|
||||
}
|
||||
|
||||
class FuseConvertTransformation : public LayerTransformation, public testing::WithParamInterface<FuseConvertTransformationParams> {
|
||||
public:
|
||||
void SetUp() override {
|
||||
|
@ -89,19 +89,6 @@ public:
|
||||
Expected expected;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline std::ostream& operator<<(std::ostream& os, const std::vector<T>& values) {
|
||||
os << "{ ";
|
||||
for (size_t i = 0; i < values.size(); ++i) {
|
||||
os << values[i];
|
||||
if (i != (values.size() - 1ul)) {
|
||||
os << ", ";
|
||||
}
|
||||
}
|
||||
os << " }";
|
||||
return os;
|
||||
}
|
||||
|
||||
class InterpolateTransformation : public LayerTransformation, public testing::WithParamInterface<InterpolateTransformationTestValues> {
|
||||
public:
|
||||
void SetUp() override {
|
||||
|
@ -249,3 +249,16 @@ protected:
|
||||
std::shared_ptr<Function> actualFunction;
|
||||
std::shared_ptr<Function> referenceFunction;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline std::ostream& operator<<(std::ostream& os, const std::vector<T>& values) {
|
||||
os << "{ ";
|
||||
for (size_t i = 0; i < values.size(); ++i) {
|
||||
os << values[i];
|
||||
if (i != (values.size() - 1ul)) {
|
||||
os << ", ";
|
||||
}
|
||||
}
|
||||
os << " }";
|
||||
return os;
|
||||
}
|
||||
|
@ -48,19 +48,6 @@ public:
|
||||
Expected expected;
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
inline std::ostream& operator<<(std::ostream& os, const std::vector<T>& values) {
|
||||
os << "{ ";
|
||||
for (size_t i = 0; i < values.size(); ++i) {
|
||||
os << values[i];
|
||||
if (i != (values.size() - 1ul)) {
|
||||
os << ", ";
|
||||
}
|
||||
}
|
||||
os << " }";
|
||||
return os;
|
||||
}
|
||||
|
||||
class MultiplyToGroupConvolutionTransformation :
|
||||
public LayerTransformation,
|
||||
public testing::WithParamInterface<MultiplyToGroupConvolutionTransformationTestValues> {
|
||||
|
@ -55,19 +55,6 @@ typedef std::tuple<
|
||||
int
|
||||
> MVNTransformationParams;
|
||||
|
||||
template <typename T>
|
||||
inline std::ostream& operator<<(std::ostream& os, const std::vector<T>& values) {
|
||||
os << "{ ";
|
||||
for (size_t i = 0; i < values.size(); ++i) {
|
||||
os << values[i];
|
||||
if (i != (values.size() - 1ul)) {
|
||||
os << ", ";
|
||||
}
|
||||
}
|
||||
os << " }";
|
||||
return os;
|
||||
}
|
||||
|
||||
class MVNTransformation : public LayerTransformation, public testing::WithParamInterface<MVNTransformationParams> {
|
||||
public:
|
||||
void SetUp() override {
|
||||
|
@ -0,0 +1,793 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "layer_transformation.hpp"
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <gtest/gtest.h>
|
||||
#include <ngraph/ngraph.hpp>
|
||||
|
||||
#include <low_precision/pad.hpp>
|
||||
|
||||
#include "common_test_utils/ngraph_test_utils.hpp"
|
||||
#include "lpt_ngraph_functions/common/dequantization_operations.hpp"
|
||||
#include "lpt_ngraph_functions/pad_function.hpp"
|
||||
#include "simple_low_precision_transformer.hpp"
|
||||
|
||||
|
||||
namespace {
|
||||
using namespace testing;
|
||||
using namespace ngraph;
|
||||
using namespace ngraph::pass;
|
||||
|
||||
class PadTransformationTestValues {
|
||||
public:
|
||||
class Actual {
|
||||
public:
|
||||
ngraph::element::Type precisionBeforeDequantization;
|
||||
ngraph::builder::subgraph::DequantizationOperations dequantization;
|
||||
};
|
||||
|
||||
class Expected {
|
||||
public:
|
||||
ngraph::element::Type precisionBeforeDequantization;
|
||||
ngraph::builder::subgraph::DequantizationOperations dequantizationBefore;
|
||||
ngraph::element::Type precisionAfterOperation;
|
||||
ngraph::builder::subgraph::DequantizationOperations dequantizationAfter;
|
||||
};
|
||||
|
||||
TestTransformationParams params;
|
||||
Actual actual;
|
||||
Expected expected;
|
||||
};
|
||||
|
||||
typedef std::tuple <
|
||||
ngraph::PartialShape, // input Shape
|
||||
std::pair<std::vector<uint64_t>, std::vector<uint64_t>>, // pads begin, pads end
|
||||
ngraph::op::PadMode, // pads mode
|
||||
float, // pads value (used if mode == CONSTANT)
|
||||
PadTransformationTestValues> PadTransformationParams;
|
||||
|
||||
class PadTransformation : public LayerTransformation, public testing::WithParamInterface<PadTransformationParams> {
|
||||
public:
|
||||
void SetUp() override {
|
||||
const ngraph::PartialShape inputShape = std::get<0>(GetParam());
|
||||
const auto pads = std::get<1>(GetParam());
|
||||
const ngraph::op::PadMode padsMode = std::get<2>(GetParam());
|
||||
const float padsValue = std::get<3>(GetParam());
|
||||
const PadTransformationTestValues testValues = std::get<4>(GetParam());
|
||||
|
||||
const auto precisionAfterActualOp = testValues.actual.dequantization.convert.empty() ?
|
||||
testValues.actual.precisionBeforeDequantization : testValues.actual.dequantization.convert.outPrecision;
|
||||
|
||||
actualFunction = ngraph::builder::subgraph::PadFunction::get(
|
||||
inputShape,
|
||||
testValues.actual.precisionBeforeDequantization,
|
||||
testValues.actual.dequantization,
|
||||
pads.first,
|
||||
pads.second,
|
||||
padsMode,
|
||||
padsValue,
|
||||
precisionAfterActualOp,
|
||||
{ {}, {}, {} });
|
||||
|
||||
SimpleLowPrecisionTransformer transformer;
|
||||
transformer.add<ngraph::pass::low_precision::PadTransformation, ngraph::opset1::Pad>(testValues.params);
|
||||
transformer.transform(actualFunction);
|
||||
|
||||
referenceFunction = ngraph::builder::subgraph::PadFunction::get(
|
||||
inputShape,
|
||||
testValues.expected.precisionBeforeDequantization,
|
||||
testValues.expected.dequantizationBefore,
|
||||
pads.first,
|
||||
pads.second,
|
||||
padsMode,
|
||||
padsValue,
|
||||
testValues.expected.precisionAfterOperation,
|
||||
testValues.expected.dequantizationAfter);
|
||||
}
|
||||
|
||||
static std::string getTestCaseName(testing::TestParamInfo<PadTransformationParams> obj) {
|
||||
const ngraph::PartialShape inputShape = std::get<0>(obj.param);
|
||||
const auto pads = std::get<1>(obj.param);
|
||||
const ngraph::op::PadMode padsMode = std::get<2>(obj.param);
|
||||
const float padsValue = std::get<3>(obj.param);
|
||||
const PadTransformationTestValues testValues = std::get<4>(obj.param);
|
||||
|
||||
std::ostringstream result;
|
||||
result << "mode_" << padsMode << "_";
|
||||
if (padsMode == ngraph::op::PadMode::CONSTANT) {
|
||||
result << "pad_value_{ " << padsValue << " }";
|
||||
}
|
||||
|
||||
result << "_" <<
|
||||
toString(testValues.params) << "_" <<
|
||||
inputShape << "_" << pads.first << "_" << pads.second << "_" <<
|
||||
testValues.actual.precisionBeforeDequantization << "_" <<
|
||||
testValues.actual.dequantization << "_" <<
|
||||
testValues.expected.dequantizationBefore;
|
||||
|
||||
return result.str();
|
||||
}
|
||||
};
|
||||
|
||||
TEST_P(PadTransformation, CompareFunctions) {
|
||||
actualFunction->validate_nodes_and_infer_types();
|
||||
auto res = compare_functions(referenceFunction, actualFunction, true, true);
|
||||
ASSERT_TRUE(res.first) << res.second;
|
||||
}
|
||||
|
||||
const std::vector<ngraph::PartialShape> inputShapes = {
|
||||
{1, 3, 6, 6},
|
||||
{4, 3, 6, 6},
|
||||
{Dimension::dynamic(), 3, 6, Dimension::dynamic()}
|
||||
};
|
||||
|
||||
const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> padsBySpatialDimensions = {
|
||||
{0, 0, 2, 1},
|
||||
{0, 0, 1, 2}
|
||||
};
|
||||
|
||||
// test-cases with common logic for all modes
|
||||
// (per-tensor & per-channel quantizations without subtracts, pads by spatial dimensions)
|
||||
// and test-case without dequantization
|
||||
namespace commonTestCases {
|
||||
std::vector<ngraph::op::PadMode> allModes = {
|
||||
ngraph::op::PadMode::EDGE,
|
||||
ngraph::op::PadMode::REFLECT,
|
||||
ngraph::op::PadMode::SYMMETRIC,
|
||||
ngraph::op::PadMode::CONSTANT,
|
||||
};
|
||||
|
||||
const std::vector<PadTransformationTestValues> deqWithoutSub = {
|
||||
{
|
||||
LayerTransformation::createParamsU8I8(),
|
||||
{
|
||||
ngraph::element::u8,
|
||||
{{ngraph::element::f32}, {}, {3.f}}
|
||||
},
|
||||
{
|
||||
ngraph::element::u8,
|
||||
{{}, {}, {}},
|
||||
ngraph::element::u8,
|
||||
{{ngraph::element::f32}, {}, {3.f}}
|
||||
}
|
||||
},
|
||||
{
|
||||
LayerTransformation::createParamsI8I8(),
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {}, {3.f}}
|
||||
},
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{}, {}, {}},
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {}, {3.f}}
|
||||
}
|
||||
},
|
||||
{
|
||||
LayerTransformation::createParamsI8I8(),
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
|
||||
},
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{}, {}, {}},
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
|
||||
}
|
||||
},
|
||||
{
|
||||
LayerTransformation::createParamsU8I8(),
|
||||
{
|
||||
ngraph::element::u8,
|
||||
{{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
|
||||
},
|
||||
{
|
||||
ngraph::element::u8,
|
||||
{{}, {}, {}},
|
||||
ngraph::element::u8,
|
||||
{{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
|
||||
}
|
||||
},
|
||||
{
|
||||
LayerTransformation::createParamsU8I8(),
|
||||
{
|
||||
ngraph::element::u8,
|
||||
{{}, {}, {}}
|
||||
},
|
||||
{
|
||||
ngraph::element::u8,
|
||||
{{}, {}, {}},
|
||||
ngraph::element::u8,
|
||||
{{}, {}, {}}
|
||||
}
|
||||
},
|
||||
{
|
||||
LayerTransformation::createParamsU8I8(),
|
||||
{
|
||||
ngraph::element::f32,
|
||||
{{}, {}, {{3.f, 1.f, 2.f}}}
|
||||
},
|
||||
{
|
||||
ngraph::element::f32,
|
||||
{{}, {}, {}},
|
||||
ngraph::element::f32,
|
||||
{{}, {}, {{3.f, 1.f, 2.f}}}
|
||||
}
|
||||
},
|
||||
{
|
||||
LayerTransformation::createParamsU8I8().setUpdatePrecisions(false),
|
||||
{
|
||||
ngraph::element::f32,
|
||||
{{}, {}, {{3.f, 1.f, 2.f}}}
|
||||
},
|
||||
{
|
||||
ngraph::element::f32,
|
||||
{{}, {}, {}},
|
||||
ngraph::element::f32,
|
||||
{{}, {}, {{3.f, 1.f, 2.f}}}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
smoke_LPT,
|
||||
PadTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(inputShapes),
|
||||
::testing::Values(padsBySpatialDimensions),
|
||||
::testing::ValuesIn(allModes),
|
||||
::testing::Values(0.f),
|
||||
::testing::ValuesIn(deqWithoutSub)),
|
||||
PadTransformation::getTestCaseName);
|
||||
} // namespace commonTestCases
|
||||
|
||||
// test-cases with common logic for "EDGE", "REFLECT", and "SYMMETRIC" modes:
|
||||
// pads by spatial dimensions, dequantization with subtract
|
||||
namespace dqWithSubtract {
|
||||
std::vector<ngraph::op::PadMode> modesInWhichSubPropagated = {
|
||||
ngraph::op::PadMode::EDGE,
|
||||
ngraph::op::PadMode::REFLECT,
|
||||
ngraph::op::PadMode::SYMMETRIC,
|
||||
};
|
||||
|
||||
const std::vector<PadTransformationTestValues> deqWithSub = {
|
||||
{
|
||||
LayerTransformation::createParamsU8I8(),
|
||||
{
|
||||
ngraph::element::u8,
|
||||
{{ngraph::element::f32}, {128.f}, {3.f}}
|
||||
},
|
||||
{
|
||||
ngraph::element::u8,
|
||||
{{}, {}, {}},
|
||||
ngraph::element::u8,
|
||||
{{ngraph::element::f32}, {128.f}, {3.f}}
|
||||
}
|
||||
},
|
||||
{
|
||||
LayerTransformation::createParamsI8I8(),
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {64.f}, {3.f}}
|
||||
},
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{}, {}, {}},
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {64.f}, {3.f}}
|
||||
}
|
||||
},
|
||||
{
|
||||
LayerTransformation::createParamsI8I8(),
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {{64.f, 32.f, 16.f}}, {{3.f, 1.f, 2.f}}}
|
||||
},
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{}, {}, {}},
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {{64.f, 32.f, 16.f}}, {{3.f, 1.f, 2.f}}}
|
||||
}
|
||||
},
|
||||
{
|
||||
LayerTransformation::createParamsU8I8(),
|
||||
{
|
||||
ngraph::element::u8,
|
||||
{{ngraph::element::f32}, {{128.f, 64.f, 32.f}}, {{3.f, 1.f, 2.f}}}
|
||||
},
|
||||
{
|
||||
ngraph::element::u8,
|
||||
{{}, {}, {}},
|
||||
ngraph::element::u8,
|
||||
{{ngraph::element::f32}, {{128.f, 64.f, 32.f}}, {{3.f, 1.f, 2.f}}}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
smoke_LPT,
|
||||
PadTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(inputShapes),
|
||||
::testing::Values(padsBySpatialDimensions),
|
||||
::testing::ValuesIn(modesInWhichSubPropagated),
|
||||
::testing::Values(0.f),
|
||||
::testing::ValuesIn(deqWithSub)),
|
||||
PadTransformation::getTestCaseName);
|
||||
} // namespace dqWithSubtract
|
||||
|
||||
// dequantization with subtract and "CONSTANT" mode, also dequantization and padding by the same dimension
|
||||
namespace testCasesForConstantMode {
|
||||
const std::vector<PadTransformationTestValues> testValuesForConstantMode = {
|
||||
{
|
||||
LayerTransformation::createParamsI8I8(),
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {64.f}, {3.f}}
|
||||
},
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {64.f}, {3.f}},
|
||||
ngraph::element::f32,
|
||||
{{}, {}, {}}
|
||||
}
|
||||
},
|
||||
{
|
||||
LayerTransformation::createParamsI8I8(),
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {{64.f, 32.f, 16.f}}, {{3.f, 1.f, 2.f}}}
|
||||
},
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {{64.f, 32.f, 16.f}}, {{3.f, 1.f, 2.f}}},
|
||||
ngraph::element::f32,
|
||||
{{}, {}, {}}
|
||||
}
|
||||
},
|
||||
{
|
||||
LayerTransformation::createParamsU8I8(),
|
||||
{
|
||||
ngraph::element::u8,
|
||||
{{ngraph::element::f32}, {{128.f, 64.f, 32.f}}, {{3.f, 1.f, 2.f}}}
|
||||
},
|
||||
{
|
||||
ngraph::element::u8,
|
||||
{{ngraph::element::f32}, {{128.f, 64.f, 32.f}}, {{3.f, 1.f, 2.f}}},
|
||||
ngraph::element::f32,
|
||||
{{}, {}, {}}
|
||||
}
|
||||
},
|
||||
{
|
||||
LayerTransformation::createParamsU8I8(),
|
||||
{
|
||||
ngraph::element::u8,
|
||||
{{ngraph::element::f32}, {}, {{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}}
|
||||
},
|
||||
{
|
||||
ngraph::element::u8,
|
||||
{{}, {}, {}},
|
||||
ngraph::element::u8,
|
||||
{{ngraph::element::f32}, {}, {{1.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 1.f}, ngraph::element::f32, {1, 1, 9, 1}}}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
smoke_LPT,
|
||||
PadTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(inputShapes),
|
||||
::testing::Values(padsBySpatialDimensions),
|
||||
::testing::Values(ngraph::op::PadMode::CONSTANT),
|
||||
::testing::Values(0.f),
|
||||
::testing::ValuesIn(testValuesForConstantMode)),
|
||||
PadTransformation::getTestCaseName);
|
||||
} // namespace testCasesForConstantMode
|
||||
|
||||
// dequantization with "CONSTANT" mode (non zero value) and non unique pad dimension: dequantization isn't propagated
|
||||
namespace testCasesForConstantModeWithNonZeroValues {
|
||||
const std::vector<PadTransformationTestValues> testValuesForConstantMode2 = {
|
||||
{
|
||||
LayerTransformation::createParamsI8I8(),
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {}, {3.f}}
|
||||
},
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {}, {3.f}},
|
||||
ngraph::element::f32,
|
||||
{{}, {}, {}}
|
||||
}
|
||||
},
|
||||
{
|
||||
LayerTransformation::createParamsI8I8(),
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
|
||||
},
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}},
|
||||
ngraph::element::f32,
|
||||
{{}, {}, {}}
|
||||
}
|
||||
},
|
||||
{
|
||||
LayerTransformation::createParamsU8I8(),
|
||||
{
|
||||
ngraph::element::u8,
|
||||
{{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
|
||||
},
|
||||
{
|
||||
ngraph::element::u8,
|
||||
{{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}},
|
||||
ngraph::element::f32,
|
||||
{{}, {}, {}}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
smoke_LPT,
|
||||
PadTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(inputShapes),
|
||||
::testing::Values(padsBySpatialDimensions),
|
||||
::testing::Values(ngraph::op::PadMode::CONSTANT),
|
||||
::testing::Values(1.f),
|
||||
::testing::ValuesIn(testValuesForConstantMode2)),
|
||||
PadTransformation::getTestCaseName);
|
||||
} // namespace testCasesForConstantModeWithNonZeroValues
|
||||
|
||||
namespace testCasesForConstantModeAndUniquePadDimension {
|
||||
const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> padsByUniqueDimension = {
|
||||
{0, 0, 2, 0},
|
||||
{0, 0, 1, 0}
|
||||
};
|
||||
|
||||
const std::vector<PadTransformationTestValues> testValuesForConstantMode = {
|
||||
{
|
||||
LayerTransformation::createParamsI8I8(),
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{
|
||||
{ngraph::element::f32},
|
||||
{{64.f, 64.f, 64.f, 32.f, 32.f, 32.f}, ngraph::element::f32, {1, 1, 6, 1}},
|
||||
{{3.f, 3.f, 3.f, 2.f, 2.f, 2.f}, ngraph::element::f32, {1, 1, 6, 1}}
|
||||
}
|
||||
},
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{},
|
||||
ngraph::element::i8,
|
||||
{
|
||||
{ngraph::element::f32},
|
||||
{{0.f, 0.f, 64.f, 64.f, 64.f, 32.f, 32.f, 32.f, 0.f}, ngraph::element::f32, {1, 1, 9, 1}},
|
||||
{{1.f, 1.f, 3.f, 3.f, 3.f, 2.f, 2.f, 2.f, 1.f}, ngraph::element::f32, {1, 1, 9, 1}}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
LayerTransformation::createParamsI8I8(),
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{
|
||||
{ngraph::element::f32},
|
||||
{64.f},
|
||||
{3.f}
|
||||
}
|
||||
},
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{},
|
||||
ngraph::element::i8,
|
||||
{
|
||||
{ngraph::element::f32},
|
||||
{{0.f, 0.f, 64.f, 64.f, 64.f, 64.f, 64.f, 64.f, 0.f}, ngraph::element::f32, {1, 1, 9, 1}},
|
||||
{3.f}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
smoke_LPT,
|
||||
PadTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(inputShapes),
|
||||
::testing::Values(padsByUniqueDimension),
|
||||
::testing::Values(ngraph::op::PadMode::CONSTANT),
|
||||
::testing::Values(0.f),
|
||||
::testing::ValuesIn(testValuesForConstantMode)),
|
||||
PadTransformation::getTestCaseName);
|
||||
} // namespace testCasesForConstantModeAndUniquePadDimension
|
||||
|
||||
namespace testCasesForNonZeroConstantModeAndUniquePadDimension {
|
||||
const std::pair<std::vector<uint64_t>, std::vector<uint64_t>> padsByUniqueDimension = {
|
||||
{0, 0, 2, 0},
|
||||
{0, 0, 1, 0}
|
||||
};
|
||||
|
||||
const std::vector<PadTransformationTestValues> testValuesForConstantMode = {
|
||||
{
|
||||
LayerTransformation::createParamsI8I8(),
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{
|
||||
{ngraph::element::f32},
|
||||
{},
|
||||
{{3.f, 3.f, 3.f, 2.f, 2.f, 2.f}, ngraph::element::f32, {1, 1, 6, 1}}
|
||||
}
|
||||
},
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{},
|
||||
ngraph::element::i8,
|
||||
{
|
||||
{ngraph::element::f32},
|
||||
{},
|
||||
{{1.f, 1.f, 3.f, 3.f, 3.f, 2.f, 2.f, 2.f, 1.f}, ngraph::element::f32, {1, 1, 9, 1}}
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
LayerTransformation::createParamsI8I8(),
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{
|
||||
{ngraph::element::f32},
|
||||
{64.f},
|
||||
{3.f}
|
||||
}
|
||||
},
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{},
|
||||
ngraph::element::i8,
|
||||
{
|
||||
{ngraph::element::f32},
|
||||
{{0.f, 0.f, 64.f, 64.f, 64.f, 64.f, 64.f, 64.f, 0.f}, ngraph::element::f32, {1, 1, 9, 1}},
|
||||
{{1.f, 1.f, 3.f, 3.f, 3.f, 3.f, 3.f, 3.f, 1.f}, ngraph::element::f32, {1, 1, 9, 1}}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
smoke_LPT,
|
||||
PadTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(inputShapes),
|
||||
::testing::Values(padsByUniqueDimension),
|
||||
::testing::Values(ngraph::op::PadMode::CONSTANT),
|
||||
::testing::Values(2.f),
|
||||
::testing::ValuesIn(testValuesForConstantMode)),
|
||||
PadTransformation::getTestCaseName);
|
||||
} // namespace testCasesForNonZeroConstantModeAndUniquePadDimension
|
||||
|
||||
namespace testCasesForEdgeMode {
|
||||
const std::vector<PadTransformationTestValues> testValuesForEdgeMode = {
|
||||
{
|
||||
LayerTransformation::createParamsI8I8(),
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{
|
||||
{ngraph::element::f32},
|
||||
{{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}},
|
||||
{{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}
|
||||
}
|
||||
},
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{}, {}, {}},
|
||||
ngraph::element::i8,
|
||||
{
|
||||
{ngraph::element::f32},
|
||||
{{1.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f}, ngraph::element::f32, {1, 1, 9, 1}},
|
||||
{{1.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f}, ngraph::element::f32, {1, 1, 9, 1}}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
smoke_LPT,
|
||||
PadTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(inputShapes),
|
||||
::testing::Values(padsBySpatialDimensions),
|
||||
::testing::Values(ngraph::op::PadMode::EDGE),
|
||||
::testing::Values(0.f),
|
||||
::testing::ValuesIn(testValuesForEdgeMode)),
|
||||
PadTransformation::getTestCaseName);
|
||||
} // namespace testCasesForEdgeMode
|
||||
|
||||
namespace testCasesForReflectMode {
|
||||
const std::vector<PadTransformationTestValues> testValuesForReflectMode = {
|
||||
{
|
||||
LayerTransformation::createParamsI8I8(),
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{
|
||||
{ngraph::element::f32},
|
||||
{{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}},
|
||||
{{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}
|
||||
}
|
||||
},
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{
|
||||
{ngraph::element::f32},
|
||||
{{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}},
|
||||
{{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}
|
||||
},
|
||||
ngraph::element::f32,
|
||||
{{}, {}, {}}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
smoke_LPT,
|
||||
PadTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(inputShapes),
|
||||
::testing::Values(padsBySpatialDimensions),
|
||||
::testing::Values(ngraph::op::PadMode::REFLECT),
|
||||
::testing::Values(0.f),
|
||||
::testing::ValuesIn(testValuesForReflectMode)),
|
||||
PadTransformation::getTestCaseName);
|
||||
} // namespace testCasesForReflectMode
|
||||
|
||||
namespace testCasesForSymetricMode {
|
||||
const std::vector<PadTransformationTestValues> testValuesForSymetricMode = {
|
||||
{
|
||||
LayerTransformation::createParamsI8I8(),
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{
|
||||
{ngraph::element::f32},
|
||||
{{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}},
|
||||
{{1.f, 2.f, 3.f, 4.f, 5.f, 6.f}, ngraph::element::f32, {1, 1, 6, 1}}
|
||||
}
|
||||
},
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{}, {}, {}},
|
||||
ngraph::element::i8,
|
||||
{
|
||||
{ngraph::element::f32},
|
||||
{{2.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f}, ngraph::element::f32, {1, 1, 9, 1}},
|
||||
{{2.f, 1.f, 1.f, 2.f, 3.f, 4.f, 5.f, 6.f, 6.f}, ngraph::element::f32, {1, 1, 9, 1}}
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
smoke_LPT,
|
||||
PadTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(inputShapes),
|
||||
::testing::Values(padsBySpatialDimensions),
|
||||
::testing::Values(ngraph::op::PadMode::SYMMETRIC),
|
||||
::testing::Values(0.f),
|
||||
::testing::ValuesIn(testValuesForSymetricMode)),
|
||||
PadTransformation::getTestCaseName);
|
||||
} // namespace testCasesForSymetricMode
|
||||
|
||||
namespace testCasesWithDynamicChannels {
|
||||
const std::vector<ngraph::PartialShape> inputShapesWithDynamicChannels = {
|
||||
{Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic(), Dimension::dynamic()}
|
||||
};
|
||||
|
||||
std::vector<ngraph::op::PadMode> allModes = {
|
||||
ngraph::op::PadMode::EDGE,
|
||||
ngraph::op::PadMode::REFLECT,
|
||||
ngraph::op::PadMode::SYMMETRIC,
|
||||
ngraph::op::PadMode::CONSTANT,
|
||||
};
|
||||
|
||||
const std::vector<PadTransformationTestValues> testValuesForDynamicChannels = {
|
||||
{
|
||||
LayerTransformation::createParamsI8I8(),
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {}, {3.f}}
|
||||
},
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{}, {}, {}},
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {}, {3.f}}
|
||||
}
|
||||
},
|
||||
{
|
||||
LayerTransformation::createParamsI8I8(),
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
|
||||
},
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}},
|
||||
ngraph::element::f32,
|
||||
{{}, {}, {}},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
smoke_LPT,
|
||||
PadTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(inputShapesWithDynamicChannels),
|
||||
::testing::Values(padsBySpatialDimensions),
|
||||
::testing::ValuesIn(allModes),
|
||||
::testing::Values(0.f),
|
||||
::testing::ValuesIn(testValuesForDynamicChannels)),
|
||||
PadTransformation::getTestCaseName);
|
||||
} // namespace testCasesWithDynamicChannels
|
||||
|
||||
namespace testCasesWithDynamicRank {
|
||||
const std::vector<ngraph::PartialShape> inputShapesWithDynamicRank = {
|
||||
ngraph::PartialShape::dynamic()
|
||||
};
|
||||
|
||||
std::vector<ngraph::op::PadMode> allModes = {
|
||||
ngraph::op::PadMode::EDGE,
|
||||
ngraph::op::PadMode::REFLECT,
|
||||
ngraph::op::PadMode::SYMMETRIC,
|
||||
ngraph::op::PadMode::CONSTANT,
|
||||
};
|
||||
|
||||
const std::vector<PadTransformationTestValues> testValuesForDynamicRank = {
|
||||
{
|
||||
LayerTransformation::createParamsI8I8(),
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {}, {3.f}}
|
||||
},
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {}, {3.f}},
|
||||
ngraph::element::f32,
|
||||
{{}, {}, {}},
|
||||
}
|
||||
},
|
||||
{
|
||||
LayerTransformation::createParamsI8I8(),
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}}
|
||||
},
|
||||
{
|
||||
ngraph::element::i8,
|
||||
{{ngraph::element::f32}, {}, {{3.f, 1.f, 2.f}}},
|
||||
ngraph::element::f32,
|
||||
{{}, {}, {}},
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_SUITE_P(
|
||||
smoke_LPT,
|
||||
PadTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(inputShapesWithDynamicRank),
|
||||
::testing::Values(padsBySpatialDimensions),
|
||||
::testing::ValuesIn(allModes),
|
||||
::testing::Values(0.f),
|
||||
::testing::ValuesIn(testValuesForDynamicRank)),
|
||||
PadTransformation::getTestCaseName);
|
||||
} // namespace testCasesWithDynamicRank
|
||||
} // namespace
|
@ -0,0 +1,197 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "low_precision_transformations/pad_transformation.hpp"
|
||||
|
||||
|
||||
using namespace LayerTestsDefinitions;
|
||||
|
||||
namespace {
|
||||
const std::vector<ngraph::element::Type> netPrecisions = {
|
||||
ngraph::element::f32,
|
||||
// ngraph::element::f16
|
||||
};
|
||||
|
||||
const std::vector<ngraph::PartialShape> inputShapes = {
|
||||
{ 1, 3, 16, 16},
|
||||
{ 4, 3, 16, 16}
|
||||
};
|
||||
|
||||
const std::vector<ngraph::pass::low_precision::LayerTransformation::Params> trasformationParamValues = {
|
||||
LayerTestsUtils::LayerTransformationParamsNGraphFactory::createParamsU8I8()
|
||||
};
|
||||
|
||||
namespace commonTestCases {
|
||||
const std::vector<ngraph::op::PadMode> padModes = {
|
||||
ngraph::op::PadMode::CONSTANT,
|
||||
ngraph::op::PadMode::EDGE,
|
||||
ngraph::op::PadMode::REFLECT,
|
||||
ngraph::op::PadMode::SYMMETRIC
|
||||
};
|
||||
|
||||
const std::vector<LayerTestsDefinitions::PadTransformationParam> params = {
|
||||
// tensor quantization
|
||||
{
|
||||
{ 256ul, ngraph::Shape{ 1, 1, 1, 1 }, { 0.f }, { 25.5f }, { 0.f }, { 12.8f } },
|
||||
{ 0, 0, 1, 1 },
|
||||
{ 0, 0, 1, 1 },
|
||||
0.f,
|
||||
"Pad",
|
||||
"U8"
|
||||
},
|
||||
// per-channel quantization with the same values
|
||||
{
|
||||
{
|
||||
256ul, ngraph::Shape{ 1, 3, 1, 1 },
|
||||
{ -127.f, -127.f, -127.f },
|
||||
{ 128.f, 128.f, 128.f },
|
||||
{ 0.f, 0.f, 0.f },
|
||||
{ 255.f, 255.f, 255.f }
|
||||
},
|
||||
{ 0, 0, 1, 1 },
|
||||
{ 0, 0, 1, 1 },
|
||||
0.f,
|
||||
"Pad",
|
||||
"U8"
|
||||
},
|
||||
// per-channel quantization with different values
|
||||
{
|
||||
{
|
||||
256ul,
|
||||
ngraph::Shape{ 1, 3, 1, 1 },
|
||||
{ -127.f, 0.f, 128.f / 2.f },
|
||||
{ 128.f / 4.f, 128.f / 2.f, 128.f },
|
||||
{ 0.f, 0.f, 0.f },
|
||||
{ 255.f / 4.f, 255.f / 2.f, 255.f }
|
||||
},
|
||||
{ 0, 0, 1, 1 },
|
||||
{ 0, 0, 1, 1 },
|
||||
0.f,
|
||||
"Pad",
|
||||
"U8"
|
||||
},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(smoke_LPT, PadTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::ValuesIn(inputShapes),
|
||||
::testing::ValuesIn(padModes),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU),
|
||||
::testing::ValuesIn(trasformationParamValues),
|
||||
::testing::ValuesIn(params)),
|
||||
PadTransformation::getTestCaseName);
|
||||
} // namespace commonTestCases
|
||||
|
||||
namespace testCasesForConstantMode {
|
||||
const std::vector<LayerTestsDefinitions::PadTransformationParam> params = {
|
||||
// tensor quantization
|
||||
{
|
||||
{ 256ul, ngraph::Shape{ 1, 1, 1, 1 }, { -2.f }, { 10.5f }, { -2.f }, { 10.5f } },
|
||||
{ 0, 0, 1, 1 },
|
||||
{ 0, 0, 1, 1 },
|
||||
0.f,
|
||||
"Pad",
|
||||
"FP32"
|
||||
},
|
||||
// tensor quantization with subtract, non zero padValue and pad by unique dimension
|
||||
{
|
||||
{ 256ul, ngraph::Shape{ 1, 1, 1, 1 }, { 0.f }, { 25.5f }, { 0.f }, { 12.8f } },
|
||||
{ 0, 0, 2, 0 },
|
||||
{ 0, 0, 1, 0 },
|
||||
2.f,
|
||||
"Pad",
|
||||
"U8"
|
||||
},
|
||||
// per-channel quantization with different values, non zero padValue and pad by channel
|
||||
{
|
||||
{
|
||||
256ul,
|
||||
ngraph::Shape{ 1, 3, 1, 1 },
|
||||
{ -127.f, 0.f, 128.f / 2.f },
|
||||
{ 128.f / 4.f, 128.f / 2.f, 128.f },
|
||||
{ 0.f, 0.f, 0.f },
|
||||
{ 255.f / 4.f, 255.f / 2.f, 255.f }
|
||||
},
|
||||
{ 0, 1, 0, 0 },
|
||||
{ 0, 0, 0, 0 },
|
||||
2.f,
|
||||
"Pad",
|
||||
"U8"
|
||||
},
|
||||
// per-channel quantization with subtract
|
||||
{
|
||||
{
|
||||
256ul,
|
||||
ngraph::Shape{ 1, 3, 1, 1 },
|
||||
{ -2.f, -4.f, -6.f }, { 10.5f, 8.5f, 6.5f },
|
||||
{ -2.f, -4.f, -6.f }, { 10.5f, 8.5f, 6.5f }
|
||||
},
|
||||
{ 0, 0, 1, 1 },
|
||||
{ 0, 0, 1, 1 },
|
||||
0.f,
|
||||
"Pad",
|
||||
"FP32"
|
||||
},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(smoke_LPT, PadTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::ValuesIn(inputShapes),
|
||||
::testing::Values(ngraph::op::PadMode::CONSTANT),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU),
|
||||
::testing::ValuesIn(trasformationParamValues),
|
||||
::testing::ValuesIn(params)),
|
||||
PadTransformation::getTestCaseName);
|
||||
} // namespace testCasesForConstantMode
|
||||
|
||||
namespace testCasesForOtherModes {
|
||||
const std::vector<ngraph::op::PadMode> modesWithoutConstant = {
|
||||
ngraph::op::PadMode::EDGE,
|
||||
ngraph::op::PadMode::REFLECT,
|
||||
ngraph::op::PadMode::SYMMETRIC
|
||||
};
|
||||
|
||||
const std::vector<LayerTestsDefinitions::PadTransformationParam> params = {
|
||||
// tensor quantization
|
||||
{
|
||||
{ 256ul, ngraph::Shape{ 1, 1, 1, 1 }, { -2.f }, { 10.5f }, { -2.f }, { 10.5f } },
|
||||
{ 0, 0, 1, 1 },
|
||||
{ 0, 0, 1, 1 },
|
||||
0.f,
|
||||
"Pad",
|
||||
"U8"
|
||||
},
|
||||
// per-channel quantization with subtract
|
||||
{
|
||||
{
|
||||
256ul,
|
||||
ngraph::Shape{ 1, 3, 1, 1 },
|
||||
{ -2.f, -4.f, -6.f }, { 10.5f, 8.5f, 6.5f },
|
||||
{ -2.f, -4.f, -6.f }, { 10.5f, 8.5f, 6.5f }
|
||||
},
|
||||
{ 0, 0, 1, 1 },
|
||||
{ 0, 0, 1, 1 },
|
||||
0.f,
|
||||
"Pad",
|
||||
"U8"
|
||||
},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(smoke_LPT, PadTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::ValuesIn(inputShapes),
|
||||
::testing::ValuesIn(modesWithoutConstant),
|
||||
::testing::Values(CommonTestUtils::DEVICE_CPU),
|
||||
::testing::ValuesIn(trasformationParamValues),
|
||||
::testing::ValuesIn(params)),
|
||||
PadTransformation::getTestCaseName);
|
||||
} // namespace testCasesForOtherModes
|
||||
} // namespace
|
@ -0,0 +1,120 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include "low_precision_transformations/pad_transformation.hpp"
|
||||
|
||||
|
||||
using namespace LayerTestsDefinitions;
|
||||
|
||||
namespace {
|
||||
const std::vector<ngraph::element::Type> netPrecisions = {
|
||||
ngraph::element::f32,
|
||||
ngraph::element::f16
|
||||
};
|
||||
|
||||
const std::vector<ngraph::PartialShape> inputShapes = {
|
||||
{ 1, 3, 16, 16},
|
||||
};
|
||||
|
||||
const std::vector<ngraph::pass::low_precision::LayerTransformation::Params> trasformationParamValues = {
|
||||
LayerTestsUtils::LayerTransformationParamsNGraphFactory::createParamsU8I8()
|
||||
};
|
||||
|
||||
namespace commonTestCases {
|
||||
|
||||
const std::vector<ngraph::op::PadMode> padModes = {
|
||||
ngraph::op::PadMode::CONSTANT,
|
||||
ngraph::op::PadMode::EDGE,
|
||||
ngraph::op::PadMode::REFLECT,
|
||||
ngraph::op::PadMode::SYMMETRIC
|
||||
};
|
||||
|
||||
const std::vector<LayerTestsDefinitions::PadTransformationParam> params = {
|
||||
// tensor quantization
|
||||
{
|
||||
{ 256ul, ngraph::Shape{ 1, 1, 1, 1 }, { 0.f }, { 25.5f }, { 0.f }, { 12.8f } },
|
||||
{ 0, 0, 1, 1 },
|
||||
{ 0, 0, 1, 1 },
|
||||
},
|
||||
// per-channel quantization
|
||||
{
|
||||
{
|
||||
256ul,
|
||||
ngraph::Shape{ 1, 3, 1, 1 },
|
||||
{ -127.f, 0.f, 128.f / 2.f },
|
||||
{ 128.f / 4.f, 128.f / 2.f, 128.f },
|
||||
{ 0.f, 0.f, 0.f },
|
||||
{ 255.f / 4.f, 255.f / 2.f, 255.f }
|
||||
},
|
||||
{ 0, 0, 1, 1 },
|
||||
{ 0, 0, 1, 1 },
|
||||
}
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(smoke_LPT, PadTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::ValuesIn(inputShapes),
|
||||
::testing::ValuesIn(padModes),
|
||||
::testing::Values(CommonTestUtils::DEVICE_GPU),
|
||||
::testing::ValuesIn(trasformationParamValues),
|
||||
::testing::ValuesIn(params)),
|
||||
PadTransformation::getTestCaseName);
|
||||
} // namespace commonTestCases
|
||||
|
||||
namespace testCasesForConstantMode {
|
||||
|
||||
const std::vector<LayerTestsDefinitions::PadTransformationParam> params = {
|
||||
// tensor quantization
|
||||
{
|
||||
{ 256ul, ngraph::Shape{ 1, 1, 1, 1 }, { -2.f }, { 10.5f }, { -2.f }, { 10.5f } },
|
||||
{ 0, 0, 1, 1 },
|
||||
{ 0, 0, 1, 1 },
|
||||
},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(smoke_LPT, PadTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::ValuesIn(inputShapes),
|
||||
::testing::Values(ngraph::op::PadMode::CONSTANT),
|
||||
::testing::Values(CommonTestUtils::DEVICE_GPU),
|
||||
::testing::ValuesIn(trasformationParamValues),
|
||||
::testing::ValuesIn(params)),
|
||||
PadTransformation::getTestCaseName);
|
||||
} // namespace testCasesForConstantMode
|
||||
|
||||
namespace testCasesForOtherModes {
|
||||
|
||||
const std::vector<ngraph::op::PadMode> modesWithoutConstant = {
|
||||
ngraph::op::PadMode::EDGE,
|
||||
ngraph::op::PadMode::REFLECT,
|
||||
ngraph::op::PadMode::SYMMETRIC
|
||||
};
|
||||
|
||||
const std::vector<LayerTestsDefinitions::PadTransformationParam> params = {
|
||||
// tensor quantization
|
||||
{
|
||||
{ 256ul, ngraph::Shape{ 1, 1, 1, 1 }, { -2.f }, { 10.5f }, { -2.f }, { 10.5f } },
|
||||
{ 0, 0, 1, 1 },
|
||||
{ 0, 0, 1, 1 },
|
||||
},
|
||||
};
|
||||
|
||||
INSTANTIATE_TEST_CASE_P(smoke_LPT, PadTransformation,
|
||||
::testing::Combine(
|
||||
::testing::ValuesIn(netPrecisions),
|
||||
::testing::ValuesIn(inputShapes),
|
||||
::testing::ValuesIn(modesWithoutConstant),
|
||||
::testing::Values(CommonTestUtils::DEVICE_GPU),
|
||||
::testing::ValuesIn(trasformationParamValues),
|
||||
::testing::ValuesIn(params)),
|
||||
PadTransformation::getTestCaseName);
|
||||
} // namespace testCasesForOtherModes
|
||||
|
||||
} // namespace
|
@ -0,0 +1,40 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "shared_test_classes/base/low_precision_transformations/layer_transformation.hpp"
|
||||
#include "lpt_ngraph_functions/common/fake_quantize_on_data.hpp"
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
class PadTransformationParam {
|
||||
public:
|
||||
ngraph::builder::subgraph::FakeQuantizeOnData fakeQuantize;
|
||||
std::vector<uint64_t> padsBegin;
|
||||
std::vector<uint64_t> padsEnd;
|
||||
float padValue;
|
||||
std::string layerName;
|
||||
std::string expectedKernelType;
|
||||
};
|
||||
|
||||
typedef std::tuple<
|
||||
ngraph::element::Type,
|
||||
ngraph::PartialShape,
|
||||
ngraph::op::PadMode,
|
||||
std::string,
|
||||
ngraph::pass::low_precision::LayerTransformation::Params,
|
||||
PadTransformationParam
|
||||
> PadTransformationParams;
|
||||
|
||||
class PadTransformation :
|
||||
public testing::WithParamInterface<PadTransformationParams>,
|
||||
public LayerTestsUtils::LayerTransformation {
|
||||
public:
|
||||
static std::string getTestCaseName(testing::TestParamInfo<PadTransformationParams> obj);
|
||||
|
||||
protected:
|
||||
void SetUp() override;
|
||||
void Run() override;
|
||||
};
|
||||
} // namespace LayerTestsDefinitions
|
@ -0,0 +1,64 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include "low_precision_transformations/pad_transformation.hpp"
|
||||
#include <sstream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include <ngraph/ngraph.hpp>
|
||||
|
||||
#include "lpt_ngraph_functions/pad_function.hpp"
|
||||
|
||||
namespace LayerTestsDefinitions {
|
||||
|
||||
std::string PadTransformation::getTestCaseName(testing::TestParamInfo<PadTransformationParams> obj) {
|
||||
ngraph::element::Type netPrecision;
|
||||
ngraph::PartialShape inputShape;
|
||||
ngraph::op::PadMode padMode;
|
||||
std::string targetDevice;
|
||||
ngraph::pass::low_precision::LayerTransformation::Params params;
|
||||
PadTransformationParam param;
|
||||
std::tie(netPrecision, inputShape, padMode, targetDevice, params, param) = obj.param;
|
||||
|
||||
std::ostringstream result;
|
||||
result << getTestCaseNameByParams(netPrecision, inputShape, targetDevice, params)
|
||||
<< "_" << param.fakeQuantize << "_"
|
||||
<< CommonTestUtils::vec2str(param.padsBegin) << CommonTestUtils::vec2str(param.padsEnd) << "_"
|
||||
<< padMode << "_" << (padMode == ngraph::op::PadMode::CONSTANT ? "" : std::to_string(param.padValue));
|
||||
return result.str();
|
||||
}
|
||||
|
||||
void PadTransformation::SetUp() {
|
||||
ngraph::element::Type netPrecision;
|
||||
ngraph::PartialShape inputShape;
|
||||
ngraph::op::PadMode mode;
|
||||
ngraph::pass::low_precision::LayerTransformation::Params params;
|
||||
PadTransformationParam param;
|
||||
std::tie(netPrecision, inputShape, mode, targetDevice, params, param) = this->GetParam();
|
||||
|
||||
function = ngraph::builder::subgraph::PadFunction::get(
|
||||
inputShape,
|
||||
netPrecision,
|
||||
param.fakeQuantize,
|
||||
param.padsBegin,
|
||||
param.padsEnd,
|
||||
mode,
|
||||
param.padValue);
|
||||
}
|
||||
|
||||
void PadTransformation::Run() {
|
||||
LayerTestsCommon::Run();
|
||||
|
||||
const auto params = std::get<5>(GetParam());
|
||||
const auto actualPrecision = getRuntimePrecisionByType(params.layerName);
|
||||
const auto expectedPrecision = params.expectedKernelType;
|
||||
|
||||
EXPECT_EQ(actualPrecision, expectedPrecision);
|
||||
}
|
||||
|
||||
TEST_P(PadTransformation, CompareWithRefImpl) {
|
||||
Run();
|
||||
};
|
||||
|
||||
} // namespace LayerTestsDefinitions
|
@ -0,0 +1,41 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <sstream>
|
||||
#include <vector>
|
||||
#include <ngraph/ngraph.hpp>
|
||||
#include "lpt_ngraph_functions/common/fake_quantize_on_data.hpp"
|
||||
#include "lpt_ngraph_functions/common/dequantization_operations.hpp"
|
||||
|
||||
namespace ngraph {
|
||||
namespace builder {
|
||||
namespace subgraph {
|
||||
|
||||
class PadFunction {
|
||||
public:
|
||||
static std::shared_ptr<ngraph::Function> get(
|
||||
const PartialShape& inputShape,
|
||||
const element::Type precisionBeforeDequantization,
|
||||
const builder::subgraph::DequantizationOperations& dequantizationBefore,
|
||||
const std::vector<uint64_t>& padsBegin,
|
||||
const std::vector<uint64_t>& padsEnd,
|
||||
const op::PadMode mode,
|
||||
const float padValue,
|
||||
const element::Type precisionAfterOperation,
|
||||
const builder::subgraph::DequantizationOperations& dequantizationAfter);
|
||||
|
||||
static std::shared_ptr<Function> get(
|
||||
const PartialShape& inputShape,
|
||||
const element::Type inputPrecision,
|
||||
const builder::subgraph::FakeQuantizeOnData& fakeQuantizeOnData,
|
||||
const std::vector<uint64_t>& padsBegin,
|
||||
const std::vector<uint64_t>& padsEnd,
|
||||
const op::PadMode mode,
|
||||
const float padValue = 0.f);
|
||||
};
|
||||
} // namespace subgraph
|
||||
} // namespace builder
|
||||
} // namespace ngraph
|
@ -0,0 +1,81 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <memory>
|
||||
#include <vector>
|
||||
#include <ngraph/ngraph.hpp>
|
||||
|
||||
|
||||
#include <ngraph/opsets/opset1.hpp>
|
||||
#include "ngraph_functions/subgraph_builders.hpp"
|
||||
#include "lpt_ngraph_functions/common/builders.hpp"
|
||||
#include "lpt_ngraph_functions/pad_function.hpp"
|
||||
#include "low_precision/network_helper.hpp"
|
||||
|
||||
namespace ngraph {
|
||||
namespace builder {
|
||||
namespace subgraph {
|
||||
std::shared_ptr<ngraph::Function> PadFunction::get(
|
||||
const PartialShape& inputShape,
|
||||
const element::Type precisionBeforeDequantization,
|
||||
const builder::subgraph::DequantizationOperations& dequantizationBefore,
|
||||
const std::vector<uint64_t>& padsBegin,
|
||||
const std::vector<uint64_t>& padsEnd,
|
||||
const op::PadMode mode,
|
||||
const float padValue,
|
||||
const element::Type precisionAfterOperation,
|
||||
const builder::subgraph::DequantizationOperations& dequantizationAfter) {
|
||||
const auto input = std::make_shared<opset1::Parameter>(precisionBeforeDequantization, inputShape);
|
||||
const auto deqBefore = makeDequantization(input, dequantizationBefore);
|
||||
|
||||
const auto padsBeginConst = opset1::Constant::create(element::u64, Shape{ padsBegin.size() }, padsBegin);
|
||||
const auto padsEndConst = opset1::Constant::create(element::u64, Shape{ padsEnd.size() }, padsEnd);
|
||||
const auto padsValueConst = opset1::Constant::create(deqBefore->get_output_element_type(0), Shape{}, { padValue });
|
||||
|
||||
const auto pad = std::make_shared<ngraph::op::TypeRelaxed<opset1::Pad>>(
|
||||
std::vector<element::Type>{ precisionAfterOperation, element::u64, element::u64, precisionAfterOperation},
|
||||
std::vector<element::Type>{ precisionAfterOperation },
|
||||
op::TemporaryReplaceOutputType(deqBefore, precisionAfterOperation).get(),
|
||||
op::TemporaryReplaceOutputType(padsBeginConst, element::u64).get(),
|
||||
op::TemporaryReplaceOutputType(padsEndConst, element::u64).get(),
|
||||
op::TemporaryReplaceOutputType(padsValueConst, precisionAfterOperation).get(),
|
||||
mode);
|
||||
|
||||
const auto deqAfter = makeDequantization(pad, dequantizationAfter);
|
||||
deqAfter->set_friendly_name("Pad");
|
||||
|
||||
const auto function = std::make_shared<ngraph::Function>(
|
||||
ResultVector{ std::make_shared<ngraph::opset1::Result>(deqAfter) },
|
||||
ngraph::ParameterVector{ input }, "PadTransformation");
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
std::shared_ptr<Function> PadFunction::get(
|
||||
const PartialShape& inputShape,
|
||||
const element::Type inputPrecision,
|
||||
const builder::subgraph::FakeQuantizeOnData& fakeQuantize,
|
||||
const std::vector<uint64_t>& padsBegin,
|
||||
const std::vector<uint64_t>& padsEnd,
|
||||
const op::PadMode mode,
|
||||
const float padValue) {
|
||||
const auto input = std::make_shared<opset1::Parameter>(inputPrecision, inputShape);
|
||||
const auto fqOnData = makeFakeQuantize(input, inputPrecision, fakeQuantize);
|
||||
|
||||
const auto padsBeginConst = opset1::Constant::create(element::u64, Shape{ padsBegin.size() }, padsBegin);
|
||||
const auto padsEndConst = opset1::Constant::create(element::u64, Shape{ padsEnd.size() }, padsEnd);
|
||||
const auto padsValueConst = opset1::Constant::create(inputPrecision, Shape{}, { padValue });
|
||||
const auto pad = std::make_shared<opset1::Pad>(fqOnData, padsBeginConst, padsEndConst, padsValueConst, mode);
|
||||
pad->set_friendly_name("Pad");
|
||||
|
||||
const auto function = std::make_shared<Function>(
|
||||
ResultVector{ std::make_shared<opset1::Result>(pad) },
|
||||
ParameterVector{ input }, "PadTransformation");
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
} // namespace subgraph
|
||||
} // namespace builder
|
||||
} // namespace ngraph
|
Loading…
Reference in New Issue
Block a user