Serialization of experimental and custom ops (#2862)
* Add IEGeneric node type handling. * Remove dependency on plugin_api library. IEGeneric type name is passed via Visiotr API as new syntetic atribute. * Add custom operations support * Fix charachter literals comparison. * Pass custom opsets to CNNNetwork:serialize(). IE extensions are stored in ngraph CNNNetwork and later used to pass custom opsets to serialization transformation. * Refactor custom ops tests to use template_extension library. * Add comment on __generic_ie_type__ purpose.
This commit is contained in:
parent
251429511d
commit
34af04e1a8
@ -20,6 +20,7 @@
|
||||
#include "ie_common.h"
|
||||
#include "ie_data.h"
|
||||
#include "details/ie_exception_conversion.hpp"
|
||||
#include "ie_extension.h"
|
||||
|
||||
namespace ngraph {
|
||||
|
||||
@ -54,8 +55,10 @@ public:
|
||||
* This constructor wraps existing ngraph::Function
|
||||
* If you want to avoid modification of original Function, please create a copy
|
||||
* @param network Pointer to the ngraph::Function object
|
||||
* @param exts Vector of pointers to IE extension objects
|
||||
*/
|
||||
explicit CNNNetwork(const std::shared_ptr<ngraph::Function>& network);
|
||||
explicit CNNNetwork(const std::shared_ptr<ngraph::Function>& network,
|
||||
const std::vector<IExtensionPtr>& exts = {});
|
||||
|
||||
/**
|
||||
* @brief A destructor
|
||||
|
@ -53,7 +53,8 @@ static std::shared_ptr<ngraph::Function> copyFunction(const std::shared_ptr<cons
|
||||
return specialized_function;
|
||||
}
|
||||
|
||||
CNNNetwork::CNNNetwork(const std::shared_ptr<ngraph::Function>& graph) {
|
||||
CNNNetwork::CNNNetwork(const std::shared_ptr<ngraph::Function>& graph,
|
||||
const std::vector<IExtensionPtr>& exts) {
|
||||
OV_ITT_SCOPED_TASK(itt::domains::IE, "CNNNetwork::CNNNetwork");
|
||||
|
||||
if (graph == nullptr) {
|
||||
@ -61,7 +62,7 @@ CNNNetwork::CNNNetwork(const std::shared_ptr<ngraph::Function>& graph) {
|
||||
}
|
||||
|
||||
// Create CNNNetworkNGraphImpl
|
||||
network = std::make_shared<CNNNetworkNGraphImpl>(graph);
|
||||
network = std::make_shared<CNNNetworkNGraphImpl>(graph, exts);
|
||||
actual = network.get();
|
||||
if (actual == nullptr) {
|
||||
THROW_IE_EXCEPTION << "CNNNetwork was not initialized.";
|
||||
@ -111,8 +112,10 @@ void CNNNetworkNGraphImpl::createDataForResult(const ::ngraph::Output<::ngraph::
|
||||
}
|
||||
}
|
||||
|
||||
CNNNetworkNGraphImpl::CNNNetworkNGraphImpl(const std::shared_ptr<Function>& nGraph)
|
||||
: _ngraph_function(nGraph) {
|
||||
CNNNetworkNGraphImpl::CNNNetworkNGraphImpl(
|
||||
const std::shared_ptr<Function>& nGraph,
|
||||
const std::vector<IExtensionPtr>& exts)
|
||||
: _ngraph_function(nGraph), _ie_extensions(exts) {
|
||||
// Restore usual attributes for ICNNNetwork
|
||||
auto keep_input_info = [](CNNNetworkNGraphImpl& network, const DataPtr& inData) {
|
||||
InputInfo::Ptr info(new InputInfo());
|
||||
@ -402,8 +405,15 @@ StatusCode CNNNetworkNGraphImpl::serialize(const std::string& xmlPath,
|
||||
ResponseDesc* resp) const noexcept {
|
||||
try {
|
||||
if (getFunction()) {
|
||||
std::map<std::string, ngraph::OpSet> custom_opsets;
|
||||
for (auto extension : _ie_extensions) {
|
||||
auto opset = extension->getOpSets();
|
||||
custom_opsets.insert(begin(opset), end(opset));
|
||||
}
|
||||
ngraph::pass::Manager manager;
|
||||
manager.register_pass<ngraph::pass::Serialize>(xmlPath, binPath);
|
||||
manager.register_pass<ngraph::pass::Serialize>(
|
||||
xmlPath, binPath, ngraph::pass::Serialize::Version::IR_V10,
|
||||
custom_opsets);
|
||||
manager.run_passes(_ngraph_function);
|
||||
} else {
|
||||
#ifdef ENABLE_V7_SERIALIZE
|
||||
|
@ -27,6 +27,7 @@
|
||||
#include "ie_common.h"
|
||||
#include "ie_data.h"
|
||||
#include "ie_input_info.hpp"
|
||||
#include "ie_extension.h"
|
||||
|
||||
namespace InferenceEngine {
|
||||
namespace details {
|
||||
@ -36,7 +37,8 @@ namespace details {
|
||||
*/
|
||||
class INFERENCE_ENGINE_API_CLASS(CNNNetworkNGraphImpl): public ICNNNetwork {
|
||||
public:
|
||||
CNNNetworkNGraphImpl(const std::shared_ptr<::ngraph::Function>& nGraph);
|
||||
CNNNetworkNGraphImpl(const std::shared_ptr<::ngraph::Function>& nGraph,
|
||||
const std::vector<IExtensionPtr>& exts = {});
|
||||
CNNNetworkNGraphImpl(const ICNNNetwork& nGraph);
|
||||
~CNNNetworkNGraphImpl() override = default;
|
||||
|
||||
@ -88,6 +90,7 @@ protected:
|
||||
private:
|
||||
InferenceEngine::InputsDataMap _inputData;
|
||||
std::map<std::string, DataPtr> _outputData;
|
||||
const std::vector<IExtensionPtr> _ie_extensions;
|
||||
|
||||
/**
|
||||
* @brief Create DataPtr for nGraph operation
|
||||
|
@ -168,3 +168,17 @@ void ngraph::op::GenericIE::validate_and_infer_types() {
|
||||
<< " with type " << type;
|
||||
}
|
||||
}
|
||||
|
||||
bool ngraph::op::GenericIE::visit_attributes(ngraph::AttributeVisitor& visitor) {
|
||||
for (const auto& p : params) {
|
||||
std::string name = p.first;
|
||||
std::string value = p.second;
|
||||
visitor.on_attribute(name, value);
|
||||
}
|
||||
// This is a way to pass type name to transformations::Serialize() without
|
||||
// adding plugin_api dependency on transformation library
|
||||
std::string name = "__generic_ie_type__";
|
||||
std::string value = getType();
|
||||
visitor.on_attribute(name, value);
|
||||
return true;
|
||||
}
|
||||
|
@ -104,6 +104,8 @@ public:
|
||||
|
||||
std::shared_ptr<Node> clone_with_new_inputs(const OutputVector& new_args) const override;
|
||||
|
||||
bool visit_attributes(ngraph::AttributeVisitor& visitor) override;
|
||||
|
||||
static void addExtension(std::shared_ptr<const ngraph::Function> func, const InferenceEngine::IShapeInferExtensionPtr& ext);
|
||||
static std::vector<InferenceEngine::IShapeInferExtensionPtr> getExtensions(std::shared_ptr<const ngraph::Function> func);
|
||||
|
||||
|
@ -63,7 +63,7 @@ public:
|
||||
originBlob(weights) { }
|
||||
};
|
||||
|
||||
V10Parser::V10Parser(const std::vector<IExtensionPtr>& exts) {
|
||||
V10Parser::V10Parser(const std::vector<IExtensionPtr>& exts) : _exts(exts) {
|
||||
// Load default opsets
|
||||
opsets["opset1"] = ngraph::get_opset1();
|
||||
opsets["opset2"] = ngraph::get_opset2();
|
||||
@ -196,7 +196,7 @@ std::shared_ptr<ICNNNetwork> V10Parser::parse(const pugi::xml_node& root, std::i
|
||||
result_nodes[0]->add_control_dependency(assign);
|
||||
}
|
||||
}
|
||||
CNNNetwork net(function);
|
||||
CNNNetwork net(function, _exts);
|
||||
parsePreProcess(net, root, binStream);
|
||||
return net;
|
||||
}
|
||||
|
@ -59,6 +59,7 @@ public:
|
||||
|
||||
private:
|
||||
std::map<std::string, ngraph::OpSet> opsets;
|
||||
const std::vector<IExtensionPtr> _exts;
|
||||
|
||||
struct GenericLayerParams {
|
||||
struct LayerPortData {
|
||||
|
@ -62,7 +62,7 @@ bool ONNXReader::supportModel(std::istream& model) const {
|
||||
}
|
||||
|
||||
CNNNetwork ONNXReader::read(std::istream& model, const std::vector<IExtensionPtr>& exts) const {
|
||||
return CNNNetwork(ngraph::onnx_import::import_onnx_model(model, readPathFromStream(model)));
|
||||
return CNNNetwork(ngraph::onnx_import::import_onnx_model(model, readPathFromStream(model)), exts);
|
||||
}
|
||||
|
||||
INFERENCE_PLUGIN_API(StatusCode) InferenceEngine::CreateReader(IReader*& reader, ResponseDesc *resp) noexcept {
|
||||
|
@ -33,11 +33,12 @@ public:
|
||||
bool run_on_function(std::shared_ptr<ngraph::Function> f) override;
|
||||
|
||||
Serialize(const std::string& xmlPath, const std::string& binPath,
|
||||
Version version = Version::IR_V10)
|
||||
: m_xmlPath{xmlPath}, m_binPath{binPath}, m_version{version} {}
|
||||
Version version = Version::IR_V10, std::map<std::string, ngraph::OpSet> custom_opsets = {})
|
||||
: m_xmlPath{xmlPath}, m_binPath{binPath}, m_version{version}, m_custom_opsets{custom_opsets} {}
|
||||
|
||||
private:
|
||||
const std::string m_xmlPath;
|
||||
const std::string m_binPath;
|
||||
const Version m_version;
|
||||
const std::map<std::string, ngraph::OpSet> m_custom_opsets;
|
||||
};
|
||||
|
@ -18,8 +18,8 @@ NGRAPH_RTTI_DEFINITION(ngraph::pass::Serialize, "Serialize", 0);
|
||||
|
||||
namespace { // helpers
|
||||
template <typename T, typename A>
|
||||
std::string joinVec(std::vector<T, A> const& vec,
|
||||
std::string const& glue = std::string(",")) {
|
||||
std::string joinVec(const std::vector<T, A>& vec,
|
||||
const std::string& glue = std::string(",")) {
|
||||
if (vec.empty()) return "";
|
||||
std::stringstream oss;
|
||||
oss << vec[0];
|
||||
@ -51,6 +51,8 @@ class XmlVisitor : public ngraph::AttributeVisitor {
|
||||
}
|
||||
|
||||
public:
|
||||
std::string ie_generic_type_name = "";
|
||||
|
||||
XmlVisitor(pugi::xml_node& data) : m_data(data) {}
|
||||
|
||||
void on_adapter(const std::string& name,
|
||||
@ -65,7 +67,15 @@ public:
|
||||
}
|
||||
void on_adapter(const std::string& name,
|
||||
ngraph::ValueAccessor<std::string>& adapter) override {
|
||||
m_data.append_attribute(name.c_str()).set_value(adapter.get().c_str());
|
||||
// __generic_ie_type__ should not be serialized as a <data> attribute
|
||||
// it is a WA to retrieve layer type name without introducing dependency on
|
||||
// plugi_api library on transformations library
|
||||
if (name == "__generic_ie_type__") {
|
||||
ie_generic_type_name = adapter.get();
|
||||
} else {
|
||||
m_data.append_attribute(name.c_str())
|
||||
.set_value(adapter.get().c_str());
|
||||
}
|
||||
}
|
||||
void on_adapter(const std::string& name,
|
||||
ngraph::ValueAccessor<int64_t>& adapter) override {
|
||||
@ -160,7 +170,9 @@ ConstantAtributes dump_constant_data(std::vector<uint8_t>& bin,
|
||||
return attr;
|
||||
}
|
||||
|
||||
std::string get_opset_name(const ngraph::Node* n) {
|
||||
std::string get_opset_name(
|
||||
const ngraph::Node* n,
|
||||
const std::map<std::string, ngraph::OpSet>& custom_opsets) {
|
||||
auto opsets = std::array<std::reference_wrapper<const ngraph::OpSet>, 5>{
|
||||
ngraph::get_opset1(), ngraph::get_opset2(), ngraph::get_opset3(),
|
||||
ngraph::get_opset4(), ngraph::get_opset5()};
|
||||
@ -171,6 +183,15 @@ std::string get_opset_name(const ngraph::Node* n) {
|
||||
return "opset" + std::to_string(idx + 1);
|
||||
}
|
||||
}
|
||||
|
||||
for (const auto& custom_opset : custom_opsets) {
|
||||
std::string name = custom_opset.first;
|
||||
ngraph::OpSet opset = custom_opset.second;
|
||||
if (opset.contains_op_type(n)) {
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
return "experimental";
|
||||
}
|
||||
|
||||
@ -180,8 +201,6 @@ std::string get_opset_name(const ngraph::Node* n) {
|
||||
// discrepancies discoverd, translations needs to be added here.
|
||||
std::string get_type_name(const ngraph::Node* n) {
|
||||
std::string name = n->get_type_name();
|
||||
NGRAPH_CHECK(name != "GenericIE", "Unsupported type in ", n);
|
||||
|
||||
const std::unordered_map<std::string, std::string> translator = {
|
||||
{"Constant", "Const"}};
|
||||
if (translator.count(name) > 0) {
|
||||
@ -250,8 +269,10 @@ std::string get_node_unique_name(std::unordered_set<std::string>& unique_names,
|
||||
return name;
|
||||
}
|
||||
|
||||
void ngfunction_2_irv10(pugi::xml_document& doc, std::vector<uint8_t>& bin,
|
||||
const ngraph::Function& f) {
|
||||
void ngfunction_2_irv10(
|
||||
pugi::xml_document& doc, std::vector<uint8_t>& bin,
|
||||
const ngraph::Function& f,
|
||||
const std::map<std::string, ngraph::OpSet>& custom_opsets) {
|
||||
pugi::xml_node netXml = doc.append_child("net");
|
||||
netXml.append_attribute("name").set_value(f.get_friendly_name().c_str());
|
||||
netXml.append_attribute("version").set_value("10");
|
||||
@ -270,9 +291,9 @@ void ngfunction_2_irv10(pugi::xml_document& doc, std::vector<uint8_t>& bin,
|
||||
layer.append_attribute("id").set_value(layer_ids.find(node)->second);
|
||||
layer.append_attribute("name").set_value(
|
||||
get_node_unique_name(unique_names, node).c_str());
|
||||
layer.append_attribute("type").set_value(get_type_name(node).c_str());
|
||||
auto layer_type_attribute = layer.append_attribute("type");
|
||||
layer.append_attribute("version").set_value(
|
||||
get_opset_name(node).c_str());
|
||||
get_opset_name(node, custom_opsets).c_str());
|
||||
|
||||
// <layers/data>
|
||||
pugi::xml_node data = layer.append_child("data");
|
||||
@ -281,7 +302,13 @@ void ngfunction_2_irv10(pugi::xml_document& doc, std::vector<uint8_t>& bin,
|
||||
XmlVisitor visitor{data};
|
||||
NGRAPH_CHECK(node->visit_attributes(visitor),
|
||||
"Visitor API is not supported in ", node);
|
||||
|
||||
std::string node_type_name {node->get_type_name()};
|
||||
if (node_type_name == "GenericIE") {
|
||||
layer_type_attribute.set_value(
|
||||
visitor.ie_generic_type_name.c_str());
|
||||
} else {
|
||||
layer_type_attribute.set_value(get_type_name(node).c_str());
|
||||
}
|
||||
// <layers/data> constant atributes (special case)
|
||||
if (auto constant = dynamic_cast<ngraph::op::Constant*>(node)) {
|
||||
ConstantAtributes attr = dump_constant_data(bin, *constant);
|
||||
@ -347,7 +374,7 @@ bool pass::Serialize::run_on_function(std::shared_ptr<ngraph::Function> f) {
|
||||
std::vector<uint8_t> constants;
|
||||
switch (m_version) {
|
||||
case Version::IR_V10:
|
||||
ngfunction_2_irv10(xml_doc, constants, *f);
|
||||
ngfunction_2_irv10(xml_doc, constants, *f, m_custom_opsets);
|
||||
break;
|
||||
default:
|
||||
NGRAPH_UNREACHABLE("Unsupported version");
|
||||
|
@ -0,0 +1,103 @@
|
||||
// Copyright (C) 2020 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <file_utils.h>
|
||||
#include <ie_api.h>
|
||||
#include <ie_iextension.h>
|
||||
#include "common_test_utils/ngraph_test_utils.hpp"
|
||||
#include "ie_core.hpp"
|
||||
#include "ngraph/ngraph.hpp"
|
||||
#include "transformations/serialize.hpp"
|
||||
|
||||
#ifndef IR_SERIALIZATION_MODELS_PATH // should be already defined by cmake
|
||||
#define IR_SERIALIZATION_MODELS_PATH ""
|
||||
#endif
|
||||
|
||||
#ifndef IE_BUILD_POSTFIX // should be already defined by cmake
|
||||
#define IE_BUILD_POSTFIX ""
|
||||
#endif
|
||||
|
||||
static std::string get_extension_path() {
|
||||
return FileUtils::makeSharedLibraryName<char>(
|
||||
{}, std::string("template_extension") + IE_BUILD_POSTFIX);
|
||||
}
|
||||
|
||||
class CustomOpsSerializationTest : public ::testing::Test {
|
||||
protected:
|
||||
std::string test_name =
|
||||
::testing::UnitTest::GetInstance()->current_test_info()->name();
|
||||
std::string m_out_xml_path = test_name + ".xml";
|
||||
std::string m_out_bin_path = test_name + ".bin";
|
||||
|
||||
void TearDown() override {
|
||||
std::remove(m_out_xml_path.c_str());
|
||||
std::remove(m_out_bin_path.c_str());
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(CustomOpsSerializationTest, CustomOpUser_MO) {
|
||||
const std::string model = IR_SERIALIZATION_MODELS_PATH "custom_op.xml";
|
||||
|
||||
InferenceEngine::Core ie;
|
||||
ie.AddExtension(
|
||||
InferenceEngine::make_so_pointer<InferenceEngine::IExtension>(
|
||||
get_extension_path()));
|
||||
|
||||
auto expected = ie.ReadNetwork(model);
|
||||
expected.serialize(m_out_xml_path, m_out_bin_path);
|
||||
auto result = ie.ReadNetwork(m_out_xml_path, m_out_bin_path);
|
||||
|
||||
bool success;
|
||||
std::string message;
|
||||
std::tie(success, message) =
|
||||
compare_functions(result.getFunction(), expected.getFunction());
|
||||
|
||||
ASSERT_TRUE(success) << message;
|
||||
}
|
||||
|
||||
TEST_F(CustomOpsSerializationTest, CustomOpUser_ONNXImporter) {
|
||||
const std::string model = IR_SERIALIZATION_MODELS_PATH "custom_op.prototxt";
|
||||
|
||||
InferenceEngine::Core ie;
|
||||
ie.AddExtension(
|
||||
InferenceEngine::make_so_pointer<InferenceEngine::IExtension>(
|
||||
get_extension_path()));
|
||||
|
||||
auto expected = ie.ReadNetwork(model);
|
||||
expected.serialize(m_out_xml_path, m_out_bin_path);
|
||||
auto result = ie.ReadNetwork(m_out_xml_path, m_out_bin_path);
|
||||
|
||||
bool success;
|
||||
std::string message;
|
||||
std::tie(success, message) =
|
||||
compare_functions(result.getFunction(), expected.getFunction());
|
||||
|
||||
ASSERT_TRUE(success) << message;
|
||||
}
|
||||
|
||||
TEST_F(CustomOpsSerializationTest, CustomOpTransformation) {
|
||||
const std::string model = IR_SERIALIZATION_MODELS_PATH "custom_op.xml";
|
||||
|
||||
InferenceEngine::Core ie;
|
||||
auto extension =
|
||||
InferenceEngine::make_so_pointer<InferenceEngine::IExtension>(
|
||||
get_extension_path());
|
||||
ie.AddExtension(extension);
|
||||
auto expected = ie.ReadNetwork(model);
|
||||
ngraph::pass::Manager manager;
|
||||
manager.register_pass<ngraph::pass::Serialize>(
|
||||
m_out_xml_path, m_out_bin_path,
|
||||
ngraph::pass::Serialize::Version::IR_V10, extension->getOpSets());
|
||||
manager.run_passes(expected.getFunction());
|
||||
auto result = ie.ReadNetwork(m_out_xml_path, m_out_bin_path);
|
||||
|
||||
bool success;
|
||||
std::string message;
|
||||
std::tie(success, message) =
|
||||
compare_functions(result.getFunction(), expected.getFunction());
|
||||
|
||||
ASSERT_TRUE(success) << message;
|
||||
}
|
@ -0,0 +1,66 @@
|
||||
# This is syntetic model created by hand desined only for white-box unit testing
|
||||
ir_version: 3
|
||||
producer_name: "nGraph ONNX Importer"
|
||||
graph {
|
||||
node {
|
||||
input: "A"
|
||||
output: "Y"
|
||||
name: "operation"
|
||||
op_type: "Template"
|
||||
domain: "custom_domain"
|
||||
attribute {
|
||||
name: "add"
|
||||
type: INT
|
||||
i: 11
|
||||
}
|
||||
}
|
||||
name: "test_graph"
|
||||
input {
|
||||
name: "A"
|
||||
type {
|
||||
tensor_type {
|
||||
elem_type: 1
|
||||
shape {
|
||||
dim {
|
||||
dim_value: 2
|
||||
}
|
||||
dim {
|
||||
dim_value: 2
|
||||
}
|
||||
dim {
|
||||
dim_value: 2
|
||||
}
|
||||
dim {
|
||||
dim_value: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
output {
|
||||
name: "Y"
|
||||
type {
|
||||
tensor_type {
|
||||
elem_type: 1
|
||||
shape {
|
||||
dim {
|
||||
dim_value: 2
|
||||
}
|
||||
dim {
|
||||
dim_value: 2
|
||||
}
|
||||
dim {
|
||||
dim_value: 2
|
||||
}
|
||||
dim {
|
||||
dim_value: 1
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
opset_import {
|
||||
version: 1
|
||||
domain: "com.example"
|
||||
}
|
@ -0,0 +1,50 @@
|
||||
<?xml version="1.0" ?>
|
||||
<!--This is syntetic model created by hand desined only for white-box unit testing-->
|
||||
<net name="Network" version="10">
|
||||
<layers>
|
||||
<layer name="in1" type="Parameter" id="0" version="opset1">
|
||||
<data element_type="f32" shape="2,2,2,1"/>
|
||||
<output>
|
||||
<port id="0" precision="FP32">
|
||||
<dim>2</dim>
|
||||
<dim>2</dim>
|
||||
<dim>2</dim>
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer name="operation" id="1" type="Template" version="custom_opset">
|
||||
<data add="11"/>
|
||||
<input>
|
||||
<port id="1" precision="FP32">
|
||||
<dim>2</dim>
|
||||
<dim>2</dim>
|
||||
<dim>2</dim>
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</input>
|
||||
<output>
|
||||
<port id="2" precision="FP32">
|
||||
<dim>2</dim>
|
||||
<dim>2</dim>
|
||||
<dim>2</dim>
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer name="output" type="Result" id="2" version="opset1">
|
||||
<input>
|
||||
<port id="0" precision="FP32">
|
||||
<dim>2</dim>
|
||||
<dim>2</dim>
|
||||
<dim>2</dim>
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</input>
|
||||
</layer>
|
||||
</layers>
|
||||
<edges>
|
||||
<edge from-layer="0" from-port="0" to-layer="1" to-port="1"/>
|
||||
<edge from-layer="1" from-port="2" to-layer="2" to-port="0"/>
|
||||
</edges>
|
||||
</net>
|
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" ?>
|
||||
<!--This is syntetic model created by hand desined only for white-box unit testing-->
|
||||
<net name="add_abc" version="10">
|
||||
<layers>
|
||||
<layer id="0" name="A" type="Parameter" version="opset1">
|
||||
<data element_type="f32" shape="1"/>
|
||||
<output>
|
||||
<port id="0" precision="FP32">
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="1" name="DetectionOutput" type="ExperimentalDetectronDetectionOutput" version="experimental">
|
||||
<data class_agnostic_box_regression="0" deltas_weights="10.0,10.0,5.0,5.0" max_delta_log_wh="4.135166645050049" max_detections_per_image="100" nms_threshold="0.5" num_classes="81" post_nms_count="2000" score_threshold="0.05"/>
|
||||
<input>
|
||||
<port id="0">
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</input>
|
||||
<output>
|
||||
<port id="1" precision="FP32">
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="2" name="Y" type="Result" version="opset1">
|
||||
<input>
|
||||
<port id="0">
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</input>
|
||||
</layer>
|
||||
</layers>
|
||||
<edges>
|
||||
<edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
|
||||
<edge from-layer="1" from-port="1" to-layer="2" to-port="0"/>
|
||||
</edges>
|
||||
</net>
|
@ -0,0 +1,38 @@
|
||||
<?xml version="1.0" ?>
|
||||
<!--This is syntetic model created by hand desined only for white-box unit testing-->
|
||||
<net name="add_abc" version="10">
|
||||
<layers>
|
||||
<layer id="0" name="A" type="Parameter" version="opset1">
|
||||
<data element_type="f32" shape="1"/>
|
||||
<output>
|
||||
<port id="0" precision="FP32">
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="1" name="ROIFeatureExtractor_1" type="ExperimentalDetectronROIFeatureExtractor" version="experimental">
|
||||
<data distribute_rois_between_levels="1" image_id="0" output_size="14" preserve_rois_order="1" pyramid_scales="4,8,16,32,64" sampling_ratio="2"/>
|
||||
<input>
|
||||
<port id="0">
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</input>
|
||||
<output>
|
||||
<port id="1" precision="FP32">
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</output>
|
||||
</layer>
|
||||
<layer id="2" name="Y" type="Result" version="opset1">
|
||||
<input>
|
||||
<port id="0">
|
||||
<dim>1</dim>
|
||||
</port>
|
||||
</input>
|
||||
</layer>
|
||||
</layers>
|
||||
<edges>
|
||||
<edge from-layer="0" from-port="0" to-layer="1" to-port="0"/>
|
||||
<edge from-layer="1" from-port="1" to-layer="2" to-port="0"/>
|
||||
</edges>
|
||||
</net>
|
@ -165,3 +165,37 @@ TEST_F(SerializationTest, ModelWithConstants_ONNXImporter) {
|
||||
|
||||
ASSERT_TRUE(success) << message;
|
||||
}
|
||||
|
||||
TEST_F(SerializationTest, ExperimentalDetectronROIFeatureExtractor_MO) {
|
||||
const std::string model = IR_SERIALIZATION_MODELS_PATH
|
||||
"experimental_detectron_roi_feature_extractor.xml";
|
||||
|
||||
InferenceEngine::Core ie;
|
||||
auto expected = ie.ReadNetwork(model);
|
||||
expected.serialize(m_out_xml_path, m_out_bin_path);
|
||||
auto result = ie.ReadNetwork(m_out_xml_path, m_out_bin_path);
|
||||
|
||||
bool success;
|
||||
std::string message;
|
||||
std::tie(success, message) =
|
||||
compare_functions(result.getFunction(), expected.getFunction());
|
||||
|
||||
ASSERT_TRUE(success) << message;
|
||||
}
|
||||
|
||||
TEST_F(SerializationTest, ExperimentalDetectronDetectionOutput_MO) {
|
||||
const std::string model = IR_SERIALIZATION_MODELS_PATH
|
||||
"experimental_detectron_detection_output.xml";
|
||||
|
||||
InferenceEngine::Core ie;
|
||||
auto expected = ie.ReadNetwork(model);
|
||||
expected.serialize(m_out_xml_path, m_out_bin_path);
|
||||
auto result = ie.ReadNetwork(m_out_xml_path, m_out_bin_path);
|
||||
|
||||
bool success;
|
||||
std::string message;
|
||||
std::tie(success, message) =
|
||||
compare_functions(result.getFunction(), expected.getFunction());
|
||||
|
||||
ASSERT_TRUE(success) << message;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user