Remove ops from Node Converter- part 2 (#4181)

* remove NodeConverter for Interpolate and ScaleShiftIE

* add SpecificCreators for Interpolate and ScaleShiftIE

* add commented lines to check if tests will pass

* remove comments to check if tests will pass

* checking if tests are avaiable for ResampleV2

* remove NodeConvertor for ExecutionNode

* remove nodeCovnertor for ResampleV2 and add SLT for serialization

* remove shufflechannels op from node converter

* enable visitor api for resamplev2

* remove nodeconverter class

* add missing newline

* remove interpolate sslt- sporadic fails

* remove unnecessary interpolate specific creator

* Add interpolate specific creator

Co-authored-by: blesniewski <bartosz.lesniewski@intel.com>
This commit is contained in:
Bartek Szmelczynski 2021-02-09 20:13:08 +01:00 committed by GitHub
parent 91f05008db
commit 78c045b7ae
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 115 additions and 304 deletions

View File

@ -67,6 +67,8 @@ public:
void validate_and_infer_types() override;
bool visit_attributes(AttributeVisitor &visitor) override;
std::shared_ptr<Node> clone_with_new_inputs(const OutputVector& new_args) const override;
ResampleIEAttrs get_attrs() { return m_attrs; }

View File

@ -22,6 +22,7 @@ public:
const Output<Node>& weights,
const Output<Node>& bias,
const element::Type output_type = element::undefined);
bool visit_attributes(AttributeVisitor& visitor) override;
void validate_and_infer_types() override;

View File

