old / new API precisions conversions, old_api_map applying (#7853)
* Enabled support of IR v11 in IR frontend * Enabled serialization to v11 * Added indexes for Inputs/Outputs * Fixed typo * Fixed code style * Fixed deserialization tests * FIxed typo * Avoid changes in the original serialized function * Split IRv7 and IRv10 code * Added preprocessing steps to read network * Added preprocessing for new API for IR v10 * clang-format * Updates for compiler flags * Reverted some changes * Fixed TI tests * Removed version from the function and indexes from parameters/results * Restore function version * Clone function rt info * Removed v11 version * Added serialization of old API map in ngraph. * Changed order type to int64_t. * Fixed uint64_t error, added comments. * Apply suggestions from code review Co-authored-by: Gleb Kazantaev <gleb.nnstu@gmail.com> * Read old_api_map * Added tests with undefined type and empty order. * Fixed reprocessing * Updated gitignore * Updated serialize / deserialize tests * Added set, get and has methods. * Fix in tests. * Applied old_api_map tests * Fixed empty convert_layout * Allow Layout from empty string * Fixed clang-format * Export FEM::load_by_model * Apply suggestions from code review Co-authored-by: Ilya Churaev <ilyachur@gmail.com> * Made inline methods, changed to shared_ptr. * Small fix. * Moved methods to header file. * Small fix. * Applied post-processing * Fixed review comments Co-authored-by: Ilya Churaev <ilya.churaev@intel.com> Co-authored-by: Anastasia Popova <anastasia.popova@intel.com> Co-authored-by: Gleb Kazantaev <gleb.nnstu@gmail.com> Co-authored-by: Ilya Churaev <ilyachur@gmail.com>
This commit is contained in:
16 files changed
+613
-129
No files matched your search
+1
-12
@@ -25,6 +25,7 @@ inference-engine/report
|
||||
docs/template_plugin/html/
|
||||
CMakeLists.txt.user
|
||||
docs/IE_PLUGIN_DG/html/
|
||||
inference-engine/ie_bridges/python/wheel/.env
|
||||
|
||||
*.project
|
||||
*.cproject
|
||||
@@ -57,15 +58,3 @@ __pycache__
|
||||
/model-optimizer/*.mapping
|
||||
/model-optimizer/*.dat
|
||||
/model-optimizer/*.svg
|
||||
|
||||
# ngraph
|
||||
ngraph/src/CPackConfig.cmake
|
||||
ngraph/src/CPackSourceConfig.cmake
|
||||
ngraph/src/VERSION
|
||||
ngraph/src/gtest/
|
||||
ngraph/src/json/
|
||||
ngraph/src/ngraphConfig.cmake
|
||||
ngraph/src/ngraphConfigVersion.cmake
|
||||
ngraph/src/protobuf/
|
||||
ngraph/src/src/
|
||||
ngraph/src/test/
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "ngraph/ngraph.hpp"
|
||||
#include "ngraph/pass/constant_folding.hpp"
|
||||
#include "ngraph/pass/manager.hpp"
|
||||
#include "openvino/core/except.hpp"
|
||||
#include "transformations/serialize.hpp"
|
||||
#include "transformations/smart_reshape/set_batch_size.hpp"
|
||||
#include "transformations/smart_reshape/smart_reshape.hpp"
|
||||
@@ -109,6 +110,20 @@ void CNNNetworkNGraphImpl::validateFunctionNames() const {
|
||||
}
|
||||
}
|
||||
|
||||
ngraph::element::Type details::toLegacyType(const ngraph::element::Type& ngraph_type, bool input) {
|
||||
if (input) {
|
||||
return ngraph_type == ngraph::element::f16 ? ngraph::element::f32 : ngraph_type;
|
||||
} else {
|
||||
if (ngraph_type == ngraph::element::i64 || ngraph_type == ngraph::element::i32) {
|
||||
return ngraph::element::i32;
|
||||
} else if (ngraph_type != ngraph::element::f32) {
|
||||
return ngraph::element::f32;
|
||||
}
|
||||
}
|
||||
|
||||
return ngraph_type;
|
||||
}
|
||||
|
||||
CNNNetworkNGraphImpl::CNNNetworkNGraphImpl(const std::shared_ptr<Function>& nGraph,
|
||||
const std::vector<IExtensionPtr>& exts,
|
||||
bool newAPI)
|
||||
@@ -128,7 +143,7 @@ CNNNetworkNGraphImpl::CNNNetworkNGraphImpl(const std::shared_ptr<Function>& nGra
|
||||
? Precision::I16
|
||||
: prc == Precision::FP16 ? Precision::FP32 : static_cast<Precision::ePrecision>(prc);
|
||||
|
||||
info->setPrecision(prc);
|
||||
info->setPrecision(details::convertPrecision(toLegacyType(details::convertPrecision(prc), true)));
|
||||
}
|
||||
|
||||
network.setInputInfo(info);
|
||||
@@ -155,12 +170,8 @@ CNNNetworkNGraphImpl::CNNNetworkNGraphImpl(const std::shared_ptr<Function>& nGra
|
||||
if (!_new_api) {
|
||||
for (auto& output : _outputData) {
|
||||
// Convert precision into native format. Be consistent with possible conversion to CNNNetwork later.
|
||||
if (output.second->getPrecision() == Precision::I64) {
|
||||
output.second->setPrecision(Precision::I32);
|
||||
} else if (output.second->getPrecision() != Precision::FP32 &&
|
||||
output.second->getPrecision() != Precision::I32) {
|
||||
output.second->setPrecision(Precision::FP32);
|
||||
}
|
||||
output.second->setPrecision(details::convertPrecision(
|
||||
toLegacyType(details::convertPrecision(output.second->getPrecision()), false)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,10 +28,13 @@
|
||||
#include "ngraph/attribute_visitor.hpp"
|
||||
#include "ngraph/function.hpp"
|
||||
#include "ngraph/node.hpp"
|
||||
#include "ngraph/type/element_type.hpp"
|
||||
|
||||
namespace InferenceEngine {
|
||||
namespace details {
|
||||
|
||||
ngraph::element::Type toLegacyType(const ngraph::element::Type& ngraph_type, bool input);
|
||||
|
||||
IE_SUPPRESS_DEPRECATED_START
|
||||
|
||||
/**
|
||||
|
||||
@@ -450,28 +450,12 @@ public:
|
||||
|
||||
ie::CNNNetwork ReadNetwork(const std::string& modelPath, const std::string& binPath) const override {
|
||||
OV_ITT_SCOPE(FIRST_INFERENCE, ov::itt::domains::IE_RT, "CoreImpl::ReadNetwork from file");
|
||||
auto cnnNet = InferenceEngine::details::ReadNetwork(modelPath, binPath, extensions);
|
||||
OPENVINO_ASSERT(cnnNet.getFunction() || !newAPI, "Cannot read IR v7 from OpenVINO 2.0 API");
|
||||
if (!newAPI)
|
||||
return cnnNet;
|
||||
|
||||
return InferenceEngine::CNNNetwork(std::make_shared<InferenceEngine::details::CNNNetworkNGraphImpl>(
|
||||
cnnNet.getFunction(),
|
||||
std::vector<InferenceEngine::IExtensionPtr>{},
|
||||
newAPI));
|
||||
return InferenceEngine::details::ReadNetwork(modelPath, binPath, extensions, newAPI);
|
||||
}
|
||||
|
||||
ie::CNNNetwork ReadNetwork(const std::string& model, const ie::Blob::CPtr& weights) const override {
|
||||
OV_ITT_SCOPE(FIRST_INFERENCE, ov::itt::domains::IE_RT, "CoreImpl::ReadNetwork from memory");
|
||||
auto cnnNet = InferenceEngine::details::ReadNetwork(model, weights, extensions);
|
||||
OPENVINO_ASSERT(cnnNet.getFunction() || !newAPI, "Cannot read IR v7 from OpenVINO 2.0 API");
|
||||
if (!newAPI)
|
||||
return cnnNet;
|
||||
|
||||
return InferenceEngine::CNNNetwork(std::make_shared<InferenceEngine::details::CNNNetworkNGraphImpl>(
|
||||
cnnNet.getFunction(),
|
||||
std::vector<InferenceEngine::IExtensionPtr>{},
|
||||
newAPI));
|
||||
return InferenceEngine::details::ReadNetwork(model, weights, extensions, newAPI);
|
||||
}
|
||||
|
||||
// TODO: In future this method can be added to ICore interface
|
||||
|
||||
@@ -7,14 +7,32 @@
|
||||
#include <fstream>
|
||||
#include <istream>
|
||||
#include <map>
|
||||
#include <memory>
|
||||
#include <mutex>
|
||||
#include <string>
|
||||
|
||||
#include "cnn_network_ngraph_impl.hpp"
|
||||
#include "cpp/ie_cnn_network.h"
|
||||
#include "details/ie_so_pointer.hpp"
|
||||
#include "file_utils.h"
|
||||
#include "frontend_manager/frontend_manager.hpp"
|
||||
#include "ie_api.h"
|
||||
#include "ie_common.h"
|
||||
#include "ie_icnn_network.hpp"
|
||||
#include "ie_input_info.hpp"
|
||||
#include "ie_ir_version.hpp"
|
||||
#include "ie_itt.hpp"
|
||||
#include "ie_reader.hpp"
|
||||
#include "ngraph/function.hpp"
|
||||
#include "ngraph/type/element_type.hpp"
|
||||
#include "ngraph/variant.hpp"
|
||||
#include "openvino/core/deprecated.hpp"
|
||||
#include "openvino/core/except.hpp"
|
||||
#include "openvino/core/preprocess/input_network_info.hpp"
|
||||
#include "openvino/core/preprocess/input_tensor_info.hpp"
|
||||
#include "openvino/core/preprocess/pre_post_process.hpp"
|
||||
#include "openvino/core/type/element_type.hpp"
|
||||
#include "transformations/rt_info/old_api_map_attribute.hpp"
|
||||
|
||||
namespace InferenceEngine {
|
||||
|
||||
@@ -109,7 +127,6 @@ void registerReaders() {
|
||||
if (initialized)
|
||||
return;
|
||||
|
||||
// TODO: Read readers info from XML
|
||||
auto create_if_exists = [](const std::string name, const std::string library_name) {
|
||||
ov::util::FilePath libraryName = ov::util::to_file_path(library_name);
|
||||
ov::util::FilePath readersLibraryPath =
|
||||
@@ -138,6 +155,7 @@ void assertIfIRv7LikeModel(std::istream& modelStream) {
|
||||
|
||||
for (auto&& kvp : readers) {
|
||||
Reader::Ptr reader = kvp.second;
|
||||
// if we have reader for IR v7
|
||||
if (reader->getName() == "IRv7") {
|
||||
return;
|
||||
}
|
||||
@@ -162,20 +180,16 @@ ov::Extensions get_extensions_map(const std::vector<InferenceEngine::IExtensionP
|
||||
return extensions;
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CNNNetwork details::ReadNetwork(const std::string& modelPath,
|
||||
const std::string& binPath,
|
||||
const std::vector<IExtensionPtr>& exts) {
|
||||
// Register readers if it is needed
|
||||
registerReaders();
|
||||
|
||||
CNNNetwork load_ir_v7_network(const std::string& modelPath,
|
||||
const std::string& binPath,
|
||||
const std::vector<IExtensionPtr>& exts) {
|
||||
// Fix unicode name
|
||||
#if defined(OPENVINO_ENABLE_UNICODE_PATH_SUPPORT) && defined(_WIN32)
|
||||
std::wstring model_path = ov::util::string_to_wstring(modelPath.c_str());
|
||||
#else
|
||||
std::string model_path = modelPath;
|
||||
#endif
|
||||
|
||||
// Try to open model file
|
||||
std::ifstream modelStream(model_path, std::ios::binary);
|
||||
if (!modelStream.is_open())
|
||||
@@ -183,7 +197,6 @@ CNNNetwork details::ReadNetwork(const std::string& modelPath,
|
||||
|
||||
assertIfIRv7LikeModel(modelStream);
|
||||
|
||||
// TODO: this code is needed only by V7 IR reader. So we need to remove it in future.
|
||||
auto fileExt = modelPath.substr(modelPath.find_last_of(".") + 1);
|
||||
for (auto it = readers.lower_bound(fileExt); it != readers.upper_bound(fileExt); it++) {
|
||||
auto reader = it->second;
|
||||
@@ -240,6 +253,182 @@ CNNNetwork details::ReadNetwork(const std::string& modelPath,
|
||||
}
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
CNNNetwork convert_to_cnnnetwork(std::shared_ptr<ngraph::Function>& function,
|
||||
const std::vector<IExtensionPtr>& exts,
|
||||
bool newAPI) {
|
||||
auto& rt_info = function->get_rt_info();
|
||||
const auto it = rt_info.find("version");
|
||||
const bool is_ir = it != rt_info.end();
|
||||
|
||||
// only for IR cases we need preprocessing or postprocessing steps
|
||||
if (is_ir) {
|
||||
using namespace ov::preprocess;
|
||||
PrePostProcessor prepost;
|
||||
|
||||
auto iv_version_impl = std::dynamic_pointer_cast<ngraph::VariantImpl<int64_t>>(it->second);
|
||||
OPENVINO_ASSERT(iv_version_impl != nullptr, "Failed to extract IR version from 'version' attribute");
|
||||
const int64_t ir_version = iv_version_impl->get();
|
||||
|
||||
if (ir_version == 10 && newAPI) {
|
||||
const auto inputs = function->inputs();
|
||||
for (size_t i = 0; i < inputs.size(); ++i) {
|
||||
const auto ngraph_type = inputs[i].get_element_type();
|
||||
const auto legacy_type = details::toLegacyType(ngraph_type, true);
|
||||
prepost.input(ov::preprocess::InputInfo(i)
|
||||
.tensor(InputTensorInfo().set_element_type(legacy_type))
|
||||
.preprocess(PreProcessSteps()
|
||||
// TODO: remove explicit type
|
||||
.convert_element_type(ngraph_type)));
|
||||
}
|
||||
|
||||
const auto outputs = function->outputs();
|
||||
for (size_t i = 0; i < outputs.size(); ++i) {
|
||||
const auto ngraph_type = outputs[i].get_element_type();
|
||||
const auto legacy_type = details::toLegacyType(ngraph_type, false);
|
||||
|
||||
prepost.output(OutputInfo(i)
|
||||
.postprocess(PostProcessSteps().convert_element_type())
|
||||
.tensor(OutputTensorInfo().set_element_type(legacy_type)));
|
||||
}
|
||||
|
||||
function = prepost.build(function);
|
||||
} else if (ir_version == 11 && !newAPI) {
|
||||
const std::string& old_api_map_key = ov::OldApiMap::get_type_info_static();
|
||||
|
||||
auto& parameters = function->get_parameters();
|
||||
for (size_t i = 0; i < parameters.size(); ++i) {
|
||||
const auto& parameter = parameters[i];
|
||||
ov::RTMap& rtInfo = parameter->get_rt_info();
|
||||
const auto it = rtInfo.find(old_api_map_key);
|
||||
if (it == rtInfo.end())
|
||||
continue;
|
||||
|
||||
const auto old_api_map_attr = std::dynamic_pointer_cast<ov::OldApiMap>(it->second);
|
||||
OPENVINO_ASSERT(old_api_map_attr != nullptr, "Failed to cast to ov::OldApiMap");
|
||||
const auto old_api_map_attr_val = old_api_map_attr->get();
|
||||
auto old_api_type = old_api_map_attr_val.get_type();
|
||||
const auto old_api_transpose_args = old_api_map_attr_val.get_order();
|
||||
|
||||
OPENVINO_ASSERT(!old_api_type.is_dynamic(), "Old API map does not support dynamic type");
|
||||
// if no differences between IR v10 and IR v11, add identity convert which will be optimized out
|
||||
if (old_api_type == ov::element::undefined)
|
||||
old_api_type = parameter->get_element_type();
|
||||
|
||||
std::stringstream tensorLayout, networkLayout;
|
||||
for (size_t i = 0; i < old_api_transpose_args.size(); ++i) {
|
||||
tensorLayout << i;
|
||||
networkLayout << old_api_transpose_args[i];
|
||||
}
|
||||
|
||||
PreProcessSteps steps;
|
||||
// TODO: remove explicit type
|
||||
steps.convert_element_type(parameter->get_element_type());
|
||||
// TODO: move steps directly to builder once we allow Layout() -> Layout transpose
|
||||
if (!old_api_transpose_args.empty())
|
||||
steps.convert_layout();
|
||||
|
||||
prepost.input(
|
||||
ov::preprocess::InputInfo(i)
|
||||
.tensor(
|
||||
InputTensorInfo().set_element_type(old_api_type).set_layout(ov::Layout(tensorLayout.str())))
|
||||
.preprocess(std::move(steps))
|
||||
.network(InputNetworkInfo().set_layout(ov::Layout(networkLayout.str()))));
|
||||
|
||||
// remove old api once we applied it
|
||||
rtInfo.erase(it);
|
||||
}
|
||||
|
||||
auto& resuls = function->get_results();
|
||||
for (size_t i = 0; i < resuls.size(); ++i) {
|
||||
const auto& result = resuls[i];
|
||||
ov::RTMap& rtInfo = result->get_rt_info();
|
||||
const auto it = rtInfo.find(old_api_map_key);
|
||||
if (it == rtInfo.end())
|
||||
continue;
|
||||
|
||||
const auto old_api_map_attr = std::dynamic_pointer_cast<ov::OldApiMap>(it->second);
|
||||
OPENVINO_ASSERT(old_api_map_attr != nullptr, "Failed to cast to ov::OldApiMap");
|
||||
const auto old_api_map_attr_val = old_api_map_attr->get();
|
||||
auto old_api_type = old_api_map_attr_val.get_type();
|
||||
const auto old_api_transpose_args = old_api_map_attr_val.get_order();
|
||||
|
||||
OPENVINO_ASSERT(!old_api_type.is_dynamic(), "Old API map does not support dynamic type");
|
||||
// if no differences between IR v10 and IR v11, add identity convert which will be optimized out
|
||||
if (old_api_type == ov::element::undefined)
|
||||
old_api_type = result->get_element_type();
|
||||
|
||||
std::stringstream tensorLayout, networkLayout;
|
||||
for (size_t i = 0; i < old_api_transpose_args.size(); ++i) {
|
||||
networkLayout << i;
|
||||
tensorLayout << old_api_transpose_args[i];
|
||||
}
|
||||
|
||||
prepost.output(OutputInfo(i)
|
||||
.network(OutputNetworkInfo().set_layout(ov::Layout(networkLayout.str())))
|
||||
.postprocess(PostProcessSteps().convert_layout().convert_element_type())
|
||||
.tensor(OutputTensorInfo()
|
||||
.set_element_type(old_api_type)
|
||||
.set_layout(ov::Layout(tensorLayout.str()))));
|
||||
|
||||
// remove old api once we applied it
|
||||
rtInfo.erase(it);
|
||||
}
|
||||
|
||||
function = prepost.build(function);
|
||||
|
||||
// TODO: keep information about layout once we have an ability to
|
||||
// apply permutation to layout
|
||||
|
||||
// restore layout information
|
||||
for (const auto& parameter : function->get_parameters()) {
|
||||
parameter->set_layout({});
|
||||
}
|
||||
for (const auto& result : function->get_results()) {
|
||||
result->set_layout({});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// need to remove information about IR version since it's needed only on read stage
|
||||
if (is_ir) {
|
||||
rt_info.erase(it);
|
||||
}
|
||||
|
||||
OPENVINO_SUPPRESS_DEPRECATED_START
|
||||
return CNNNetwork(std::make_shared<details::CNNNetworkNGraphImpl>(function, exts, newAPI));
|
||||
OPENVINO_SUPPRESS_DEPRECATED_END
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
||||
CNNNetwork details::ReadNetwork(const std::string& modelPath,
|
||||
const std::string& binPath,
|
||||
const std::vector<IExtensionPtr>& exts,
|
||||
bool newAPI) {
|
||||
// IR v7 obsolete code
|
||||
{
|
||||
// Register readers if it is needed
|
||||
registerReaders();
|
||||
auto cnnnetwork = load_ir_v7_network(modelPath, binPath, exts);
|
||||
|
||||
OPENVINO_SUPPRESS_DEPRECATED_START
|
||||
if (static_cast<ICNNNetwork::Ptr>(cnnnetwork) != nullptr) {
|
||||
OPENVINO_ASSERT(!newAPI, "Cannot read IR v7 from OpenVINO 2.0 API");
|
||||
return cnnnetwork;
|
||||
}
|
||||
IE_SUPPRESS_DEPRECATED_END
|
||||
}
|
||||
|
||||
// Fix unicode name
|
||||
#if defined(OPENVINO_ENABLE_UNICODE_PATH_SUPPORT) && defined(_WIN32)
|
||||
std::wstring model_path = ov::util::string_to_wstring(modelPath.c_str());
|
||||
#else
|
||||
std::string model_path = modelPath;
|
||||
#endif
|
||||
|
||||
// Try to load with FrontEndManager
|
||||
auto& manager = get_frontend_manager();
|
||||
ngraph::frontend::FrontEnd::Ptr FE;
|
||||
@@ -265,8 +454,10 @@ CNNNetwork details::ReadNetwork(const std::string& modelPath,
|
||||
|
||||
if (inputModel) {
|
||||
auto ngFunc = FE->convert(inputModel);
|
||||
return CNNNetwork(ngFunc, exts);
|
||||
return convert_to_cnnnetwork(ngFunc, exts, newAPI);
|
||||
}
|
||||
|
||||
const auto fileExt = modelPath.substr(modelPath.find_last_of(".") + 1);
|
||||
IE_THROW(NetworkNotRead) << "Unable to read the model: " << modelPath
|
||||
<< " Please check that model format: " << fileExt
|
||||
<< " is supported and the model is correct.";
|
||||
@@ -274,20 +465,26 @@ CNNNetwork details::ReadNetwork(const std::string& modelPath,
|
||||
|
||||
CNNNetwork details::ReadNetwork(const std::string& model,
|
||||
const Blob::CPtr& weights,
|
||||
const std::vector<IExtensionPtr>& exts) {
|
||||
// Register readers if it is needed
|
||||
registerReaders();
|
||||
const std::vector<IExtensionPtr>& exts,
|
||||
bool newAPI) {
|
||||
std::istringstream modelStringStream(model);
|
||||
std::istream& modelStream = modelStringStream;
|
||||
|
||||
assertIfIRv7LikeModel(modelStream);
|
||||
// IR v7 obsolete code
|
||||
{
|
||||
// Register readers if it is needed
|
||||
registerReaders();
|
||||
|
||||
for (auto it = readers.begin(); it != readers.end(); it++) {
|
||||
auto reader = it->second;
|
||||
if (reader->supportModel(modelStream)) {
|
||||
if (weights)
|
||||
return reader->read(modelStream, weights, exts);
|
||||
return reader->read(modelStream, exts);
|
||||
assertIfIRv7LikeModel(modelStream);
|
||||
|
||||
for (auto it = readers.begin(); it != readers.end(); it++) {
|
||||
auto reader = it->second;
|
||||
if (reader->supportModel(modelStream)) {
|
||||
OPENVINO_ASSERT(!newAPI, "Cannot read IR v7 from OpenVINO 2.0 API");
|
||||
if (weights)
|
||||
return reader->read(modelStream, weights, exts);
|
||||
return reader->read(modelStream, exts);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -312,7 +509,7 @@ CNNNetwork details::ReadNetwork(const std::string& model,
|
||||
inputModel = FE->load(params);
|
||||
if (inputModel) {
|
||||
auto ngFunc = FE->convert(inputModel);
|
||||
return CNNNetwork(ngFunc, exts);
|
||||
return convert_to_cnnnetwork(ngFunc, exts, newAPI);
|
||||
}
|
||||
|
||||
IE_THROW(NetworkNotRead)
|
||||
|
||||
@@ -19,11 +19,13 @@ namespace details {
|
||||
* @param binPath path to bin file, if path is empty, will try to read bin file with the same name as xml and
|
||||
* if bin file with the same name was not found, will load IR without weights.
|
||||
* @param exts vector with extensions
|
||||
* @param newAPI Whether this function is called from OpenVINO 2.0 API
|
||||
* @return CNNNetwork
|
||||
*/
|
||||
CNNNetwork ReadNetwork(const std::string& modelPath,
|
||||
const std::string& binPath,
|
||||
const std::vector<IExtensionPtr>& exts);
|
||||
const std::vector<IExtensionPtr>& exts,
|
||||
bool newAPI);
|
||||
/**
|
||||
* @brief Reads IR xml and bin (with the same name) files
|
||||
* @param model string with IR
|
||||
@@ -32,9 +34,13 @@ CNNNetwork ReadNetwork(const std::string& modelPath,
|
||||
* @note Reading ONNX models doesn't support loading weights from data blobs.
|
||||
If you are using an ONNX model with external data files, please use the
|
||||
ReadNetwork function overload which takes a filesystem path to the model.
|
||||
* @param newAPI Whether this function is called from OpenVINO 2.0 API
|
||||
* @return CNNNetwork
|
||||
*/
|
||||
CNNNetwork ReadNetwork(const std::string& model, const Blob::CPtr& weights, const std::vector<IExtensionPtr>& exts);
|
||||
CNNNetwork ReadNetwork(const std::string& model,
|
||||
const Blob::CPtr& weights,
|
||||
const std::vector<IExtensionPtr>& exts,
|
||||
bool newAPI);
|
||||
|
||||
} // namespace details
|
||||
} // namespace InferenceEngine
|
||||
@@ -57,7 +57,7 @@ StatusCode CNNNetReaderImpl::ReadNetwork(const void* model, size_t size, Respons
|
||||
xmlDoc = std::make_shared<pugi::xml_document>();
|
||||
pugi::xml_parse_result res = xmlDoc->load_buffer(model, size);
|
||||
if (res.status != pugi::status_ok) {
|
||||
return DescriptionBuffer(resp) << res.description() << "at offset " << res.offset;
|
||||
return DescriptionBuffer(resp) << res.description() << " at offset " << res.offset;
|
||||
}
|
||||
StatusCode ret = ReadNetwork();
|
||||
if (ret != OK) {
|
||||
|
||||
@@ -33,7 +33,7 @@ CNNNetwork IRReader::read(std::istream& model, const Blob::CPtr& weights, const
|
||||
pugi::xml_document xmlDoc;
|
||||
pugi::xml_parse_result res = xmlDoc.load(model);
|
||||
if (res.status != pugi::status_ok) {
|
||||
IE_THROW() << res.description() << "at offset " << res.offset;
|
||||
IE_THROW() << res.description() << " at offset " << res.offset;
|
||||
}
|
||||
pugi::xml_node root = xmlDoc.document_element();
|
||||
|
||||
|
||||
@@ -19,6 +19,7 @@ set(LINK_LIBRARIES
|
||||
inference_engine_snippets
|
||||
offline_transformations
|
||||
inference_engine
|
||||
frontend_manager
|
||||
pugixml::static
|
||||
)
|
||||
|
||||
|
||||
+313
-46
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <cstdint>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <string>
|
||||
@@ -10,20 +11,56 @@
|
||||
#include <inference_engine.hpp>
|
||||
#include <transformations/rt_info/fused_names_attribute.hpp>
|
||||
#include <transformations/rt_info/old_api_map_attribute.hpp>
|
||||
#include "frontend_manager/frontend_manager.hpp"
|
||||
#include "graph_comparator.hpp"
|
||||
#include "ie_blob.h"
|
||||
#include "ngraph/node.hpp"
|
||||
#include "ngraph/op/parameter.hpp"
|
||||
#include "ngraph/shape.hpp"
|
||||
#include "ngraph/type/element_type.hpp"
|
||||
#include "ngraph/variant.hpp"
|
||||
#include "openvino/runtime/core.hpp"
|
||||
#include <ngraph/opsets/opset8.hpp>
|
||||
|
||||
using namespace ngraph;
|
||||
|
||||
TEST(RTInfoDeserialization, NodeV10) {
|
||||
class RTInfoDeserialization : public testing::Test {
|
||||
protected:
|
||||
std::shared_ptr<ngraph::Function> getWithIRFrontend(const std::string& model) {
|
||||
std::istringstream modelStringStream(model);
|
||||
std::istream& modelStream = modelStringStream;
|
||||
|
||||
ngraph::frontend::FrontEnd::Ptr FE;
|
||||
ngraph::frontend::InputModel::Ptr inputModel;
|
||||
|
||||
ov::VariantVector params{ov::make_variant(&modelStream)};
|
||||
|
||||
FE = manager.load_by_model(params);
|
||||
if (FE)
|
||||
inputModel = FE->load(params);
|
||||
|
||||
if (inputModel)
|
||||
return FE->convert(inputModel);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
ngraph::frontend::FrontEndManager manager;
|
||||
};
|
||||
|
||||
TEST_F(RTInfoDeserialization, NodeV10) {
|
||||
std::string model = R"V0G0N(
|
||||
<net name="Network" version="10">
|
||||
<layers>
|
||||
<layer name="in1" type="Parameter" id="0" version="opset8">
|
||||
<data element_type="f32" shape="1,3,22,22"/>
|
||||
<data element_type="f16" shape="1,3,22,22"/>
|
||||
<rt_info>
|
||||
<attribute name="fused_names" version="0" value="in1"/>
|
||||
<attribute name="old_api_map" version="0" order="0,2,3,1" element_type="f16"/>
|
||||
</rt_info>
|
||||
<output>
|
||||
<port id="0" precision="FP32">
|
||||
<port id="0" precision="FP16" names="input_tensor">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
@@ -37,7 +74,7 @@ TEST(RTInfoDeserialization, NodeV10) {
|
||||
<attribute name="fused_names" version="0" value="Round1,Round2"/>
|
||||
</rt_info>
|
||||
<input>
|
||||
<port id="1" precision="FP32">
|
||||
<port id="1" precision="FP16">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
@@ -45,7 +82,7 @@ TEST(RTInfoDeserialization, NodeV10) {
|
||||
</port>
|
||||
</input>
|
||||
<output>
|
||||
<port id="2" precision="FP32">
|
||||
<port id="2" precision="FP16" names="output_tensor">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
@@ -55,7 +92,7 @@ TEST(RTInfoDeserialization, NodeV10) {
|
||||
</layer>
|
||||
<layer name="output" type="Result" id="2" version="opset8">
|
||||
<input>
|
||||
<port id="0" precision="FP32">
|
||||
<port id="0" precision="FP16">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
@@ -70,13 +107,15 @@ TEST(RTInfoDeserialization, NodeV10) {
|
||||
</edges>
|
||||
</net>
|
||||
)V0G0N";
|
||||
auto core = InferenceEngine::Core();
|
||||
auto net = core.ReadNetwork(model, InferenceEngine::Blob::Ptr());
|
||||
auto f = net.getFunction();
|
||||
auto f = getWithIRFrontend(model);
|
||||
ASSERT_NE(nullptr, f);
|
||||
|
||||
auto check_rt_info = [](const RTMap & info) {
|
||||
const std::string & key = VariantWrapper<ngraph::FusedNames>::get_type_info_static();
|
||||
ASSERT_FALSE(info.count(key));
|
||||
EXPECT_FALSE(info.count(key));
|
||||
|
||||
const std::string & key_old_api = ov::OldApiMap::get_type_info_static();
|
||||
EXPECT_FALSE(info.count(key_old_api));
|
||||
};
|
||||
|
||||
auto check_version = [](const std::shared_ptr<ov::Function>& f) {
|
||||
@@ -94,16 +133,71 @@ TEST(RTInfoDeserialization, NodeV10) {
|
||||
auto result = f->get_results()[0];
|
||||
auto round = result->get_input_node_ptr(0);
|
||||
check_rt_info(round->get_rt_info());
|
||||
|
||||
// read IR v10 with old API
|
||||
{
|
||||
InferenceEngine::Core core;
|
||||
auto f_10 = core.ReadNetwork(model, InferenceEngine::Blob::CPtr());
|
||||
ASSERT_NE(nullptr, f_10.getFunction());
|
||||
|
||||
auto res = compare_functions(f, f_10.getFunction());
|
||||
EXPECT_TRUE(res.first) << res.second;
|
||||
}
|
||||
|
||||
// read IR v10 with new API and check that CNNNetwork precision conversions are applied
|
||||
{
|
||||
ngraph::Shape shape{1, 3, 22, 22};
|
||||
auto type = ngraph::element::f32;
|
||||
auto param = std::make_shared<ngraph::opset8::Parameter>(type, shape);
|
||||
param->set_friendly_name("in1");
|
||||
param->get_output_tensor(0).set_names({"input_tensor"});
|
||||
|
||||
auto convert_param = std::make_shared<opset8::Convert>(param, ngraph::element::f16);
|
||||
convert_param->get_output_tensor(0).set_names({"input_tensor/convert_element_type"});
|
||||
|
||||
auto round = std::make_shared<opset8::Round>(convert_param,
|
||||
ngraph::opset8::Round::RoundMode::HALF_TO_EVEN);
|
||||
round->set_friendly_name("Round");
|
||||
// TODO: why it has this name?
|
||||
round->get_output_tensor(0).set_names({"output_tensor"});
|
||||
|
||||
auto convert_result = std::make_shared<opset8::Convert>(round, type);
|
||||
convert_result->set_friendly_name("Round/convert_element_type");
|
||||
convert_result->get_output_tensor(0).set_names({"output_tensor"});
|
||||
|
||||
auto result = std::make_shared<opset8::Result>(convert_result);
|
||||
result->set_friendly_name("output");
|
||||
|
||||
auto f_10_ref = std::make_shared<ngraph::Function>(ngraph::ResultVector{result},
|
||||
ngraph::ParameterVector{param});
|
||||
f_10_ref->set_friendly_name("Network");
|
||||
|
||||
ov::runtime::Core core;
|
||||
auto f_10_core = core.read_model(model, InferenceEngine::Blob::CPtr());
|
||||
ASSERT_NE(nullptr, f_10_core);
|
||||
|
||||
auto& rt_info = f_10_core->get_rt_info();
|
||||
EXPECT_EQ(0, rt_info.count("version"));
|
||||
|
||||
const auto fc = FunctionsComparator::with_default()
|
||||
.enable(FunctionsComparator::ATTRIBUTES)
|
||||
.enable(FunctionsComparator::PRECISIONS)
|
||||
.enable(FunctionsComparator::RUNTIME_KEYS)
|
||||
.enable(FunctionsComparator::NAMES)
|
||||
.enable(FunctionsComparator::CONST_VALUES);
|
||||
auto res = fc.compare(f_10_core, f_10_ref);
|
||||
EXPECT_TRUE(res.valid) << res.message;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(RTInfoDeserialization, InputAndOutputV10) {
|
||||
TEST_F(RTInfoDeserialization, InputAndOutputV10) {
|
||||
std::string model = R"V0G0N(
|
||||
<net name="Network" version="10">
|
||||
<layers>
|
||||
<layer name="in1" type="Parameter" id="0" version="opset8">
|
||||
<data element_type="f32" shape="1,3,22,22"/>
|
||||
<data element_type="i64" shape="1,3,22,22"/>
|
||||
<output>
|
||||
<port id="0" precision="FP32">
|
||||
<port id="0" precision="I64" names="input_tensor">
|
||||
<rt_info>
|
||||
<attribute name="fused_names" version="0" value="test1,test2"/>
|
||||
</rt_info>
|
||||
@@ -136,7 +230,7 @@ TEST(RTInfoDeserialization, InputAndOutputV10) {
|
||||
</port>
|
||||
</input>
|
||||
<output>
|
||||
<port id="2" precision="FP32">
|
||||
<port id="2" precision="I64" names="output_tensor">
|
||||
<rt_info>
|
||||
<attribute name="fused_names" version="0" value="test4,test5"/>
|
||||
</rt_info>
|
||||
@@ -149,7 +243,7 @@ TEST(RTInfoDeserialization, InputAndOutputV10) {
|
||||
</layer>
|
||||
<layer name="output" type="Result" id="2" version="opset8">
|
||||
<input>
|
||||
<port id="0" precision="FP32">
|
||||
<port id="0" precision="I64">
|
||||
<rt_info>
|
||||
<attribute name="fused_names" version="0" value="test5,test6"/>
|
||||
</rt_info>
|
||||
@@ -168,9 +262,8 @@ TEST(RTInfoDeserialization, InputAndOutputV10) {
|
||||
</edges>
|
||||
</net>
|
||||
)V0G0N";
|
||||
auto core = InferenceEngine::Core();
|
||||
auto net = core.ReadNetwork(model, InferenceEngine::Blob::Ptr());
|
||||
auto f = net.getFunction();
|
||||
auto f = getWithIRFrontend(model);
|
||||
ASSERT_NE(nullptr, f);
|
||||
|
||||
auto check_rt_info = [](const RTMap & info) {
|
||||
const std::string & key = VariantWrapper<ngraph::FusedNames>::get_type_info_static();
|
||||
@@ -196,20 +289,71 @@ TEST(RTInfoDeserialization, InputAndOutputV10) {
|
||||
check_rt_info(add->input(0).get_rt_info());
|
||||
check_rt_info(add->input(1).get_rt_info());
|
||||
check_rt_info(add->output(0).get_rt_info());
|
||||
|
||||
// read IR v10 with old API
|
||||
{
|
||||
InferenceEngine::Core core;
|
||||
auto f_10 = core.ReadNetwork(model, InferenceEngine::Blob::CPtr());
|
||||
ASSERT_NE(nullptr, f_10.getFunction());
|
||||
|
||||
auto res = compare_functions(f, f_10.getFunction());
|
||||
EXPECT_TRUE(res.first) << res.second;
|
||||
}
|
||||
|
||||
// read IR v10 with new API and check that CNNNetwork precision conversions are applied
|
||||
{
|
||||
const ngraph::Shape shape{1, 3, 22, 22};
|
||||
const auto type = ngraph::element::i64;
|
||||
auto param = std::make_shared<ngraph::opset8::Parameter>(type, shape);
|
||||
param->set_friendly_name("in1");
|
||||
param->get_output_tensor(0).set_names({"input_tensor"});
|
||||
|
||||
auto sum = std::make_shared<opset8::Add>(param, param);
|
||||
sum->set_friendly_name("sum");
|
||||
// TODO: why it has this name?
|
||||
sum->get_output_tensor(0).set_names({"output_tensor"});
|
||||
|
||||
auto convert_result = std::make_shared<opset8::Convert>(sum, ngraph::element::i32);
|
||||
convert_result->set_friendly_name("sum/convert_element_type");
|
||||
convert_result->get_output_tensor(0).set_names({"output_tensor"});
|
||||
|
||||
auto result = std::make_shared<opset8::Result>(convert_result);
|
||||
result->set_friendly_name("output");
|
||||
|
||||
auto f_10_ref = std::make_shared<ngraph::Function>(ngraph::ResultVector{result},
|
||||
ngraph::ParameterVector{param});
|
||||
f_10_ref->set_friendly_name("Network");
|
||||
|
||||
ov::runtime::Core core;
|
||||
auto f_10_core = core.read_model(model, InferenceEngine::Blob::CPtr());
|
||||
ASSERT_NE(nullptr, f_10_core);
|
||||
|
||||
auto& rt_info = f_10_core->get_rt_info();
|
||||
EXPECT_EQ(0, rt_info.count("version"));
|
||||
|
||||
const auto fc = FunctionsComparator::with_default()
|
||||
.enable(FunctionsComparator::ATTRIBUTES)
|
||||
.enable(FunctionsComparator::PRECISIONS)
|
||||
.enable(FunctionsComparator::RUNTIME_KEYS)
|
||||
.enable(FunctionsComparator::NAMES)
|
||||
.enable(FunctionsComparator::CONST_VALUES);
|
||||
auto res = fc.compare(f_10_core, f_10_ref);
|
||||
EXPECT_TRUE(res.valid) << res.message;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(RTInfoDeserialization, NodeV11) {
|
||||
TEST_F(RTInfoDeserialization, NodeV11) {
|
||||
std::string model = R"V0G0N(
|
||||
<net name="Network" version="11">
|
||||
<layers>
|
||||
<layer name="in1" type="Parameter" id="0" version="opset8">
|
||||
<data element_type="f32" shape="1,3,22,22"/>
|
||||
<data element_type="f32" shape="1,22,22,3"/>
|
||||
<rt_info>
|
||||
<attribute name="old_api_map" version="0" order="0,2,3,1" element_type="f16"/>
|
||||
<attribute name="fused_names" version="0" value="in1"/>
|
||||
<attribute name="old_api_map" version="0" order="0,2,3,1" element_type="f32"/>
|
||||
</rt_info>
|
||||
<output>
|
||||
<port id="0" precision="FP32">
|
||||
<port id="0" precision="FP32" names="input_tensor">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
@@ -231,7 +375,7 @@ TEST(RTInfoDeserialization, NodeV11) {
|
||||
</port>
|
||||
</input>
|
||||
<output>
|
||||
<port id="2" precision="FP32">
|
||||
<port id="2" precision="FP32" names="output_tensor">
|
||||
<dim>1</dim>
|
||||
<dim>3</dim>
|
||||
<dim>22</dim>
|
||||
@@ -241,7 +385,7 @@ TEST(RTInfoDeserialization, NodeV11) {
|
||||
</layer>
|
||||
<layer name="output" type="Result" id="2" version="opset8">
|
||||
<rt_info>
|
||||
<attribute name="old_api_map" version="0" order="0,3,1,2" element_type="undefined"/>
|
||||
<attribute name="old_api_map" version="0" order="0,3,1,2" element_type="f16"/>
|
||||
</rt_info>
|
||||
<input>
|
||||
<port id="0" precision="FP32">
|
||||
@@ -259,16 +403,15 @@ TEST(RTInfoDeserialization, NodeV11) {
|
||||
</edges>
|
||||
</net>
|
||||
)V0G0N";
|
||||
auto core = InferenceEngine::Core();
|
||||
auto net = core.ReadNetwork(model, InferenceEngine::Blob::Ptr());
|
||||
auto f = net.getFunction();
|
||||
auto f = getWithIRFrontend(model);
|
||||
ASSERT_NE(nullptr, f);
|
||||
|
||||
auto check_fused_names = [](const RTMap & info, const std::string & names) {
|
||||
const std::string & key = VariantWrapper<ngraph::FusedNames>::get_type_info_static();
|
||||
ASSERT_TRUE(info.count(key));
|
||||
auto fused_names_attr = std::dynamic_pointer_cast<VariantWrapper<ngraph::FusedNames>>(info.at(key));
|
||||
ASSERT_TRUE(fused_names_attr);
|
||||
ASSERT_EQ(fused_names_attr->get().getNames(), names);
|
||||
EXPECT_EQ(fused_names_attr->get().getNames(), names);
|
||||
};
|
||||
|
||||
auto check_old_api_map = [](const RTMap & info, const std::vector<uint64_t> & order, const ngraph::element::Type& type) {
|
||||
@@ -277,40 +420,138 @@ TEST(RTInfoDeserialization, NodeV11) {
|
||||
auto old_api_map_attr = std::dynamic_pointer_cast<ov::OldApiMap>(info.at(old_api_map_key));
|
||||
ASSERT_TRUE(old_api_map_attr);
|
||||
auto old_api_map_attr_val = old_api_map_attr->get();
|
||||
ASSERT_EQ(old_api_map_attr_val.get_order(), order);
|
||||
ASSERT_EQ(old_api_map_attr_val.get_type(), type);
|
||||
EXPECT_EQ(old_api_map_attr_val.get_order(), order);
|
||||
EXPECT_EQ(old_api_map_attr_val.get_type(), type);
|
||||
};
|
||||
auto check_version = [](const std::shared_ptr<ov::Function>& f) {
|
||||
auto& rt_info = f->get_rt_info();
|
||||
ASSERT_TRUE(rt_info.count("version"));
|
||||
auto version = std::dynamic_pointer_cast<VariantWrapper<int64_t>>(rt_info.at("version"));
|
||||
ASSERT_NE(version, nullptr);
|
||||
ASSERT_EQ(version->get(), 11);
|
||||
EXPECT_EQ(version->get(), 11);
|
||||
};
|
||||
check_version(f);
|
||||
|
||||
auto param = f->get_parameters()[0];
|
||||
check_fused_names(param->get_rt_info(), "in1");
|
||||
check_old_api_map(param->get_rt_info(),
|
||||
std::vector<uint64_t>({0, 2, 3, 1}),
|
||||
ngraph::element::Type_t::f32);
|
||||
std::vector<uint64_t>({0, 2, 3, 1}),
|
||||
ngraph::element::Type_t::f16);
|
||||
|
||||
auto result = f->get_results()[0];
|
||||
auto result = f->get_result();
|
||||
check_old_api_map(result->get_rt_info(),
|
||||
std::vector<uint64_t>({0, 3, 1, 2}),
|
||||
ngraph::element::Type_t::undefined);
|
||||
ngraph::element::Type_t::f16);
|
||||
auto round = result->get_input_node_ptr(0);
|
||||
check_fused_names(round->get_rt_info(), "Round1,Round2");
|
||||
|
||||
// read IR v11 with new API
|
||||
{
|
||||
ov::runtime::Core core;
|
||||
auto f_11 = core.read_model(model, InferenceEngine::Blob::CPtr());
|
||||
ASSERT_NE(nullptr, f_11);
|
||||
|
||||
check_old_api_map(f_11->get_parameters()[0]->get_rt_info(),
|
||||
std::vector<uint64_t>({0, 2, 3, 1}),
|
||||
ngraph::element::Type_t::f16);
|
||||
|
||||
check_old_api_map(f_11->get_result()->get_rt_info(),
|
||||
std::vector<uint64_t>({0, 3, 1, 2}),
|
||||
ngraph::element::Type_t::f16);
|
||||
|
||||
auto res = compare_functions(f, f_11);
|
||||
EXPECT_TRUE(res.first) << res.second;
|
||||
}
|
||||
|
||||
// read IR v11 with old API and check that old_api_map is applied
|
||||
{
|
||||
const ngraph::PartialShape shape{1, 3, 22, 22};
|
||||
auto type = ngraph::element::f16;
|
||||
auto param = std::make_shared<ngraph::opset8::Parameter>(type, shape);
|
||||
param->set_friendly_name("in1");
|
||||
param->get_output_tensor(0).set_names({"input_tensor"});
|
||||
|
||||
auto convert_param = std::make_shared<opset8::Convert>(param, ngraph::element::f32);
|
||||
convert_param->set_friendly_name("in1/convert_element_type");
|
||||
convert_param->get_output_tensor(0).set_names({"input_tensor/convert_element_type"});
|
||||
|
||||
auto constant_param = std::make_shared<opset8::Constant>(ngraph::element::i64, ngraph::Shape{4},
|
||||
std::vector<int64_t>{0, 2, 3, 1});
|
||||
auto transpose_param = std::make_shared<opset8::Transpose>(convert_param, constant_param);
|
||||
transpose_param->set_friendly_name("in1/convert_element_type/convert_layout");
|
||||
transpose_param->get_output_tensor(0).set_names({"input_tensor/convert_element_type/convert_layout"});
|
||||
|
||||
auto round = std::make_shared<opset8::Round>(transpose_param,
|
||||
ngraph::opset8::Round::RoundMode::HALF_TO_EVEN);
|
||||
round->set_friendly_name("Round");
|
||||
// TODO: why it has this name?
|
||||
round->get_output_tensor(0).set_names({"output_tensor"});
|
||||
round->get_rt_info()[VariantWrapper<ngraph::FusedNames>::get_type_info_static()] =
|
||||
std::make_shared<VariantWrapper<ngraph::FusedNames>>(ngraph::FusedNames("Round1,Round2"));
|
||||
|
||||
auto constant_result = std::make_shared<opset8::Constant>(ngraph::element::i64, ngraph::Shape{4},
|
||||
std::vector<int64_t>{0, 3, 1, 2});
|
||||
auto transpose_result = std::make_shared<opset8::Transpose>(round, constant_result);
|
||||
transpose_result->set_friendly_name("Round/convert_layout");
|
||||
|
||||
auto convert_result = std::make_shared<opset8::Convert>(transpose_result, type);
|
||||
convert_result->set_friendly_name("Round/convert_layout/convert_element_type");
|
||||
convert_result->get_output_tensor(0).set_names({"output_tensor"});
|
||||
|
||||
auto result = std::make_shared<opset8::Result>(convert_result);
|
||||
result->set_friendly_name("output");
|
||||
|
||||
auto f_10_ref = std::make_shared<ngraph::Function>(ngraph::ResultVector{result},
|
||||
ngraph::ParameterVector{param});
|
||||
f_10_ref->set_friendly_name("Network");
|
||||
|
||||
InferenceEngine::Core core;
|
||||
auto cnn_core = core.ReadNetwork(model, InferenceEngine::Blob::CPtr());
|
||||
auto f_10_core = cnn_core.getFunction();
|
||||
ASSERT_NE(nullptr, f_10_core);
|
||||
|
||||
auto& rt_info = f_10_core->get_rt_info();
|
||||
EXPECT_EQ(0, rt_info.count("version"));
|
||||
|
||||
const auto fc = FunctionsComparator::with_default()
|
||||
.enable(FunctionsComparator::ATTRIBUTES)
|
||||
.enable(FunctionsComparator::PRECISIONS)
|
||||
.enable(FunctionsComparator::RUNTIME_KEYS)
|
||||
.enable(FunctionsComparator::NAMES)
|
||||
.enable(FunctionsComparator::CONST_VALUES);
|
||||
auto res = fc.compare(f_10_core, f_10_ref);
|
||||
EXPECT_TRUE(res.valid) << res.message;
|
||||
|
||||
EXPECT_EQ(shape, f_10_ref->input().get_partial_shape());
|
||||
EXPECT_EQ(shape, f_10_core->input().get_partial_shape());
|
||||
EXPECT_EQ(shape, f_10_ref->get_output_partial_shape(0));
|
||||
EXPECT_EQ(shape, f_10_core->get_output_partial_shape(0));
|
||||
|
||||
// check that old api map is removed once applied
|
||||
auto check_old_api_rt_info = [](const RTMap & info) {
|
||||
const std::string & key = ov::OldApiMap::get_type_info_static();
|
||||
EXPECT_FALSE(info.count(key));
|
||||
};
|
||||
|
||||
check_old_api_rt_info(f_10_core->get_parameters()[0]->get_rt_info());
|
||||
check_old_api_rt_info(f_10_core->get_result()->get_rt_info());
|
||||
|
||||
// check information about layout
|
||||
EXPECT_TRUE(f_10_core->get_parameters()[0]->get_layout().empty())
|
||||
<< f_10_core->get_parameters()[0]->get_layout().to_string();
|
||||
EXPECT_TRUE(f_10_core->get_results()[0]->get_layout().empty())
|
||||
<< f_10_core->get_results()[0]->get_layout().to_string();
|
||||
}
|
||||
}
|
||||
|
||||
TEST(RTInfoDeserialization, InputAndOutputV11) {
|
||||
TEST_F(RTInfoDeserialization, InputAndOutputV11) {
|
||||
std::string model = R"V0G0N(
|
||||
<net name="Network" version="11">
|
||||
<layers>
|
||||
<layer name="in1" type="Parameter" id="0" version="opset8">
|
||||
<data element_type="f32" shape="1,3,22,22"/>
|
||||
<rt_info>
|
||||
<attribute name="old_api_map" version="0" order="" element_type="u8"/>
|
||||
<attribute name="old_api_map" version="0" order="" element_type="undefined"/>
|
||||
</rt_info>
|
||||
<output>
|
||||
<port id="0" precision="FP32">
|
||||
@@ -358,6 +599,9 @@ TEST(RTInfoDeserialization, InputAndOutputV11) {
|
||||
</output>
|
||||
</layer>
|
||||
<layer name="output" type="Result" id="2" version="opset8">
|
||||
<rt_info>
|
||||
<attribute name="old_api_map" version="0" order="" element_type="undefined"/>
|
||||
</rt_info>
|
||||
<input>
|
||||
<port id="0" precision="FP32">
|
||||
<rt_info>
|
||||
@@ -378,9 +622,8 @@ TEST(RTInfoDeserialization, InputAndOutputV11) {
|
||||
</edges>
|
||||
</net>
|
||||
)V0G0N";
|
||||
auto core = InferenceEngine::Core();
|
||||
auto net = core.ReadNetwork(model, InferenceEngine::Blob::Ptr());
|
||||
auto f = net.getFunction();
|
||||
auto f = getWithIRFrontend(model);
|
||||
ASSERT_NE(nullptr, f);
|
||||
|
||||
auto check_version = [](const std::shared_ptr<ov::Function>& f) {
|
||||
auto& rt_info = f->get_rt_info();
|
||||
@@ -413,18 +656,43 @@ TEST(RTInfoDeserialization, InputAndOutputV11) {
|
||||
check_fused_names(param->output(0).get_rt_info(), "test1,test2");
|
||||
check_old_api_map(param->get_rt_info(),
|
||||
std::vector<uint64_t>({}),
|
||||
ngraph::element::Type_t::u8);
|
||||
ngraph::element::Type_t::undefined);
|
||||
|
||||
auto result = f->get_results()[0];
|
||||
auto result = f->get_result();
|
||||
check_fused_names(result->input(0).get_rt_info(), "test5,test6");
|
||||
check_old_api_map(result->get_rt_info(),
|
||||
std::vector<uint64_t>({}),
|
||||
ngraph::element::Type_t::undefined);
|
||||
|
||||
auto add = result->get_input_node_ptr(0);
|
||||
check_fused_names(add->input(0).get_rt_info(), "test2,test3");
|
||||
check_fused_names(add->input(1).get_rt_info(), "test3,test4");
|
||||
check_fused_names(add->output(0).get_rt_info(), "test4,test5");
|
||||
|
||||
// read IR v11 with old API - the function is the same since no old_api_map is applied
|
||||
{
|
||||
InferenceEngine::Core core;
|
||||
auto cnn = core.ReadNetwork(model, InferenceEngine::Blob::CPtr());
|
||||
auto f_10 = cnn.getFunction();
|
||||
ASSERT_NE(nullptr, f_10);
|
||||
|
||||
EXPECT_EQ(0, f_10->get_rt_info().count("version"));
|
||||
|
||||
// check that old api map is removed once applied
|
||||
auto check_old_api_rt_info = [](const RTMap & info) {
|
||||
const std::string & key = ov::OldApiMap::get_type_info_static();
|
||||
EXPECT_FALSE(info.count(key));
|
||||
};
|
||||
|
||||
check_old_api_rt_info(f_10->get_parameters()[0]->get_rt_info());
|
||||
check_old_api_rt_info(f_10->get_result()->get_rt_info());
|
||||
|
||||
auto res = compare_functions(f, f_10);
|
||||
EXPECT_TRUE(res.first) << res.second;
|
||||
}
|
||||
}
|
||||
|
||||
TEST(RTInfoDeserialization, IndexesInputAndOutputV11) {
|
||||
TEST_F(RTInfoDeserialization, IndexesInputAndOutputV11) {
|
||||
std::string model = R"V0G0N(
|
||||
<net name="Network" version="11">
|
||||
<layers>
|
||||
@@ -522,9 +790,8 @@ TEST(RTInfoDeserialization, IndexesInputAndOutputV11) {
|
||||
</edges>
|
||||
</net>
|
||||
)V0G0N";
|
||||
auto core = InferenceEngine::Core();
|
||||
auto net = core.ReadNetwork(model, InferenceEngine::Blob::Ptr());
|
||||
auto f = net.getFunction();
|
||||
auto f = getWithIRFrontend(model);
|
||||
ASSERT_NE(nullptr, f);
|
||||
|
||||
auto check_version = [](const std::shared_ptr<ov::Function>& f) {
|
||||
auto& rt_info = f->get_rt_info();
|
||||
|
||||
+31
-14
@@ -2,6 +2,7 @@
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <common_test_utils/file_utils.hpp>
|
||||
#include <gtest/gtest.h>
|
||||
|
||||
#include <file_utils.h>
|
||||
@@ -13,6 +14,7 @@
|
||||
#include "transformations/serialize.hpp"
|
||||
#include <openvino/opsets/opset8.hpp>
|
||||
#include <transformations/rt_info/attributes.hpp>
|
||||
#include "frontend_manager/frontend_manager.hpp"
|
||||
|
||||
using namespace ngraph;
|
||||
|
||||
@@ -23,9 +25,28 @@ protected:
|
||||
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());
|
||||
CommonTestUtils::removeIRFiles(m_out_xml_path, m_out_bin_path);
|
||||
}
|
||||
|
||||
std::shared_ptr<ngraph::Function> getWithIRFrontend(const std::string& model_path,
|
||||
const std::string& weights_path) {
|
||||
ngraph::frontend::FrontEnd::Ptr FE;
|
||||
ngraph::frontend::InputModel::Ptr inputModel;
|
||||
|
||||
ov::VariantVector params{ov::make_variant(model_path), ov::make_variant(weights_path)};
|
||||
|
||||
FE = manager.load_by_model(params);
|
||||
if (FE)
|
||||
inputModel = FE->load(params);
|
||||
|
||||
if (inputModel)
|
||||
return FE->convert(inputModel);
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
private:
|
||||
ngraph::frontend::FrontEndManager manager;
|
||||
};
|
||||
|
||||
TEST_F(RTInfoSerializationTest, all_attributes_latest) {
|
||||
@@ -53,9 +74,8 @@ TEST_F(RTInfoSerializationTest, all_attributes_latest) {
|
||||
m.register_pass<pass::Serialize>(m_out_xml_path, m_out_bin_path);
|
||||
m.run_passes(function);
|
||||
|
||||
auto core = InferenceEngine::Core();
|
||||
auto net = core.ReadNetwork(m_out_xml_path, m_out_bin_path);
|
||||
auto f = net.getFunction();
|
||||
auto f = getWithIRFrontend(m_out_xml_path, m_out_bin_path);
|
||||
ASSERT_NE(nullptr, f);
|
||||
|
||||
auto check_info = [](const RTMap & info) {
|
||||
const std::string & key = VariantWrapper<ngraph::FusedNames>::get_type_info_static();
|
||||
@@ -109,9 +129,8 @@ TEST_F(RTInfoSerializationTest, all_attributes_v10) {
|
||||
m.register_pass<pass::Serialize>(m_out_xml_path, m_out_bin_path, pass::Serialize::Version::IR_V10);
|
||||
m.run_passes(function);
|
||||
|
||||
auto core = InferenceEngine::Core();
|
||||
auto net = core.ReadNetwork(m_out_xml_path, m_out_bin_path);
|
||||
auto f = net.getFunction();
|
||||
auto f = getWithIRFrontend(m_out_xml_path, m_out_bin_path);
|
||||
ASSERT_NE(nullptr, f);
|
||||
|
||||
auto check_info = [](const RTMap & info) {
|
||||
const std::string & key = VariantWrapper<ngraph::FusedNames>::get_type_info_static();
|
||||
@@ -148,9 +167,8 @@ TEST_F(RTInfoSerializationTest, all_attributes_v11) {
|
||||
m.register_pass<pass::Serialize>(m_out_xml_path, m_out_bin_path);
|
||||
m.run_passes(function);
|
||||
|
||||
auto core = InferenceEngine::Core();
|
||||
auto net = core.ReadNetwork(m_out_xml_path, m_out_bin_path);
|
||||
auto f = net.getFunction();
|
||||
auto f = getWithIRFrontend(m_out_xml_path, m_out_bin_path);
|
||||
ASSERT_NE(nullptr, f);
|
||||
|
||||
auto check_info = [](const RTMap & info) {
|
||||
const std::string & key = VariantWrapper<ngraph::FusedNames>::get_type_info_static();
|
||||
@@ -201,9 +219,8 @@ TEST_F(RTInfoSerializationTest, parameter_result_v11) {
|
||||
m.register_pass<pass::Serialize>(m_out_xml_path, m_out_bin_path, pass::Serialize::Version::IR_V11);
|
||||
m.run_passes(function);
|
||||
|
||||
auto core = InferenceEngine::Core();
|
||||
auto net = core.ReadNetwork(m_out_xml_path, m_out_bin_path);
|
||||
auto f = net.getFunction();
|
||||
auto f = getWithIRFrontend(m_out_xml_path, m_out_bin_path);
|
||||
ASSERT_NE(nullptr, f);
|
||||
|
||||
ASSERT_EQ(function->get_results().size(), f->get_results().size());
|
||||
ASSERT_EQ(function->get_parameters().size(), f->get_parameters().size());
|
||||
|
||||
@@ -67,6 +67,11 @@ Layout Layout::scalar() {
|
||||
// 2. can define order and meaning for dimensions "NCHW"
|
||||
// 3. partial layout specialization "NC?"
|
||||
Layout::Layout(const std::string& layout_str) {
|
||||
if (layout_str.empty()) {
|
||||
m_dynamic = true;
|
||||
m_left_size = m_right_size = 0;
|
||||
return;
|
||||
}
|
||||
auto layout = ngraph::trim(layout_str);
|
||||
OPENVINO_ASSERT(layout.length() > 0, "Cannot parse ov::Layout from an empty string");
|
||||
if (layout == SCALAR) {
|
||||
|
||||
@@ -92,9 +92,13 @@ void PreProcessSteps::PreProcessStepsImpl::add_convert_impl(const ov::element::T
|
||||
for (const auto& node : nodes) {
|
||||
OPENVINO_ASSERT(node->get_element_type().is_static(),
|
||||
"Can't insert 'convert_element_type' for dynamic source tensor type.");
|
||||
auto convert = std::make_shared<op::v0::Convert>(node, type);
|
||||
inherit_friendly_names(function, node, convert, "/convert_element_type");
|
||||
res.emplace_back(convert);
|
||||
if (node->get_element_type() != type) {
|
||||
auto convert = std::make_shared<op::v0::Convert>(node, type);
|
||||
inherit_friendly_names(function, node, convert, "/convert_element_type");
|
||||
res.emplace_back(convert);
|
||||
} else {
|
||||
res.emplace_back(node);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
},
|
||||
|
||||
@@ -79,7 +79,7 @@ private:
|
||||
};
|
||||
|
||||
template <>
|
||||
FrontEnd::Ptr FrontEndManager::load_by_model(const std::vector<std::shared_ptr<Variant>>& variants);
|
||||
FRONTEND_API FrontEnd::Ptr FrontEndManager::load_by_model(const std::vector<std::shared_ptr<Variant>>& variants);
|
||||
|
||||
// --------- Plugin exporting information --------------
|
||||
|
||||
|
||||
@@ -194,7 +194,7 @@ public:
|
||||
m_extensions(extensions) {
|
||||
pugi::xml_parse_result res = m_xml_doc.load(stream);
|
||||
if (res.status != pugi::status_ok) {
|
||||
IE_THROW() << res.description() << "at offset " << res.offset;
|
||||
IE_THROW() << res.description() << " at offset " << res.offset;
|
||||
}
|
||||
m_root = m_xml_doc.document_element();
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ TEST(layout, advanced_syntax) {
|
||||
|
||||
TEST(layout, empty) {
|
||||
Layout l;
|
||||
EXPECT_TRUE(Layout("").empty());
|
||||
EXPECT_FALSE(layout::has_batch(l));
|
||||
EXPECT_THROW(layout::batch(l), ov::AssertFailure);
|
||||
EXPECT_FALSE(layout::has_channels(l));
|
||||
@@ -132,7 +133,6 @@ TEST(layout, dims_valid_syntax) {
|
||||
|
||||
TEST(layout, dims_wrong_syntax) {
|
||||
Layout l;
|
||||
EXPECT_THROW(l = "", ov::AssertFailure);
|
||||
EXPECT_THROW(l = " ", ov::AssertFailure);
|
||||
std::string invalidChars = "`~!@#$%^&*()-=+{}\"'><,|";
|
||||
for (auto c : invalidChars) {
|
||||
|
||||
Reference in new issue
Block a user