[CPU] Interpolate operation improvements (#2366)
* interpolate improvement * JITTED cubic mode * fix 'code is too big' when JIT * extend test to cover tail code path * transformation of interpolate1 to interpolate4 * add low precision transformation for interpolate4
This commit is contained in:
@@ -20,6 +20,16 @@ void InterpolateTransformation::registerMatcherIn(GraphRewrite& pass, Transforma
|
|||||||
pass,
|
pass,
|
||||||
context,
|
context,
|
||||||
make_op_pattern<opset1::Interpolate>({ make_op_label<opset1::Multiply>(), make_op_label<opset1::Constant>() }));
|
make_op_pattern<opset1::Interpolate>({ make_op_label<opset1::Multiply>(), make_op_label<opset1::Constant>() }));
|
||||||
|
addPattern(
|
||||||
|
pass,
|
||||||
|
context,
|
||||||
|
make_op_pattern<opset4::Interpolate>({ make_op_label<opset1::Multiply>(), make_op_label<opset1::Constant>(),
|
||||||
|
make_op_label<opset1::Constant>(), make_op_label<opset1::Constant>() }));
|
||||||
|
addPattern(
|
||||||
|
pass,
|
||||||
|
context,
|
||||||
|
make_op_pattern<opset4::Interpolate>({ make_op_label<opset1::Multiply>(), make_op_label<opset1::Constant>(),
|
||||||
|
make_op_label<opset1::Constant>() }));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InterpolateTransformation::transform(TransformationContext &context, ngraph::pattern::Matcher &m) const {
|
bool InterpolateTransformation::transform(TransformationContext &context, ngraph::pattern::Matcher &m) const {
|
||||||
@@ -33,9 +43,19 @@ bool InterpolateTransformation::transform(TransformationContext &context, ngraph
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool InterpolateTransformation::isPrecisionPreserved(std::shared_ptr<Node> layer) const noexcept {
|
bool InterpolateTransformation::isPrecisionPreserved(std::shared_ptr<Node> layer) const noexcept {
|
||||||
std::shared_ptr<opset1::Interpolate> interpolate = as_type_ptr<opset1::Interpolate>(layer);
|
std::shared_ptr<opset1::Interpolate> interpolate1 = as_type_ptr<opset1::Interpolate>(layer);
|
||||||
const auto attrs = interpolate->get_attrs();
|
if (interpolate1) {
|
||||||
return attrs.mode == "nearest";
|
const auto attrs = interpolate1->get_attrs();
|
||||||
|
return attrs.mode == "nearest";
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<opset4::Interpolate> interpolate4 = as_type_ptr<opset4::Interpolate>(layer);
|
||||||
|
if (interpolate4) {
|
||||||
|
const auto attrs = interpolate4->get_attrs();
|
||||||
|
return attrs.mode == op::v4::Interpolate::InterpolateMode::nearest;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool InterpolateTransformation::canBeTransformed(const TransformationContext& context, std::shared_ptr<Node> layer) const {
|
bool InterpolateTransformation::canBeTransformed(const TransformationContext& context, std::shared_ptr<Node> layer) const {
|
||||||
@@ -49,19 +69,46 @@ bool InterpolateTransformation::canBeTransformed(const TransformationContext& co
|
|||||||
if (dequantization.empty()) {
|
if (dequantization.empty()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
const auto interpolate = as_type_ptr<opset1::Interpolate>(layer);
|
|
||||||
const auto interpAttrs = interpolate->get_attrs();
|
|
||||||
|
|
||||||
if (interpAttrs.axes.count(0) || interpAttrs.axes.count(1)) {
|
const auto interpolate1 = as_type_ptr<opset1::Interpolate>(layer);
|
||||||
return false;
|
if (interpolate1) {
|
||||||
|
const auto interpAttrs = interpolate1->get_attrs();
|
||||||
|
if (interpAttrs.axes.count(0) || interpAttrs.axes.count(1)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (interpAttrs.mode != "nearest") {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
if (interpAttrs.pads_begin[0] != 0 || interpAttrs.pads_end[0] != 0 || interpAttrs.align_corners) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (interpAttrs.mode != "nearest") {
|
const auto interpolate4 = as_type_ptr<opset4::Interpolate>(layer);
|
||||||
return false;
|
if (interpolate4) {
|
||||||
}
|
const auto interpAttrs = interpolate4->get_attrs();
|
||||||
|
|
||||||
if (interpAttrs.pads_begin[0] != 0 || interpAttrs.pads_end[0] != 0 || interpAttrs.align_corners) {
|
if (interpAttrs.mode != op::v4::Interpolate::InterpolateMode::nearest) {
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pads_begin = interpAttrs.pads_begin;
|
||||||
|
for (int i = 0; i < pads_begin.size(); ++i) {
|
||||||
|
if (pads_begin[i] != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
auto pads_end = interpAttrs.pads_end;
|
||||||
|
for (int i = 0; i < pads_end.size(); ++i) {
|
||||||
|
if (pads_end[i] != 0) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (interpAttrs.coordinate_transformation_mode == op::v4::Interpolate::CoordinateTransformMode::align_corners) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|||||||
@@ -242,6 +242,7 @@ LowPrecisionTransformations LowPrecisionTransformer::getAllTransformations(const
|
|||||||
add<SqueezeTransformation, opset1::Squeeze>(params).
|
add<SqueezeTransformation, opset1::Squeeze>(params).
|
||||||
add<TransposeTransformation, opset1::Transpose>(params).
|
add<TransposeTransformation, opset1::Transpose>(params).
|
||||||
add<UnsqueezeTransformation, opset1::Unsqueeze>(params).
|
add<UnsqueezeTransformation, opset1::Unsqueeze>(params).
|
||||||
|
add<InterpolateTransformation, opset4::Interpolate>(params).
|
||||||
|
|
||||||
addCleanup<FuseConvertTransformation, opset1::Multiply>(params).
|
addCleanup<FuseConvertTransformation, opset1::Multiply>(params).
|
||||||
|
|
||||||
@@ -341,6 +342,7 @@ TypeRelaxedReplacer::TypeRelaxedReplacer() {
|
|||||||
make_matcher_type_relaxed<opset1::Multiply>(this);
|
make_matcher_type_relaxed<opset1::Multiply>(this);
|
||||||
make_matcher_type_relaxed<op::MVN>(this);
|
make_matcher_type_relaxed<op::MVN>(this);
|
||||||
make_matcher_type_relaxed<opset1::NormalizeL2>(this);
|
make_matcher_type_relaxed<opset1::NormalizeL2>(this);
|
||||||
|
make_matcher_type_relaxed<opset4::Interpolate>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
LowPrecisionTransformer::LowPrecisionTransformer(const LowPrecisionTransformations& transformations)
|
LowPrecisionTransformer::LowPrecisionTransformer(const LowPrecisionTransformations& transformations)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -10,6 +10,8 @@
|
|||||||
#include <memory>
|
#include <memory>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
|
#define MAX_INPUT_INTERPOLATE 4
|
||||||
|
|
||||||
using namespace InferenceEngine;
|
using namespace InferenceEngine;
|
||||||
|
|
||||||
namespace MKLDNNPlugin {
|
namespace MKLDNNPlugin {
|
||||||
@@ -54,14 +56,8 @@ struct jit_interpolate_config_params {
|
|||||||
};
|
};
|
||||||
|
|
||||||
struct jit_interpolate_call_args {
|
struct jit_interpolate_call_args {
|
||||||
const void *src;
|
const void *src_ptr[MAX_INPUT_INTERPOLATE];
|
||||||
const void *srcTR;
|
const void *weight_ptr[MAX_INPUT_INTERPOLATE];
|
||||||
const void *srcBL;
|
|
||||||
const void *srcBR;
|
|
||||||
const float *weight;
|
|
||||||
const float *weightR;
|
|
||||||
const float *weightT;
|
|
||||||
const float *weightB;
|
|
||||||
const int *index;
|
const int *index;
|
||||||
void *dst;
|
void *dst;
|
||||||
size_t work_amount;
|
size_t work_amount;
|
||||||
@@ -110,18 +106,20 @@ private:
|
|||||||
void linearOnnxCGathered(const uint8_t *in_ptr_, uint8_t *out_ptr_, int B, int C, int IH, int IW, int OH, int OW);
|
void linearOnnxCGathered(const uint8_t *in_ptr_, uint8_t *out_ptr_, int B, int C, int IH, int IW, int OH, int OW);
|
||||||
void linearOnnxRef(const uint8_t *in_ptr_, uint8_t *out_ptr_, int B, int C, int IH, int IW, int OH, int OW);
|
void linearOnnxRef(const uint8_t *in_ptr_, uint8_t *out_ptr_, int B, int C, int IH, int IW, int OH, int OW);
|
||||||
|
|
||||||
|
// cubic
|
||||||
|
std::vector<float> getCubicCoeffs(float mantissa, float a);
|
||||||
|
void cubicPlanar(const uint8_t *in_ptr_, uint8_t *out_ptr_, int B, int C, int IH, int IW, int OH, int OW);
|
||||||
|
void cubicCGathered(const uint8_t *in_ptr_, uint8_t *out_ptr_, int B, int C, int IH, int IW, int OH, int OW);
|
||||||
|
void cubicRef(const uint8_t *in_ptr_, uint8_t *out_ptr_, int B, int C, int IH, int IW, int OH, int OW);
|
||||||
|
|
||||||
// linear
|
// linear
|
||||||
void linearInterpolation(const uint8_t *in_ptr_, uint8_t *out_ptr_, int B, int C, int ID, int IH, int IW,
|
void linearInterpolation(const uint8_t *in_ptr_, uint8_t *out_ptr_, int B, int C, int ID, int IH, int IW,
|
||||||
float fx, float fy, float fz, int OD, int OH, int OW, int kernel_width, bool antialias);
|
float fx, float fy, float fz, int OD, int OH, int OW, int kernel_width, bool antialias);
|
||||||
|
|
||||||
// cubic
|
|
||||||
std::vector<float> getCubicCoeffs(float mantissa, float a);
|
|
||||||
void cubic(const uint8_t *in_ptr_, uint8_t *out_ptr_, int B, int C, int IH, int IW, int OH, int OW, float a);
|
|
||||||
|
|
||||||
void buildTblNN(SizeVector& srcDimPad5d, SizeVector& dstDim5d, std::vector<float>& dataScales, InterpolateLayoutType layout);
|
void buildTblNN(SizeVector& srcDimPad5d, SizeVector& dstDim5d, std::vector<float>& dataScales, InterpolateLayoutType layout);
|
||||||
void buildTblLinearOnnx(SizeVector& srcDimPad5d, SizeVector& dstDim5d, std::vector<float>& dataScales, InterpolateLayoutType layout);
|
void buildTblLinearOnnx(SizeVector& srcDimPad5d, SizeVector& dstDim5d, std::vector<float>& dataScales, InterpolateLayoutType layout);
|
||||||
void buidTblLinear(SizeVector& srcDimPad5d, SizeVector& dstDim5d, std::vector<float>& dataScales, int kernel_width, bool antialias);
|
void buildTblLinear(SizeVector& srcDimPad5d, SizeVector& dstDim5d, std::vector<float>& dataScales, int kernel_width, bool antialias);
|
||||||
void buidTblCubic(SizeVector& srcDimPad5d, SizeVector& dstDim5d, std::vector<float>& dataScales, float cubicCoeff);
|
void buildTblCubic(SizeVector& srcDimPad5d, SizeVector& dstDim5d, std::vector<float>& dataScales, float cubicCoeff, InterpolateLayoutType layout);
|
||||||
|
|
||||||
void setPostOps(mkldnn::primitive_attr &attr, bool initWeights = false);
|
void setPostOps(mkldnn::primitive_attr &attr, bool initWeights = false);
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,31 @@
|
|||||||
|
// Copyright (C) 2020 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <utility>
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
#include <transformations_visibility.hpp>
|
||||||
|
|
||||||
|
#include <ngraph/pass/graph_rewrite.hpp>
|
||||||
|
|
||||||
|
namespace ngraph {
|
||||||
|
namespace pass {
|
||||||
|
|
||||||
|
class TRANSFORMATIONS_API ConvertInterpolate1ToInterpolate4;
|
||||||
|
|
||||||
|
} // namespace pass
|
||||||
|
} // namespace ngraph
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ingroup ie_transformation_common_api
|
||||||
|
* @brief ConvertInterpolate1ToInterpolate4 covert v0:interpolate into v4::Interpolate.
|
||||||
|
*/
|
||||||
|
class ngraph::pass::ConvertInterpolate1ToInterpolate4: public ngraph::pass::MatcherPass {
|
||||||
|
public:
|
||||||
|
NGRAPH_RTTI_DECLARATION;
|
||||||
|
ConvertInterpolate1ToInterpolate4();
|
||||||
|
};
|
||||||
@@ -38,6 +38,7 @@
|
|||||||
#include "transformations/op_conversions/convert_space_to_depth.hpp"
|
#include "transformations/op_conversions/convert_space_to_depth.hpp"
|
||||||
#include "transformations/op_conversions/convert_broadcast_to_tiles.hpp"
|
#include "transformations/op_conversions/convert_broadcast_to_tiles.hpp"
|
||||||
#include "transformations/op_conversions/convert_gelu.hpp"
|
#include "transformations/op_conversions/convert_gelu.hpp"
|
||||||
|
#include "transformations/op_conversions/convert_interpolate1_to_interpolate4.hpp"
|
||||||
#include "transformations/op_conversions/batch_norm_decomposition.hpp"
|
#include "transformations/op_conversions/batch_norm_decomposition.hpp"
|
||||||
#include "transformations/op_conversions/reduce_l1_decomposition.hpp"
|
#include "transformations/op_conversions/reduce_l1_decomposition.hpp"
|
||||||
#include "transformations/op_conversions/reduce_l2_decomposition.hpp"
|
#include "transformations/op_conversions/reduce_l2_decomposition.hpp"
|
||||||
@@ -110,6 +111,7 @@ bool ngraph::pass::CommonOptimizations::run_on_function(std::shared_ptr<ngraph::
|
|||||||
manager.register_pass<ngraph::pass::ConvolutionBackpropDataMultiplyFusion>();
|
manager.register_pass<ngraph::pass::ConvolutionBackpropDataMultiplyFusion>();
|
||||||
manager.register_pass<ngraph::pass::GroupConvolutionBackpropDataMultiplyFusion>();
|
manager.register_pass<ngraph::pass::GroupConvolutionBackpropDataMultiplyFusion>();
|
||||||
manager.register_pass<ngraph::pass::ConstantFolding>();
|
manager.register_pass<ngraph::pass::ConstantFolding>();
|
||||||
|
manager.register_pass<ngraph::pass::ConvertInterpolate1ToInterpolate4, false>();
|
||||||
|
|
||||||
manager.register_pass<ngraph::pass::ConvertPreviousNMSToNMS5>();
|
manager.register_pass<ngraph::pass::ConvertPreviousNMSToNMS5>();
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,69 @@
|
|||||||
|
// Copyright (C) 2020 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include "transformations/op_conversions/convert_interpolate1_to_interpolate4.hpp"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
#include <ngraph/opsets/opset1.hpp>
|
||||||
|
#include <ngraph/opsets/opset4.hpp>
|
||||||
|
#include <ngraph/rt_info.hpp>
|
||||||
|
#include <ngraph/pattern/op/wrap_type.hpp>
|
||||||
|
|
||||||
|
NGRAPH_RTTI_DEFINITION(ngraph::pass::ConvertInterpolate1ToInterpolate4, "ConvertInterpolate1ToInterpolate4", 0);
|
||||||
|
|
||||||
|
ngraph::pass::ConvertInterpolate1ToInterpolate4::ConvertInterpolate1ToInterpolate4() {
|
||||||
|
auto interpolate1 = ngraph::pattern::wrap_type<ngraph::opset1::Interpolate>({pattern::any_input(pattern::has_static_rank()), pattern::any_input()});
|
||||||
|
ngraph::matcher_pass_callback callback = [this](pattern::Matcher& m) {
|
||||||
|
auto interpolate1 = std::dynamic_pointer_cast<ngraph::opset1::Interpolate>(m.get_match_root());
|
||||||
|
if (!interpolate1)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
auto interpolate_attrs = interpolate1->get_attrs();
|
||||||
|
auto input_shape_rank = interpolate1->input(0).get_partial_shape().rank().get_length();
|
||||||
|
|
||||||
|
// attrs
|
||||||
|
auto mode_v4 = ngraph::op::v4::Interpolate::InterpolateMode();
|
||||||
|
if (interpolate_attrs.mode == "nearest") {
|
||||||
|
mode_v4 = ngraph::op::v4::Interpolate::InterpolateMode::nearest;
|
||||||
|
} else if (interpolate_attrs.mode == "cubic") {
|
||||||
|
mode_v4 = ngraph::op::v4::Interpolate::InterpolateMode::cubic;
|
||||||
|
} else if (interpolate_attrs.mode == "linear") {
|
||||||
|
if (input_shape_rank < 5) {
|
||||||
|
mode_v4 = ngraph::op::v4::Interpolate::InterpolateMode::linear_onnx;
|
||||||
|
} else if (input_shape_rank == 5) {
|
||||||
|
mode_v4 = ngraph::op::v4::Interpolate::InterpolateMode::linear;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
auto nearest_mode_v4 = ngraph::op::v4::Interpolate::NearestMode::floor;
|
||||||
|
auto shape_calculation_mode_v4 = ngraph::op::v4::Interpolate::ShapeCalcMode::sizes;
|
||||||
|
auto coordinate_transformation_mode_v4 = interpolate_attrs.align_corners ? ngraph::op::v4::Interpolate::CoordinateTransformMode::align_corners :
|
||||||
|
ngraph::op::v4::Interpolate::CoordinateTransformMode::asymmetric;
|
||||||
|
auto interpolate4_attr = ngraph::op::v4::Interpolate::InterpolateAttrs(mode_v4, shape_calculation_mode_v4,
|
||||||
|
interpolate_attrs.pads_begin, interpolate_attrs.pads_end,
|
||||||
|
coordinate_transformation_mode_v4, nearest_mode_v4, interpolate_attrs.antialias, -0.75);
|
||||||
|
|
||||||
|
// input
|
||||||
|
auto axes = interpolate_attrs.axes.to_vector();
|
||||||
|
auto axes_node = ngraph::opset4::Constant::create(element::i64, {axes.size()}, axes);
|
||||||
|
auto default_scales = std::vector<float>(axes.size(), 1.f);
|
||||||
|
auto scales_node = ngraph::opset4::Constant::create(element::f32, {axes.size()}, default_scales);
|
||||||
|
|
||||||
|
auto interpolate4 = std::make_shared<ngraph::opset4::Interpolate>(interpolate1->input_value(0), interpolate1->input_value(1),
|
||||||
|
scales_node, axes_node, interpolate4_attr);
|
||||||
|
|
||||||
|
interpolate4->set_friendly_name(interpolate1->get_friendly_name());
|
||||||
|
ngraph::copy_runtime_info(interpolate1, interpolate4);
|
||||||
|
ngraph::replace_node(interpolate1, interpolate4);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
auto m = std::make_shared<ngraph::pattern::Matcher>(interpolate1, "ConvertInterpolate1ToInterpolate4");
|
||||||
|
this->register_matcher(m, callback);
|
||||||
|
}
|
||||||
@@ -21,6 +21,7 @@
|
|||||||
|
|
||||||
using namespace testing;
|
using namespace testing;
|
||||||
using namespace ngraph::pass;
|
using namespace ngraph::pass;
|
||||||
|
using namespace ngraph;
|
||||||
using namespace ngraph::builder::subgraph;
|
using namespace ngraph::builder::subgraph;
|
||||||
|
|
||||||
class interpAttributes {
|
class interpAttributes {
|
||||||
@@ -32,6 +33,8 @@ public:
|
|||||||
std::vector<size_t> pads_begin;
|
std::vector<size_t> pads_begin;
|
||||||
std::vector<size_t> pads_end;
|
std::vector<size_t> pads_end;
|
||||||
|
|
||||||
|
interpAttributes() = default;
|
||||||
|
|
||||||
interpAttributes(const ngraph::AxisSet& axes,
|
interpAttributes(const ngraph::AxisSet& axes,
|
||||||
const std::string& mode,
|
const std::string& mode,
|
||||||
const bool& align_corners,
|
const bool& align_corners,
|
||||||
@@ -42,6 +45,23 @@ public:
|
|||||||
antialias(antialias), pads_begin(pads_begin), pads_end(pads_end) {}
|
antialias(antialias), pads_begin(pads_begin), pads_end(pads_end) {}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class interp4Attributes {
|
||||||
|
public:
|
||||||
|
op::v4::Interpolate::InterpolateMode mode;
|
||||||
|
op::v4::Interpolate::CoordinateTransformMode coordinate_transformation_mode;
|
||||||
|
std::vector<size_t> pads_begin;
|
||||||
|
std::vector<size_t> pads_end;
|
||||||
|
|
||||||
|
interp4Attributes() = default;
|
||||||
|
|
||||||
|
interp4Attributes(const op::v4::Interpolate::InterpolateMode mode,
|
||||||
|
const op::v4::Interpolate::CoordinateTransformMode coordinate_transformation_mode,
|
||||||
|
const std::vector<size_t>& pads_begin,
|
||||||
|
const std::vector<size_t>& pads_end) :
|
||||||
|
mode(mode), coordinate_transformation_mode(coordinate_transformation_mode),
|
||||||
|
pads_begin(pads_begin), pads_end(pads_end) {}
|
||||||
|
};
|
||||||
|
|
||||||
class InterpolateTransformationTestValues {
|
class InterpolateTransformationTestValues {
|
||||||
public:
|
public:
|
||||||
class Actual {
|
class Actual {
|
||||||
@@ -60,9 +80,11 @@ public:
|
|||||||
|
|
||||||
ngraph::Shape inputShape;
|
ngraph::Shape inputShape;
|
||||||
ngraph::Shape outputShape;
|
ngraph::Shape outputShape;
|
||||||
|
ngraph::Shape scalesShape;
|
||||||
ngraph::pass::low_precision::LayerTransformation::Params params;
|
ngraph::pass::low_precision::LayerTransformation::Params params;
|
||||||
//ngraph::op::InterpolateAttrs interpAttrs;
|
|
||||||
interpAttributes interpAttrs;
|
interpAttributes interpAttrs;
|
||||||
|
interp4Attributes interp4Attrs;
|
||||||
|
int opset_version;
|
||||||
Actual actual;
|
Actual actual;
|
||||||
Expected expected;
|
Expected expected;
|
||||||
};
|
};
|
||||||
@@ -85,60 +107,107 @@ public:
|
|||||||
void SetUp() override {
|
void SetUp() override {
|
||||||
const InterpolateTransformationTestValues testValues = GetParam();
|
const InterpolateTransformationTestValues testValues = GetParam();
|
||||||
|
|
||||||
ngraph::op::InterpolateAttrs interpAttrs;
|
if (testValues.opset_version == 1) {
|
||||||
interpAttrs.axes = testValues.interpAttrs.axes;
|
ngraph::op::InterpolateAttrs interpAttrs;
|
||||||
interpAttrs.mode = testValues.interpAttrs.mode;
|
interpAttrs.axes = testValues.interpAttrs.axes;
|
||||||
interpAttrs.align_corners = testValues.interpAttrs.align_corners;
|
interpAttrs.mode = testValues.interpAttrs.mode;
|
||||||
interpAttrs.antialias = testValues.interpAttrs.antialias;
|
interpAttrs.align_corners = testValues.interpAttrs.align_corners;
|
||||||
interpAttrs.pads_begin = testValues.interpAttrs.pads_begin;
|
interpAttrs.antialias = testValues.interpAttrs.antialias;
|
||||||
interpAttrs.pads_end = testValues.interpAttrs.pads_end;
|
interpAttrs.pads_begin = testValues.interpAttrs.pads_begin;
|
||||||
|
interpAttrs.pads_end = testValues.interpAttrs.pads_end;
|
||||||
|
|
||||||
actualFunction = ngraph::builder::subgraph::InterpolateFunction::getOriginal(
|
actualFunction = ngraph::builder::subgraph::InterpolateFunction::getOriginal(
|
||||||
testValues.inputShape,
|
testValues.inputShape,
|
||||||
testValues.outputShape,
|
testValues.outputShape,
|
||||||
interpAttrs,
|
interpAttrs,
|
||||||
testValues.actual.precisionBeforeDequantization,
|
testValues.actual.precisionBeforeDequantization,
|
||||||
testValues.actual.dequantization);
|
testValues.actual.dequantization);
|
||||||
|
|
||||||
SimpleLowPrecisionTransformer transformer;
|
SimpleLowPrecisionTransformer transformer;
|
||||||
transformer.add<ngraph::pass::low_precision::InterpolateTransformation, ngraph::opset1::Interpolate>(testValues.params);
|
transformer.add<ngraph::pass::low_precision::InterpolateTransformation, ngraph::opset1::Interpolate>(testValues.params);
|
||||||
transformer.transform(actualFunction);
|
transformer.transform(actualFunction);
|
||||||
|
|
||||||
referenceFunction = ngraph::builder::subgraph::InterpolateFunction::getReference(
|
referenceFunction = ngraph::builder::subgraph::InterpolateFunction::getReference(
|
||||||
testValues.inputShape,
|
testValues.inputShape,
|
||||||
testValues.outputShape,
|
testValues.outputShape,
|
||||||
interpAttrs,
|
interpAttrs,
|
||||||
testValues.expected.precisionBeforeDequantization,
|
testValues.expected.precisionBeforeDequantization,
|
||||||
testValues.expected.dequantizationBefore,
|
testValues.expected.dequantizationBefore,
|
||||||
testValues.expected.precisionAfterOperation,
|
testValues.expected.precisionAfterOperation,
|
||||||
testValues.expected.dequantizationAfter);
|
testValues.expected.dequantizationAfter);
|
||||||
|
} else if (testValues.opset_version == 4) {
|
||||||
|
ngraph::op::v4::Interpolate::InterpolateAttrs interp4Attrs;
|
||||||
|
interp4Attrs.mode = testValues.interp4Attrs.mode;
|
||||||
|
interp4Attrs.coordinate_transformation_mode = testValues.interp4Attrs.coordinate_transformation_mode;
|
||||||
|
interp4Attrs.pads_begin = testValues.interp4Attrs.pads_begin;
|
||||||
|
interp4Attrs.pads_end = testValues.interp4Attrs.pads_end;
|
||||||
|
|
||||||
|
actualFunction = ngraph::builder::subgraph::InterpolateFunction::getOriginal(
|
||||||
|
testValues.inputShape,
|
||||||
|
testValues.outputShape,
|
||||||
|
testValues.scalesShape,
|
||||||
|
interp4Attrs,
|
||||||
|
testValues.actual.precisionBeforeDequantization,
|
||||||
|
testValues.actual.dequantization);
|
||||||
|
|
||||||
|
SimpleLowPrecisionTransformer transformer;
|
||||||
|
transformer.add<ngraph::pass::low_precision::InterpolateTransformation, ngraph::opset4::Interpolate>(testValues.params);
|
||||||
|
transformer.transform(actualFunction);
|
||||||
|
|
||||||
|
referenceFunction = ngraph::builder::subgraph::InterpolateFunction::getReference(
|
||||||
|
testValues.inputShape,
|
||||||
|
testValues.outputShape,
|
||||||
|
testValues.scalesShape,
|
||||||
|
interp4Attrs,
|
||||||
|
testValues.expected.precisionBeforeDequantization,
|
||||||
|
testValues.expected.dequantizationBefore,
|
||||||
|
testValues.expected.precisionAfterOperation,
|
||||||
|
testValues.expected.dequantizationAfter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static std::string getTestCaseName(testing::TestParamInfo<InterpolateTransformationTestValues> obj) {
|
static std::string getTestCaseName(testing::TestParamInfo<InterpolateTransformationTestValues> obj) {
|
||||||
const InterpolateTransformationTestValues testValues = obj.param;
|
const InterpolateTransformationTestValues testValues = obj.param;
|
||||||
|
|
||||||
std::ostringstream result;
|
std::ostringstream result;
|
||||||
result <<
|
if (testValues.opset_version == 1) {
|
||||||
|
result <<
|
||||||
testValues.inputShape << "_" <<
|
testValues.inputShape << "_" <<
|
||||||
testValues.outputShape << "_" <<
|
testValues.outputShape << "_" <<
|
||||||
testValues.interpAttrs.align_corners <<
|
testValues.opset_version << "_" <<
|
||||||
testValues.interpAttrs.antialias <<
|
testValues.interpAttrs.align_corners << "_" <<
|
||||||
testValues.interpAttrs.axes <<
|
testValues.interpAttrs.antialias << "_" <<
|
||||||
testValues.interpAttrs.mode <<
|
testValues.interpAttrs.axes << "_" <<
|
||||||
testValues.interpAttrs.pads_begin <<
|
testValues.interpAttrs.mode << "_" <<
|
||||||
testValues.interpAttrs.pads_end <<
|
testValues.interpAttrs.pads_begin << "_" <<
|
||||||
|
testValues.interpAttrs.pads_end << "_" <<
|
||||||
testValues.actual.precisionBeforeDequantization << "_" <<
|
testValues.actual.precisionBeforeDequantization << "_" <<
|
||||||
testValues.actual.dequantization << "_" <<
|
testValues.actual.dequantization << "_" <<
|
||||||
testValues.expected.dequantizationBefore;
|
testValues.expected.dequantizationBefore;
|
||||||
|
} else if (testValues.opset_version == 4) {
|
||||||
|
result <<
|
||||||
|
testValues.inputShape << "_" <<
|
||||||
|
testValues.outputShape << "_" <<
|
||||||
|
testValues.opset_version << "_" <<
|
||||||
|
testValues.interp4Attrs.mode << "_" <<
|
||||||
|
testValues.interp4Attrs.coordinate_transformation_mode << "_" <<
|
||||||
|
testValues.interp4Attrs.pads_begin << "_" <<
|
||||||
|
testValues.interp4Attrs.pads_end << "_" <<
|
||||||
|
testValues.actual.precisionBeforeDequantization << "_" <<
|
||||||
|
testValues.actual.dequantization << "_" <<
|
||||||
|
testValues.expected.dequantizationBefore;
|
||||||
|
}
|
||||||
return result.str();
|
return result.str();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::vector<InterpolateTransformationTestValues> testValues {
|
const std::vector<InterpolateTransformationTestValues> testValues {
|
||||||
|
// opset1
|
||||||
// nearest mode - move dequantization
|
// nearest mode - move dequantization
|
||||||
{
|
{
|
||||||
ngraph::Shape{ 1, 4, 16, 16 },
|
ngraph::Shape{ 1, 4, 16, 16 },
|
||||||
ngraph::Shape{ 1, 4, 32, 32 },
|
ngraph::Shape{ 1, 4, 32, 32 },
|
||||||
|
ngraph::Shape{},
|
||||||
LayerTransformation::createParamsU8I8(),
|
LayerTransformation::createParamsU8I8(),
|
||||||
interpAttributes(
|
interpAttributes(
|
||||||
ngraph::AxisSet{2, 3},
|
ngraph::AxisSet{2, 3},
|
||||||
@@ -147,6 +216,8 @@ const std::vector<InterpolateTransformationTestValues> testValues {
|
|||||||
false,
|
false,
|
||||||
{0},
|
{0},
|
||||||
{0}),
|
{0}),
|
||||||
|
interp4Attributes(),
|
||||||
|
1,
|
||||||
{
|
{
|
||||||
ngraph::element::u8,
|
ngraph::element::u8,
|
||||||
{{ngraph::element::f32}, {-0.32f}, {0.1f}}
|
{{ngraph::element::f32}, {-0.32f}, {0.1f}}
|
||||||
@@ -163,6 +234,7 @@ const std::vector<InterpolateTransformationTestValues> testValues {
|
|||||||
{
|
{
|
||||||
ngraph::Shape{ 1, 4, 16, 16 },
|
ngraph::Shape{ 1, 4, 16, 16 },
|
||||||
ngraph::Shape{ 1, 4, 32, 32 },
|
ngraph::Shape{ 1, 4, 32, 32 },
|
||||||
|
ngraph::Shape{},
|
||||||
LayerTransformation::createParamsU8I8(),
|
LayerTransformation::createParamsU8I8(),
|
||||||
interpAttributes(
|
interpAttributes(
|
||||||
ngraph::AxisSet{2, 3},
|
ngraph::AxisSet{2, 3},
|
||||||
@@ -171,6 +243,8 @@ const std::vector<InterpolateTransformationTestValues> testValues {
|
|||||||
false,
|
false,
|
||||||
{0},
|
{0},
|
||||||
{0}),
|
{0}),
|
||||||
|
interp4Attributes(),
|
||||||
|
1,
|
||||||
{
|
{
|
||||||
ngraph::element::u8,
|
ngraph::element::u8,
|
||||||
{{ngraph::element::f32}, {-0.32f}, {0.1f}}
|
{{ngraph::element::f32}, {-0.32f}, {0.1f}}
|
||||||
@@ -187,6 +261,7 @@ const std::vector<InterpolateTransformationTestValues> testValues {
|
|||||||
{
|
{
|
||||||
ngraph::Shape{ 1, 4, 16, 16 },
|
ngraph::Shape{ 1, 4, 16, 16 },
|
||||||
ngraph::Shape{ 1, 8, 32, 32 },
|
ngraph::Shape{ 1, 8, 32, 32 },
|
||||||
|
ngraph::Shape{},
|
||||||
LayerTransformation::createParamsU8I8(),
|
LayerTransformation::createParamsU8I8(),
|
||||||
interpAttributes(
|
interpAttributes(
|
||||||
ngraph::AxisSet{1, 2, 3},
|
ngraph::AxisSet{1, 2, 3},
|
||||||
@@ -195,6 +270,8 @@ const std::vector<InterpolateTransformationTestValues> testValues {
|
|||||||
false,
|
false,
|
||||||
{0},
|
{0},
|
||||||
{0}),
|
{0}),
|
||||||
|
interp4Attributes(),
|
||||||
|
1,
|
||||||
{
|
{
|
||||||
ngraph::element::u8,
|
ngraph::element::u8,
|
||||||
{{ngraph::element::f32}, {-0.32f}, {0.1f}}
|
{{ngraph::element::f32}, {-0.32f}, {0.1f}}
|
||||||
@@ -211,6 +288,7 @@ const std::vector<InterpolateTransformationTestValues> testValues {
|
|||||||
{
|
{
|
||||||
ngraph::Shape{ 1, 4, 16, 16 },
|
ngraph::Shape{ 1, 4, 16, 16 },
|
||||||
ngraph::Shape{ 1, 4, 32, 32 },
|
ngraph::Shape{ 1, 4, 32, 32 },
|
||||||
|
ngraph::Shape{},
|
||||||
LayerTransformation::createParamsU8I8(),
|
LayerTransformation::createParamsU8I8(),
|
||||||
interpAttributes(
|
interpAttributes(
|
||||||
ngraph::AxisSet{2, 3},
|
ngraph::AxisSet{2, 3},
|
||||||
@@ -219,6 +297,8 @@ const std::vector<InterpolateTransformationTestValues> testValues {
|
|||||||
false,
|
false,
|
||||||
{0},
|
{0},
|
||||||
{0}),
|
{0}),
|
||||||
|
interp4Attributes(),
|
||||||
|
1,
|
||||||
{
|
{
|
||||||
ngraph::element::u8,
|
ngraph::element::u8,
|
||||||
{{ngraph::element::f32}, {-0.32f}, {0.1f}}
|
{{ngraph::element::f32}, {-0.32f}, {0.1f}}
|
||||||
@@ -235,6 +315,7 @@ const std::vector<InterpolateTransformationTestValues> testValues {
|
|||||||
{
|
{
|
||||||
ngraph::Shape{ 1, 4, 16, 16 },
|
ngraph::Shape{ 1, 4, 16, 16 },
|
||||||
ngraph::Shape{ 1, 4, 32, 32 },
|
ngraph::Shape{ 1, 4, 32, 32 },
|
||||||
|
ngraph::Shape{},
|
||||||
LayerTransformation::createParamsU8I8(),
|
LayerTransformation::createParamsU8I8(),
|
||||||
interpAttributes(
|
interpAttributes(
|
||||||
ngraph::AxisSet{2, 3},
|
ngraph::AxisSet{2, 3},
|
||||||
@@ -243,6 +324,8 @@ const std::vector<InterpolateTransformationTestValues> testValues {
|
|||||||
false,
|
false,
|
||||||
{1},
|
{1},
|
||||||
{1}),
|
{1}),
|
||||||
|
interp4Attributes(),
|
||||||
|
1,
|
||||||
{
|
{
|
||||||
ngraph::element::u8,
|
ngraph::element::u8,
|
||||||
{{ngraph::element::f32}, {-0.32f}, {0.1f}}
|
{{ngraph::element::f32}, {-0.32f}, {0.1f}}
|
||||||
@@ -253,7 +336,108 @@ const std::vector<InterpolateTransformationTestValues> testValues {
|
|||||||
ngraph::element::u8,
|
ngraph::element::u8,
|
||||||
{{}, {}, {}}
|
{{}, {}, {}}
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
|
|
||||||
|
// v4::Interpolate
|
||||||
|
// nearest mode - move dequantization
|
||||||
|
{
|
||||||
|
ngraph::Shape{ 1, 4, 16, 16 },
|
||||||
|
ngraph::Shape{ 1, 4, 32, 32 },
|
||||||
|
ngraph::Shape{ 1, 1, 2, 2 },
|
||||||
|
LayerTransformation::createParamsU8I8(),
|
||||||
|
interpAttributes(),
|
||||||
|
interp4Attributes(
|
||||||
|
ngraph::op::v4::Interpolate::InterpolateMode::nearest,
|
||||||
|
ngraph::op::v4::Interpolate::CoordinateTransformMode::half_pixel,
|
||||||
|
{0, 0, 0, 0},
|
||||||
|
{0, 0, 0, 0}),
|
||||||
|
4,
|
||||||
|
{
|
||||||
|
ngraph::element::i8,
|
||||||
|
{{ngraph::element::f32}, {-0.32f}, {0.1f}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ngraph::element::i8,
|
||||||
|
{{}, {}, {}},
|
||||||
|
ngraph::element::i8,
|
||||||
|
{{ngraph::element::f32}, {-0.32f}, {0.1f}}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// mode is not nearest - not transformed
|
||||||
|
{
|
||||||
|
ngraph::Shape{ 1, 4, 16, 16 },
|
||||||
|
ngraph::Shape{ 1, 4, 32, 32 },
|
||||||
|
ngraph::Shape{ 1, 1, 2, 2 },
|
||||||
|
LayerTransformation::createParamsU8I8(),
|
||||||
|
interpAttributes(),
|
||||||
|
interp4Attributes(
|
||||||
|
ngraph::op::v4::Interpolate::InterpolateMode::linear_onnx,
|
||||||
|
ngraph::op::v4::Interpolate::CoordinateTransformMode::half_pixel,
|
||||||
|
{0, 0, 0, 0},
|
||||||
|
{0, 0, 0, 0}),
|
||||||
|
4,
|
||||||
|
{
|
||||||
|
ngraph::element::i8,
|
||||||
|
{{ngraph::element::f32}, {-0.32f}, {0.1f}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ngraph::element::i8,
|
||||||
|
{{ngraph::element::f32}, {-0.32f}, {0.1f}},
|
||||||
|
ngraph::element::i8,
|
||||||
|
{{}, {}, {}}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// align_corners set to true - not transformed
|
||||||
|
{
|
||||||
|
ngraph::Shape{ 1, 4, 16, 16 },
|
||||||
|
ngraph::Shape{ 1, 4, 32, 32 },
|
||||||
|
ngraph::Shape{ 1, 1, 2, 2 },
|
||||||
|
LayerTransformation::createParamsU8I8(),
|
||||||
|
interpAttributes(),
|
||||||
|
interp4Attributes(
|
||||||
|
ngraph::op::v4::Interpolate::InterpolateMode::nearest,
|
||||||
|
ngraph::op::v4::Interpolate::CoordinateTransformMode::align_corners,
|
||||||
|
{0, 0, 0, 0},
|
||||||
|
{0, 0, 0, 0}),
|
||||||
|
4,
|
||||||
|
{
|
||||||
|
ngraph::element::i8,
|
||||||
|
{{ngraph::element::f32}, {-0.32f}, {0.1f}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ngraph::element::i8,
|
||||||
|
{{ngraph::element::f32}, {-0.32f}, {0.1f}},
|
||||||
|
ngraph::element::i8,
|
||||||
|
{{}, {}, {}}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
// have pads - not transformed
|
||||||
|
{
|
||||||
|
ngraph::Shape{ 1, 4, 16, 16 },
|
||||||
|
ngraph::Shape{ 1, 4, 32, 32 },
|
||||||
|
ngraph::Shape{ 1, 1, 2, 2 },
|
||||||
|
LayerTransformation::createParamsU8I8(),
|
||||||
|
interpAttributes(),
|
||||||
|
interp4Attributes(
|
||||||
|
ngraph::op::v4::Interpolate::InterpolateMode::nearest,
|
||||||
|
ngraph::op::v4::Interpolate::CoordinateTransformMode::half_pixel,
|
||||||
|
{0, 0, 0, 1},
|
||||||
|
{0, 0, 1, 0}),
|
||||||
|
4,
|
||||||
|
{
|
||||||
|
ngraph::element::i8,
|
||||||
|
{{ngraph::element::f32}, {-0.32f}, {0.1f}}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
ngraph::element::i8,
|
||||||
|
{{ngraph::element::f32}, {-0.32f}, {0.1f}},
|
||||||
|
ngraph::element::i8,
|
||||||
|
{{}, {}, {}}
|
||||||
|
}
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
TEST_P(InterpolateTransformation, CompareFunctions) {
|
TEST_P(InterpolateTransformation, CompareFunctions) {
|
||||||
|
|||||||
@@ -0,0 +1,112 @@
|
|||||||
|
// Copyright (C) 2020 Intel Corporation
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
//
|
||||||
|
|
||||||
|
#include <gtest/gtest.h>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
#include <memory>
|
||||||
|
#include <queue>
|
||||||
|
|
||||||
|
#include <ngraph/function.hpp>
|
||||||
|
#include <ngraph/opsets/opset1.hpp>
|
||||||
|
#include <ngraph/opsets/opset4.hpp>
|
||||||
|
#include <transformations/op_conversions/convert_interpolate1_to_interpolate4.hpp>
|
||||||
|
#include <transformations/init_node_info.hpp>
|
||||||
|
#include <transformations/utils/utils.hpp>
|
||||||
|
#include <ngraph/pass/manager.hpp>
|
||||||
|
|
||||||
|
#include "common_test_utils/ngraph_test_utils.hpp"
|
||||||
|
|
||||||
|
using namespace testing;
|
||||||
|
using namespace ngraph;
|
||||||
|
|
||||||
|
TEST(TransformationTests, ConvertInterpolate1ToInterpolate4) {
|
||||||
|
std::shared_ptr<ngraph::Function> f(nullptr), f_ref(nullptr);
|
||||||
|
{
|
||||||
|
auto data_node = std::make_shared<opset1::Parameter>(element::f32, Shape{2, 4, 30, 30});
|
||||||
|
auto out_shape_node = opset1::Constant::create(element::i32, Shape{4}, {2, 4, 40, 40});
|
||||||
|
|
||||||
|
auto interpolate1_attr = op::v0::InterpolateAttrs();
|
||||||
|
interpolate1_attr.axes = AxisSet(std::vector<size_t>{0, 1, 2, 3});
|
||||||
|
interpolate1_attr.mode = "nearest";
|
||||||
|
interpolate1_attr.align_corners = false;
|
||||||
|
interpolate1_attr.antialias = false;
|
||||||
|
interpolate1_attr.pads_begin = std::vector<size_t>{0, 0, 0, 0};
|
||||||
|
interpolate1_attr.pads_end = std::vector<size_t>{0, 0, 0, 0};
|
||||||
|
|
||||||
|
auto interpolate1 = std::make_shared<opset1::Interpolate>(data_node, out_shape_node, interpolate1_attr);
|
||||||
|
|
||||||
|
f = std::make_shared<Function>(NodeVector{interpolate1}, ParameterVector{data_node});
|
||||||
|
|
||||||
|
pass::Manager m;
|
||||||
|
m.register_pass<pass::InitNodeInfo>();
|
||||||
|
m.register_pass<pass::ConvertInterpolate1ToInterpolate4>();
|
||||||
|
m.run_passes(f);
|
||||||
|
ASSERT_NO_THROW(check_rt_info(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto data_node = std::make_shared<opset1::Parameter>(element::f32, Shape{2, 4, 30, 30});
|
||||||
|
auto out_shape_node = opset1::Constant::create(element::i32, Shape{4}, {2, 4, 40, 40});
|
||||||
|
auto default_scales_node = opset1::Constant::create(ngraph::element::f32, Shape{4}, {1.f, 1.f, 1.f, 1.f});
|
||||||
|
auto axes_node = opset1::Constant::create(ngraph::element::i64, Shape{4}, {0, 1, 2, 3});
|
||||||
|
|
||||||
|
auto interpolate4_attr = opset4::Interpolate::InterpolateAttrs(opset4::Interpolate::InterpolateMode::nearest,
|
||||||
|
opset4::Interpolate::ShapeCalcMode::sizes, std::vector<size_t>{0, 0, 0, 0}, std::vector<size_t>{0, 0, 0, 0},
|
||||||
|
opset4::Interpolate::CoordinateTransformMode::asymmetric, opset4::Interpolate::NearestMode::floor,
|
||||||
|
false, -0.75);
|
||||||
|
|
||||||
|
auto interpolate4 = std::make_shared<opset4::Interpolate>(data_node, out_shape_node, default_scales_node, axes_node, interpolate4_attr);
|
||||||
|
|
||||||
|
f_ref = std::make_shared<Function>(NodeVector{interpolate4}, ParameterVector{data_node});
|
||||||
|
}
|
||||||
|
|
||||||
|
auto res = compare_functions(f, f_ref);
|
||||||
|
ASSERT_TRUE(res.first) << res.second;
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST(TransformationTests, ConvertInterpolate1ToInterpolate4_1) {
|
||||||
|
std::shared_ptr<ngraph::Function> f(nullptr), f_ref(nullptr);
|
||||||
|
{
|
||||||
|
auto data_node = std::make_shared<opset1::Parameter>(element::f32, Shape{2, 4, 30, 30});
|
||||||
|
auto out_shape_node = opset1::Constant::create(element::i32, Shape{2}, {40, 40});
|
||||||
|
|
||||||
|
auto interpolate1_attr = op::v0::InterpolateAttrs();
|
||||||
|
interpolate1_attr.axes = AxisSet(std::vector<size_t>{2, 3});
|
||||||
|
interpolate1_attr.mode = "linear";
|
||||||
|
interpolate1_attr.align_corners = false;
|
||||||
|
interpolate1_attr.antialias = true;
|
||||||
|
interpolate1_attr.pads_begin = std::vector<size_t>{0, 0, 0, 0};
|
||||||
|
interpolate1_attr.pads_end = std::vector<size_t>{0, 0, 0, 0};
|
||||||
|
|
||||||
|
auto interpolate1 = std::make_shared<opset1::Interpolate>(data_node, out_shape_node, interpolate1_attr);
|
||||||
|
|
||||||
|
f = std::make_shared<Function>(NodeVector{interpolate1}, ParameterVector{data_node});
|
||||||
|
|
||||||
|
pass::Manager m;
|
||||||
|
m.register_pass<pass::InitNodeInfo>();
|
||||||
|
m.register_pass<pass::ConvertInterpolate1ToInterpolate4>();
|
||||||
|
m.run_passes(f);
|
||||||
|
ASSERT_NO_THROW(check_rt_info(f));
|
||||||
|
}
|
||||||
|
|
||||||
|
{
|
||||||
|
auto data_node = std::make_shared<opset1::Parameter>(element::f32, Shape{2, 4, 30, 30});
|
||||||
|
auto out_shape_node = opset1::Constant::create(element::i32, Shape{2}, {40, 40});
|
||||||
|
auto default_scales_node = opset1::Constant::create(ngraph::element::f32, Shape{2}, {1.f, 1.f});
|
||||||
|
auto axes_node = opset1::Constant::create(ngraph::element::i64, Shape{2}, {2, 3});
|
||||||
|
|
||||||
|
auto interpolate4_attr = opset4::Interpolate::InterpolateAttrs(opset4::Interpolate::InterpolateMode::linear_onnx,
|
||||||
|
opset4::Interpolate::ShapeCalcMode::sizes, std::vector<size_t>{0, 0, 0, 0}, std::vector<size_t>{0, 0, 0, 0},
|
||||||
|
opset4::Interpolate::CoordinateTransformMode::align_corners, opset4::Interpolate::NearestMode::floor,
|
||||||
|
false, -0.75);
|
||||||
|
|
||||||
|
auto interpolate4 = std::make_shared<opset4::Interpolate>(data_node, out_shape_node, default_scales_node, axes_node, interpolate4_attr);
|
||||||
|
|
||||||
|
f_ref = std::make_shared<Function>(NodeVector{interpolate4}, ParameterVector{data_node});
|
||||||
|
}
|
||||||
|
|
||||||
|
auto res = compare_functions(f, f_ref);
|
||||||
|
ASSERT_TRUE(res.first) << res.second;
|
||||||
|
}
|
||||||
@@ -17,11 +17,11 @@ const std::vector<InferenceEngine::Precision> netPrecisions = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
const std::vector<std::vector<size_t>> inShapes = {
|
const std::vector<std::vector<size_t>> inShapes = {
|
||||||
{1, 1, 30, 30},
|
{1, 4, 30, 30},
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::vector<std::vector<size_t>> targetShapes = {
|
const std::vector<std::vector<size_t>> targetShapes = {
|
||||||
{1, 1, 40, 40},
|
{1, 4, 40, 40},
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::vector<ngraph::op::v4::Interpolate::InterpolateMode> modesWithoutNearest = {
|
const std::vector<ngraph::op::v4::Interpolate::InterpolateMode> modesWithoutNearest = {
|
||||||
@@ -130,4 +130,60 @@ INSTANTIATE_TEST_CASE_P(smoke_Interpolate_Nearest, InterpolateLayerTest, ::testi
|
|||||||
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||||
InterpolateLayerTest::getTestCaseName);
|
InterpolateLayerTest::getTestCaseName);
|
||||||
|
|
||||||
|
const std::vector<std::vector<size_t>> targetShapesTailTest = {
|
||||||
|
{1, 4, 10, 41}, // 10 * 41 is not multipler of 4, cover tail process code path
|
||||||
|
};
|
||||||
|
|
||||||
|
const std::vector<std::vector<float>> defaultScalesTailTest = {
|
||||||
|
{0.33333f, 1.36666f}
|
||||||
|
};
|
||||||
|
|
||||||
|
const auto interpolateCasesWithoutNearestTail = ::testing::Combine(
|
||||||
|
::testing::ValuesIn(modesWithoutNearest),
|
||||||
|
::testing::ValuesIn(shapeCalculationMode),
|
||||||
|
::testing::ValuesIn(coordinateTransformModes),
|
||||||
|
::testing::ValuesIn(defaultNearestMode),
|
||||||
|
::testing::ValuesIn(antialias),
|
||||||
|
::testing::ValuesIn(pads),
|
||||||
|
::testing::ValuesIn(pads),
|
||||||
|
::testing::ValuesIn(cubeCoefs),
|
||||||
|
::testing::ValuesIn(defaultAxes),
|
||||||
|
::testing::ValuesIn(defaultScalesTailTest));
|
||||||
|
|
||||||
|
const auto interpolateCasesTail = ::testing::Combine(
|
||||||
|
::testing::ValuesIn(nearestMode),
|
||||||
|
::testing::ValuesIn(shapeCalculationMode),
|
||||||
|
::testing::ValuesIn(coordinateTransformModes),
|
||||||
|
::testing::ValuesIn(nearestModes),
|
||||||
|
::testing::ValuesIn(antialias),
|
||||||
|
::testing::ValuesIn(pads),
|
||||||
|
::testing::ValuesIn(pads),
|
||||||
|
::testing::ValuesIn(cubeCoefs),
|
||||||
|
::testing::ValuesIn(defaultAxes),
|
||||||
|
::testing::ValuesIn(defaultScalesTailTest));
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(smoke_Interpolate_Basic_2, InterpolateLayerTest, ::testing::Combine(
|
||||||
|
interpolateCasesWithoutNearestTail,
|
||||||
|
::testing::ValuesIn(netPrecisions),
|
||||||
|
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||||
|
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||||
|
::testing::Values(InferenceEngine::Layout::ANY),
|
||||||
|
::testing::Values(InferenceEngine::Layout::ANY),
|
||||||
|
::testing::ValuesIn(inShapes),
|
||||||
|
::testing::ValuesIn(targetShapesTailTest),
|
||||||
|
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||||
|
InterpolateLayerTest::getTestCaseName);
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(smoke_Interpolate_Nearest_2, InterpolateLayerTest, ::testing::Combine(
|
||||||
|
interpolateCasesTail,
|
||||||
|
::testing::ValuesIn(netPrecisions),
|
||||||
|
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||||
|
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||||
|
::testing::Values(InferenceEngine::Layout::ANY),
|
||||||
|
::testing::Values(InferenceEngine::Layout::ANY),
|
||||||
|
::testing::ValuesIn(inShapes),
|
||||||
|
::testing::ValuesIn(targetShapesTailTest),
|
||||||
|
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||||
|
InterpolateLayerTest::getTestCaseName);
|
||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|||||||
@@ -149,6 +149,7 @@ const std::vector<ngraph::op::v4::Interpolate::NearestMode> defNearestModes = {
|
|||||||
|
|
||||||
const std::vector<std::vector<size_t>> pads = {
|
const std::vector<std::vector<size_t>> pads = {
|
||||||
{0, 0, 0, 0},
|
{0, 0, 0, 0},
|
||||||
|
{0, 0, 1, 1},
|
||||||
};
|
};
|
||||||
|
|
||||||
const std::vector<bool> antialias = {
|
const std::vector<bool> antialias = {
|
||||||
@@ -191,6 +192,18 @@ const auto interpolateCasesLinearOnnx = ::testing::Combine(
|
|||||||
::testing::ValuesIn(defaultAxes),
|
::testing::ValuesIn(defaultAxes),
|
||||||
::testing::ValuesIn(defaultScales));
|
::testing::ValuesIn(defaultScales));
|
||||||
|
|
||||||
|
const auto interpolateCasesCubic = ::testing::Combine(
|
||||||
|
::testing::Values(ngraph::op::v4::Interpolate::InterpolateMode::cubic),
|
||||||
|
::testing::ValuesIn(shapeCalculationMode),
|
||||||
|
::testing::ValuesIn(coordinateTransformModes),
|
||||||
|
::testing::ValuesIn(defNearestModes),
|
||||||
|
::testing::ValuesIn(antialias),
|
||||||
|
::testing::ValuesIn(pads),
|
||||||
|
::testing::ValuesIn(pads),
|
||||||
|
::testing::ValuesIn(cubeCoefs),
|
||||||
|
::testing::ValuesIn(defaultAxes),
|
||||||
|
::testing::ValuesIn(defaultScales));
|
||||||
|
|
||||||
INSTANTIATE_TEST_CASE_P(smoke_InterpolateNN_Layout_Test, InterpolateLayerCPUTest,
|
INSTANTIATE_TEST_CASE_P(smoke_InterpolateNN_Layout_Test, InterpolateLayerCPUTest,
|
||||||
::testing::Combine(
|
::testing::Combine(
|
||||||
::testing::Combine(
|
::testing::Combine(
|
||||||
@@ -200,8 +213,8 @@ INSTANTIATE_TEST_CASE_P(smoke_InterpolateNN_Layout_Test, InterpolateLayerCPUTest
|
|||||||
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||||
::testing::Values(InferenceEngine::Layout::ANY),
|
::testing::Values(InferenceEngine::Layout::ANY),
|
||||||
::testing::Values(InferenceEngine::Layout::ANY),
|
::testing::Values(InferenceEngine::Layout::ANY),
|
||||||
::testing::Values(std::vector<size_t>({1, 1, 40, 40})),
|
::testing::Values(std::vector<size_t>({1, 21, 40, 40})),
|
||||||
::testing::Values(std::vector<size_t>({1, 1, 50, 60})),
|
::testing::Values(std::vector<size_t>({1, 21, 50, 60})),
|
||||||
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||||
::testing::ValuesIn(filterCPUInfoForDevice())),
|
::testing::ValuesIn(filterCPUInfoForDevice())),
|
||||||
InterpolateLayerCPUTest::getTestCaseName);
|
InterpolateLayerCPUTest::getTestCaseName);
|
||||||
@@ -215,8 +228,23 @@ INSTANTIATE_TEST_CASE_P(smoke_InterpolateLinearOnnx_Layout_Test, InterpolateLaye
|
|||||||
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||||
::testing::Values(InferenceEngine::Layout::ANY),
|
::testing::Values(InferenceEngine::Layout::ANY),
|
||||||
::testing::Values(InferenceEngine::Layout::ANY),
|
::testing::Values(InferenceEngine::Layout::ANY),
|
||||||
::testing::Values(std::vector<size_t>({1, 1, 40, 40})),
|
::testing::Values(std::vector<size_t>({1, 21, 40, 40})),
|
||||||
::testing::Values(std::vector<size_t>({1, 1, 50, 60})),
|
::testing::Values(std::vector<size_t>({1, 21, 50, 60})),
|
||||||
|
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||||
|
::testing::ValuesIn(filterCPUInfoForDevice())),
|
||||||
|
InterpolateLayerCPUTest::getTestCaseName);
|
||||||
|
|
||||||
|
INSTANTIATE_TEST_CASE_P(smoke_InterpolateCubic_Layout_Test, InterpolateLayerCPUTest,
|
||||||
|
::testing::Combine(
|
||||||
|
::testing::Combine(
|
||||||
|
interpolateCasesCubic,
|
||||||
|
::testing::ValuesIn(netPrecisions),
|
||||||
|
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||||
|
::testing::Values(InferenceEngine::Precision::UNSPECIFIED),
|
||||||
|
::testing::Values(InferenceEngine::Layout::ANY),
|
||||||
|
::testing::Values(InferenceEngine::Layout::ANY),
|
||||||
|
::testing::Values(std::vector<size_t>({1, 21, 40, 40})),
|
||||||
|
::testing::Values(std::vector<size_t>({1, 21, 50, 60})),
|
||||||
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
::testing::Values(CommonTestUtils::DEVICE_CPU)),
|
||||||
::testing::ValuesIn(filterCPUInfoForDevice())),
|
::testing::ValuesIn(filterCPUInfoForDevice())),
|
||||||
InterpolateLayerCPUTest::getTestCaseName);
|
InterpolateLayerCPUTest::getTestCaseName);
|
||||||
|
|||||||
@@ -35,6 +35,32 @@ public:
|
|||||||
const ngraph::builder::subgraph::DequantizationOperations& dequantizationBefore,
|
const ngraph::builder::subgraph::DequantizationOperations& dequantizationBefore,
|
||||||
const ngraph::element::Type precisionAfterOperation,
|
const ngraph::element::Type precisionAfterOperation,
|
||||||
const ngraph::builder::subgraph::DequantizationOperations& dequantizationAfter);
|
const ngraph::builder::subgraph::DequantizationOperations& dequantizationAfter);
|
||||||
|
|
||||||
|
// v4::Interpolate
|
||||||
|
static std::shared_ptr<ngraph::Function> getOriginal(
|
||||||
|
const ngraph::Shape& inputShape,
|
||||||
|
const ngraph::Shape& outputShape,
|
||||||
|
const ngraph::Shape& scalesShape,
|
||||||
|
const ngraph::op::v4::Interpolate::InterpolateAttrs& interp4Attrs,
|
||||||
|
const ngraph::element::Type precisionBeforeDequantization,
|
||||||
|
const ngraph::builder::subgraph::DequantizationOperations& dequantization);
|
||||||
|
|
||||||
|
static std::shared_ptr<ngraph::Function> getOriginal(
|
||||||
|
const ngraph::element::Type precision,
|
||||||
|
const ngraph::Shape& inputShape,
|
||||||
|
const ngraph::Shape& outputShape,
|
||||||
|
const ngraph::Shape& scalesShape,
|
||||||
|
const ngraph::op::v4::Interpolate::InterpolateAttrs& interp4Attrs);
|
||||||
|
|
||||||
|
static std::shared_ptr<ngraph::Function> getReference(
|
||||||
|
const ngraph::Shape& inputShape,
|
||||||
|
const ngraph::Shape& outputShape,
|
||||||
|
const ngraph::Shape& scalesShape,
|
||||||
|
const ngraph::op::v4::Interpolate::InterpolateAttrs& interp4Attrs,
|
||||||
|
const ngraph::element::Type precisionBeforeDequantization,
|
||||||
|
const ngraph::builder::subgraph::DequantizationOperations& dequantizationBefore,
|
||||||
|
const ngraph::element::Type precisionAfterOperation,
|
||||||
|
const ngraph::builder::subgraph::DequantizationOperations& dequantizationAfter);
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace subgraph
|
} // namespace subgraph
|
||||||
|
|||||||
@@ -70,6 +70,72 @@ std::shared_ptr<ngraph::Function> InterpolateFunction::getReference(
|
|||||||
return std::make_shared<ngraph::Function>(results, ngraph::ParameterVector{ input }, "InterpolateFunction");
|
return std::make_shared<ngraph::Function>(results, ngraph::ParameterVector{ input }, "InterpolateFunction");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// v4:interpolate
|
||||||
|
std::shared_ptr<ngraph::Function> InterpolateFunction::getOriginal(
|
||||||
|
const ngraph::Shape& inputShape,
|
||||||
|
const ngraph::Shape& outputShape,
|
||||||
|
const ngraph::Shape& scalesShape,
|
||||||
|
const ngraph::op::v4::Interpolate::InterpolateAttrs& interpAttrs,
|
||||||
|
const ngraph::element::Type precisionBeforeDequantization,
|
||||||
|
const ngraph::builder::subgraph::DequantizationOperations& dequantization) {
|
||||||
|
const std::shared_ptr<op::v0::Parameter> input = std::make_shared<ngraph::opset1::Parameter>(
|
||||||
|
precisionBeforeDequantization,
|
||||||
|
ngraph::Shape(inputShape));
|
||||||
|
|
||||||
|
const auto dequantizationOp = makeDequantization(input, dequantization);
|
||||||
|
const auto outShape = std::make_shared<ngraph::opset1::Constant>(ngraph::element::i64, ngraph::Shape{ outputShape.size() }, outputShape);
|
||||||
|
const auto scales = std::make_shared<ngraph::opset1::Constant>(ngraph::element::f32, ngraph::Shape{ scalesShape.size() }, scalesShape);
|
||||||
|
const auto interpolate = std::make_shared<ngraph::op::v4::Interpolate>(dequantizationOp, outShape, scales, interpAttrs);
|
||||||
|
interpolate->set_friendly_name("output");
|
||||||
|
|
||||||
|
ngraph::ResultVector results{ std::make_shared<ngraph::opset1::Result>(interpolate) };
|
||||||
|
return std::make_shared<ngraph::Function>(results, ngraph::ParameterVector{ input }, "InterpolateFunction");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<ngraph::Function> InterpolateFunction::getOriginal(
|
||||||
|
const ngraph::element::Type precision,
|
||||||
|
const ngraph::Shape& inputShape,
|
||||||
|
const ngraph::Shape& outputShape,
|
||||||
|
const ngraph::Shape& scalesShape,
|
||||||
|
const ngraph::op::v4::Interpolate::InterpolateAttrs& interpAttrs) {
|
||||||
|
float k = 50.f;
|
||||||
|
|
||||||
|
const auto input = std::make_shared<ngraph::opset1::Parameter>(precision, inputShape);
|
||||||
|
const auto fakeQuantizeOnActivations = ngraph::builder::makeFakeQuantize(
|
||||||
|
input, precision, 256ul, { 1ul },
|
||||||
|
{ 0.f }, { 255.f / k }, { 10.f }, { 255.f / k });
|
||||||
|
const auto outShape = std::make_shared<ngraph::opset1::Constant>(ngraph::element::i64, ngraph::Shape{ outputShape.size() }, outputShape);
|
||||||
|
const auto scales = std::make_shared<ngraph::opset1::Constant>(ngraph::element::f32, ngraph::Shape{ scalesShape.size() }, scalesShape);
|
||||||
|
const auto interpolate = std::make_shared<ngraph::op::v4::Interpolate>(fakeQuantizeOnActivations, outShape, scales, interpAttrs);
|
||||||
|
|
||||||
|
ngraph::ResultVector results{ std::make_shared<ngraph::opset1::Result>(interpolate) };
|
||||||
|
return std::make_shared<ngraph::Function>(results, ngraph::ParameterVector{ input }, "InterpolateFunction");
|
||||||
|
}
|
||||||
|
|
||||||
|
std::shared_ptr<ngraph::Function> InterpolateFunction::getReference(
|
||||||
|
const ngraph::Shape& inputShape,
|
||||||
|
const ngraph::Shape& outputShape,
|
||||||
|
const ngraph::Shape& scalesShape,
|
||||||
|
const ngraph::op::v4::Interpolate::InterpolateAttrs& interpAttrs,
|
||||||
|
const ngraph::element::Type precisionBeforeDequantization,
|
||||||
|
const ngraph::builder::subgraph::DequantizationOperations& dequantizationBefore,
|
||||||
|
const ngraph::element::Type precisionAfterOperation,
|
||||||
|
const ngraph::builder::subgraph::DequantizationOperations& dequantizationAfter) {
|
||||||
|
const std::shared_ptr<op::v0::Parameter> input = std::make_shared<ngraph::opset1::Parameter>(
|
||||||
|
precisionBeforeDequantization,
|
||||||
|
ngraph::Shape(inputShape));
|
||||||
|
|
||||||
|
const std::shared_ptr<Node> quantizationOpBefore = makeDequantization(input, dequantizationBefore);
|
||||||
|
const auto outShape = std::make_shared<ngraph::opset1::Constant>(ngraph::element::i64, ngraph::Shape{ outputShape.size() }, outputShape);
|
||||||
|
const auto scales = std::make_shared<ngraph::opset1::Constant>(ngraph::element::f32, ngraph::Shape{ scalesShape.size() }, scalesShape);
|
||||||
|
const auto interpolate = std::make_shared<ngraph::op::v4::Interpolate>(quantizationOpBefore, outShape, scales, interpAttrs);
|
||||||
|
const std::shared_ptr<Node> quantizationOpAfter = makeDequantization(interpolate, dequantizationAfter);
|
||||||
|
quantizationOpAfter->set_friendly_name("output");
|
||||||
|
|
||||||
|
ngraph::ResultVector results{ std::make_shared<ngraph::opset1::Result>(quantizationOpAfter) };
|
||||||
|
return std::make_shared<ngraph::Function>(results, ngraph::ParameterVector{ input }, "InterpolateFunction");
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace subgraph
|
} // namespace subgraph
|
||||||
} // namespace builder
|
} // namespace builder
|
||||||
} // namespace ngraph
|
} // namespace ngraph
|
||||||
|
|||||||
@@ -152,6 +152,10 @@ namespace ngraph
|
|||||||
float length_resized,
|
float length_resized,
|
||||||
float length_original) const
|
float length_original) const
|
||||||
{
|
{
|
||||||
|
if (x_scale == 1.0f || (length_resized == length_original))
|
||||||
|
{
|
||||||
|
return x_resized;
|
||||||
|
}
|
||||||
return m_func(x_resized, x_scale, length_resized, length_original);
|
return m_func(x_resized, x_scale, length_resized, length_original);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user