@ -1616,6 +1616,14 @@ InferenceEngine::details::CNNLayerCreator::CNNLayerCreator(const std::shared_ptr
return res;
});
addSpecificCreator({"Interpolate"}, [](const std::shared_ptr<::ngraph::Node>& node,
const std::map<std::string, std::string>& params) -> CNNLayerPtr {
LayerParams attrs = {node->get_friendly_name(), "Interpolate", details::convertPrecision(node->get_output_element_type(0))};
auto res = std::make_shared<InferenceEngine::CNNLayer>(attrs);
res->params = params;
return res;
});
addSpecificCreator({"CropIE"}, [](const std::shared_ptr<::ngraph::Node> &node,
const std::map<std::string, std::string> &params) -> CNNLayerPtr {
LayerParams attrs = {node->get_friendly_name(), "Crop", details::convertPrecision(node->get_output_element_type(0))};
@ -1624,6 +1632,70 @@ InferenceEngine::details::CNNLayerCreator::CNNLayerCreator(const std::shared_ptr
return res;
});
addSpecificCreator({"ScaleShiftIE"}, [](const std::shared_ptr<::ngraph::Node>& node,
const std::map<std::string, std::string>& params) -> CNNLayerPtr {
LayerParams attrs = {node->get_friendly_name(), "ScaleShift", details::convertPrecision(node->get_output_element_type(0))};
auto res = std::make_shared<InferenceEngine::ScaleShiftLayer>(attrs);
res->params = params;
const auto weightsNode = node->input_value(1).get_node_shared_ptr();
InferenceEngine::details::addBlob(weightsNode, res, InferenceEngine::details::weights);
const auto biasNode = node->input_value(2).get_node_shared_ptr();
InferenceEngine::details::addBlob(biasNode, res, InferenceEngine::details::biases);
return res;
});
addSpecificCreator({"ExecutionNode"}, [](const std::shared_ptr<::ngraph::Node>& node,
const std::map<std::string, std::string>& params) -> CNNLayerPtr {
auto& rtInfo = node->get_rt_info();
if (rtInfo.count(ExecGraphInfoSerialization::LAYER_TYPE) == 0) {
THROW_IE_EXCEPTION << "No " << ExecGraphInfoSerialization::LAYER_TYPE
<< " attribute is set in " << node->get_friendly_name() << " node";
}
auto getStringValue = [] (const std::shared_ptr<ngraph::Variant> & variant) {
auto castedVariant = std::dynamic_pointer_cast<ngraph::VariantImpl<std::string>>(variant);
IE_ASSERT(castedVariant != nullptr);
return castedVariant->get();
};
LayerParams attrs = {node->get_friendly_name(),
getStringValue(rtInfo[ExecGraphInfoSerialization::LAYER_TYPE]),
details::convertPrecision(node->get_output_element_type(0))};
rtInfo.erase(ExecGraphInfoSerialization::LAYER_TYPE);
auto res = std::make_shared<InferenceEngine::CNNLayer>(attrs);
res->params = params;
for (const auto & kvp : rtInfo) {
auto castedVariant = std::dynamic_pointer_cast<ngraph::VariantImpl<std::string>>(kvp.second);
// skip RT info which holds fusedNames, etc
if (castedVariant)
res->params[kvp.first] = getStringValue(castedVariant);
}
return res;
});
addSpecificCreator({"ResampleV2"}, [](const std::shared_ptr<::ngraph::Node>& node,
const std::map<std::string, std::string>& params) -> CNNLayerPtr {
LayerParams attrs = {node->get_friendly_name(), "Resample", details::convertPrecision(node->get_output_element_type(0))};
auto res = std::make_shared<InferenceEngine::CNNLayer>(attrs);
res->params = params;
res->params["antialias"] = res->getBoolStrParamAsIntStr("antialias");
if (res->params["type"] == "nearest") {
res->params["type"] = "caffe.ResampleParameter.NEAREST";
} else if (res->params["type"] == "cubic") {
res->params["type"] = "caffe.ResampleParameter.CUBIC";
} else if (res->params["type"] == "area") {
res->params["type"] = "caffe.ResampleParameter.AREA";
} else if (res->params["type"] == "linear") {
res->params["type"] = "caffe.ResampleParameter.LINEAR";
}
return res;
});
addSpecificCreator({"FullyConnected"}, [](const std::shared_ptr<::ngraph::Node> &node,
const std::map<std::string, std::string> &params) -> CNNLayerPtr {
LayerParams attrs = {node->get_friendly_name(), "FullyConnected", details::convertPrecision(node->get_output_element_type(0))};
@ -1673,6 +1745,14 @@ InferenceEngine::details::CNNLayerCreator::CNNLayerCreator(const std::shared_ptr
return res;
});
addSpecificCreator({"ShuffleChannels"}, [](const std::shared_ptr<::ngraph::Node>& node,
const std::map<std::string, std::string>& params) -> CNNLayerPtr {
LayerParams attrs = {node->get_friendly_name(), "ShuffleChannels", details::convertPrecision(node->get_output_element_type(0))};
auto res = std::make_shared<InferenceEngine::ShuffleChannelsLayer>(attrs);
res->params = params;
return res;
});
addSpecificCreator({"PowerIE"}, [](const std::shared_ptr<::ngraph::Node> &node,
const std::map<std::string, std::string> &params) -> CNNLayerPtr {
LayerParams attrs = {node->get_friendly_name(), "Power", details::convertPrecision(node->get_output_element_type(0))};
@ -1711,24 +1791,11 @@ void convertFunctionToICNNNetwork(const std::shared_ptr<const ::ngraph::Function
this->node = node;
}
};
static const std::vector<std::shared_ptr<Builder::INodeConverter>> convertors = {
std::make_shared<Builder::NodeConverter<::ngraph::op::ResampleV2>>(),
std::make_shared<Builder::NodeConverter<::ngraph::op::ScaleShiftIE>>(),
std::make_shared<Builder::NodeConverter<::ngraph::op::ShuffleChannels>>(),
std::make_shared<Builder::NodeConverter<::ngraph::op::v4::Interpolate>>(),
std::make_shared<Builder::NodeConverter<::ExecGraphInfoSerialization::ExecutionNode>>(),
};
CNNLayerPtr result;
for (auto &convertor : convertors) {
if (!convertor->canCreate(node)) continue;
result = convertor->createLayer(node);
break;
}
if (!result) {
CNNLayerCreator visitor(node);
if (node->visit_attributes(visitor)) result = visitor.create();
CNNLayerCreator visitor(node);
if (node->visit_attributes(visitor)) {
result = visitor.create();
}
if (!result)

View File

@ -1,264 +0,0 @@
// Copyright (C) 2018-2020 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#include <limits>
#include <cmath>
#include <set>
#include <sstream>
#include <utility>
#include "legacy/ngraph_ops/fully_connected.hpp"
#include "legacy/ngraph_ops/interp.hpp"
#include <transformations/rt_info/primitives_priority_attribute.hpp>
#include "legacy/ngraph_ops/scaleshift.hpp"
#include "exec_graph_info.hpp"
#include <cnn_network_ngraph_impl.hpp>
#include <precision_utils.h>
#include <cpp/ie_cnn_network.h>
#include <ngraph/ngraph.hpp>
#include <ngraph/variant.hpp>
#include <ngraph/opsets/opset5.hpp>
#include <legacy/convert_function_to_cnn_network.hpp>
#include "legacy/graph_transformer.h"
#include "legacy/graph_tools.hpp"
#include "legacy/net_pass.h"
#include <legacy/cnn_network_impl.hpp>
#include <ie_cnn_layer_builder_ngraph.h>
namespace InferenceEngine {
namespace Builder {
template <>
std::string asString<double>(const double& value) {
std::ostringstream sStrm;
sStrm.precision(std::numeric_limits<double>::digits10);
sStrm << std::fixed << value;
std::string result = sStrm.str();
auto pos = result.find_last_not_of("0");
if (pos != std::string::npos) result.erase(pos + 1);
pos = result.find_last_not_of(".");
if (pos != std::string::npos) result.erase(pos + 1);
return result;
}
template <>
std::string asString<float>(const float& value) {
return asString(static_cast<double>(value));
}
template <>
CNNLayer::Ptr NodeConverter<ngraph::op::ScaleShiftIE>::createLayer(const std::shared_ptr<ngraph::Node>& layer) const {
LayerParams params = {layer->get_friendly_name(), "ScaleShift",
details::convertPrecision(layer->get_output_element_type(0))};
auto res = std::make_shared<InferenceEngine::ScaleShiftLayer>(params);
const auto weightsNode = layer->input_value(1).get_node_shared_ptr();
InferenceEngine::details::addBlob(weightsNode, res, InferenceEngine::details::weights);
const auto biasNode = layer->input_value(2).get_node_shared_ptr();
InferenceEngine::details::addBlob(biasNode, res, InferenceEngine::details::biases);
return res;
}
template <>
CNNLayer::Ptr NodeConverter<ngraph::op::ShuffleChannels>::createLayer(const std::shared_ptr<ngraph::Node>& layer) const {
LayerParams params = {layer->get_friendly_name(), "ShuffleChannels", details::convertPrecision(layer->get_output_element_type(0))};
auto res = std::make_shared<InferenceEngine::ShuffleChannelsLayer>(params);
auto castedLayer = ngraph::as_type_ptr<ngraph::op::ShuffleChannels>(layer);
if (castedLayer == nullptr) THROW_IE_EXCEPTION << "Cannot get " << params.type << " layer " << params.name;
res->params["axis"] = std::to_string(castedLayer->get_axis());
res->params["group"] = std::to_string(castedLayer->get_group());
return res;
}
template <>
CNNLayer::Ptr NodeConverter<ngraph::op::ResampleV2>::createLayer(const std::shared_ptr<ngraph::Node>& layer) const {
LayerParams params = {layer->get_friendly_name(), "Resample", details::convertPrecision(layer->get_output_element_type(0))};
auto res = std::make_shared<InferenceEngine::CNNLayer>(params);
auto castedLayer = ngraph::as_type_ptr<ngraph::op::ResampleV2>(layer);
if (castedLayer == nullptr)
THROW_IE_EXCEPTION << "Cannot get " << params.type << " layer " << params.name;
auto attrs = castedLayer->get_attrs();
res->params["antialias"] = attrs.antialias ? "1" : "0";
if (attrs.mode == "nearest") {
res->params["type"] = "caffe.ResampleParameter.NEAREST";
} else if (attrs.mode == "cubic") {
res->params["type"] = "caffe.ResampleParameter.CUBIC";
} else if (attrs.mode == "area") {
res->params["type"] = "caffe.ResampleParameter.AREA";
} else if (attrs.mode == "linear") {
res->params["type"] = "caffe.ResampleParameter.LINEAR";
}
res->params["factor"] = asString(attrs.factor);
return res;
}
template <>
CNNLayer::Ptr NodeConverter<ngraph::op::v4::Interpolate>::createLayer(const std::shared_ptr<ngraph::Node>& layer) const {
LayerParams params = {layer->get_friendly_name(), "Interpolate",
details::convertPrecision(layer->get_output_element_type(0))};
auto castedLayer = ngraph::as_type_ptr<ngraph::op::v4::Interpolate>(layer);
if (castedLayer == nullptr) THROW_IE_EXCEPTION << "Cannot get " << params.type << " layer " << params.name;
auto attrs = castedLayer->get_attrs();
auto res = std::make_shared<InferenceEngine::CNNLayer>(params);
switch (attrs.mode) {
case ::ngraph::op::v4::Interpolate::InterpolateMode::nearest: {
res->params["mode"] = "nearest";
break;
}
case ::ngraph::op::v4::Interpolate::InterpolateMode::linear: {
res->params["mode"] = "linear";
break;
}
case ::ngraph::op::v4::Interpolate::InterpolateMode::linear_onnx: {
res->params["mode"] = "linear_onnx";
break;
}
case ::ngraph::op::v4::Interpolate::InterpolateMode::cubic: {
res->params["mode"] = "cubic";
break;
}
default:
THROW_IE_EXCEPTION << "Unsupported mode for Interpolate op";
break;
}
switch (attrs.shape_calculation_mode) {
case ::ngraph::op::v4::Interpolate::ShapeCalcMode::sizes: {
res->params["shape_calculation_mode"] = "sizes";
break;
}
case ::ngraph::op::v4::Interpolate::ShapeCalcMode::scales: {
res->params["shape_calculation_mode"] = "scales";
break;
}
default:
THROW_IE_EXCEPTION << "Unsupported shape_calculation_mode for Interpolate op";
break;
}
switch (attrs.coordinate_transformation_mode) {
case ::ngraph::op::v4::Interpolate::CoordinateTransformMode::half_pixel: {
res->params["coordinate_transformation_mode"] = "half_pixel";
break;
}
case ::ngraph::op::v4::Interpolate::CoordinateTransformMode::pytorch_half_pixel: {
res->params["coordinate_transformation_mode"] = "pytorch_half_pixel";
break;
}
case ::ngraph::op::v4::Interpolate::CoordinateTransformMode::asymmetric: {
res->params["coordinate_transformation_mode"] = "asymmetric";
break;
}
case ::ngraph::op::v4::Interpolate::CoordinateTransformMode::tf_half_pixel_for_nn: {
res->params["coordinate_transformation_mode"] = "tf_half_pixel_for_nn";
break;
}
case ::ngraph::op::v4::Interpolate::CoordinateTransformMode::align_corners: {
res->params["coordinate_transformation_mode"] = "align_corners";
break;
}
default:
res->params["coordinate_transformation_mode"] = "half_pixel";
break;
}
switch (attrs.nearest_mode) {
case ::ngraph::op::v4::Interpolate::NearestMode::round_prefer_floor: {
res->params["nearest_mode"] = "round_prefer_floor";
break;
}
case ::ngraph::op::v4::Interpolate::NearestMode::round_prefer_ceil: {
res->params["nearest_mode"] = "round_prefer_ceil";
break;
}
case ::ngraph::op::v4::Interpolate::NearestMode::floor: {
res->params["nearest_mode"] = "floor";
break;
}
case ::ngraph::op::v4::Interpolate::NearestMode::ceil: {
res->params["nearest_mode"] = "ceil";
break;
}
case ::ngraph::op::v4::Interpolate::NearestMode::simple: {
res->params["nearest_mode"] = "simple";
break;
}
default:
res->params["nearest_mode"] = "round_prefer_floor";
break;
}
res->params["antialias"] = attrs.antialias ? "True" : "False";
std::string value;
for (const auto& val : attrs.pads_begin) {
if (!value.empty()) value += ",";
value += asString(val);
}
res->params["pads_begin"] = value;
value.clear();
for (const auto& val : attrs.pads_end) {
if (!value.empty()) value += ",";
value += asString(val);
}
res->params["pads_end"] = value;
res->params["cube_coeff"] = asString(attrs.cube_coeff);
return res;
}
template <>
CNNLayer::Ptr NodeConverter<ExecGraphInfoSerialization::ExecutionNode>::createLayer(const std::shared_ptr<ngraph::Node>& layer) const {
auto castedLayer = ngraph::as_type_ptr<ExecGraphInfoSerialization::ExecutionNode>(layer);
if (castedLayer == nullptr)
THROW_IE_EXCEPTION << "Cannot convert " << layer->get_friendly_name() << " layer ";
auto & rtInfo = castedLayer->get_rt_info();
if (rtInfo.count(ExecGraphInfoSerialization::LAYER_TYPE) == 0) {
THROW_IE_EXCEPTION << "No " << ExecGraphInfoSerialization::LAYER_TYPE
<< " attribute is set in " << layer->get_friendly_name() << " node";
}
auto getStringValue = [] (const std::shared_ptr<ngraph::Variant> & variant) {
auto castedVariant = std::dynamic_pointer_cast<ngraph::VariantImpl<std::string>>(variant);
IE_ASSERT(castedVariant != nullptr);
return castedVariant->get();
};
LayerParams params = { layer->get_friendly_name(),
getStringValue(rtInfo[ExecGraphInfoSerialization::LAYER_TYPE]),
details::convertPrecision(layer->get_output_element_type(0)) };
rtInfo.erase(ExecGraphInfoSerialization::LAYER_TYPE);
auto res = std::make_shared<InferenceEngine::CNNLayer>(params);
for (const auto & kvp : rtInfo) {
auto castedVariant = std::dynamic_pointer_cast<ngraph::VariantImpl<std::string>>(kvp.second);
// skip RT info which holds fusedNames, etc
if (castedVariant)
res->params[kvp.first] = getStringValue(castedVariant);
}
return res;
}
} // namespace Builder
} // namespace InferenceEngine

View File

@ -24,13 +24,6 @@ namespace InferenceEngine {
namespace Builder {
class INodeConverter {
public:
virtual CNNLayer::Ptr createLayer(const std::shared_ptr<ngraph::Node>& layer) const = 0;
virtual bool canCreate(const std::shared_ptr<ngraph::Node>& node) const = 0;
virtual ~INodeConverter() = default;
};
template <class T>
std::string asString(const T& value) {
return std::to_string(value);
@ -47,24 +40,25 @@ std::string asString(const std::vector<T>& value) {
}
template <>
std::string asString<double>(const double& value);
std::string asString<double>(const double& value) {
std::ostringstream sStrm;
sStrm.precision(std::numeric_limits<double>::digits10);
sStrm << std::fixed << value;
std::string result = sStrm.str();
auto pos = result.find_last_not_of("0");
if (pos != std::string::npos) result.erase(pos + 1);
pos = result.find_last_not_of(".");
if (pos != std::string::npos) result.erase(pos + 1);
return result;
}
template <>
std::string asString<float>(const float& value);
template <class NGT>
class NodeConverter : public INodeConverter {
public:
NodeConverter() = default;
~NodeConverter() override = default;
CNNLayer::Ptr createLayer(const std::shared_ptr<ngraph::Node>& layer) const override;
bool canCreate(const std::shared_ptr<ngraph::Node>& node) const override {
auto castedPtr = ngraph::as_type_ptr<NGT>(node);
return castedPtr != nullptr;
}
};
std::string asString<float>(const float& value) {
return asString(static_cast<double>(value));
}
} // namespace Builder
} // namespace InferenceEngine

View File

@ -115,3 +115,10 @@ shared_ptr<Node> op::ResampleV2::clone_with_new_inputs(const OutputVector& new_a
check_new_args_count(this, new_args);
return make_shared<ResampleV2>(new_args.at(0), new_args.at(1), m_attrs);
}
bool op::ResampleV2::visit_attributes(AttributeVisitor& visitor) {
visitor.on_attribute("antialias", m_attrs.antialias);
visitor.on_attribute("factor", m_attrs.factor);
visitor.on_attribute("mode", m_attrs.mode);
return true;
}

View File

@ -57,3 +57,7 @@ void op::ScaleShiftIE::validate_and_infer_types() {
set_output_type(0, data_et, get_input_partial_shape(0));
}
bool ngraph::op::ScaleShiftIE::visit_attributes(AttributeVisitor& visitor) {
return true;
}

View File

@ -352,7 +352,7 @@ TEST_F(NGraphReaderTests, ReadInterpolate4Network) {
</blobs>
</layer>
<layer id="4" name="interpolate" precision="FP32" type="Interpolate">
<data antialias="False" coordinate_transformation_mode="asymmetric" cube_coeff="123" mode="nearest" nearest_mode="floor" pads_begin="2,3,4,5" pads_end="6,7,8,9" shape_calculation_mode="sizes"/>
<data antialias="false" coordinate_transformation_mode="asymmetric" cube_coeff="123" mode="nearest" nearest_mode="floor" pads_begin="2,3,4,5" pads_end="6,7,8,9" shape_calculation_mode="sizes"/>
<input>
<port id="0">
<dim>1</dim>