[ONNX] Add ONNX specific FrontEnd classes (#6615)
This change implements a subset of FrontEnd API for ONNX: Changes: - move onnx_common, onnx_editor and onnx_import to ngraph/frontend/onnx - introduce new target 'onnx_frontend_ngraph' located in ngraph/frontend/onnx/frontend - new target implements subset of FrontEnd, InputModel and Place interfaces
This commit is contained in:
1 parent
fd3e4a3d45
commit
22273f8069
39 files changed
+852
-318
No files matched your search
@@ -109,6 +109,7 @@ jobs:
|
||||
-DENABLE_WHEEL=ON
|
||||
-DENABLE_TESTS=ON
|
||||
-DNGRAPH_ONNX_IMPORT_ENABLE=ON
|
||||
-DNGRAPH_ONNX_FRONTEND_ENABLE=ON
|
||||
-DENABLE_FASTER_BUILD=ON
|
||||
-DENABLE_STRICT_DEPENDENCIES=OFF
|
||||
-DIE_EXTRA_MODULES=$(OPENVINO_CONTRIB_REPO_DIR)/modules
|
||||
|
||||
@@ -95,6 +95,7 @@ jobs:
|
||||
-DENABLE_SAMPLES=OFF
|
||||
-DENABLE_SPEECH_DEMO=OFF
|
||||
-DNGRAPH_ONNX_IMPORT_ENABLE=ON
|
||||
-DNGRAPH_ONNX_FRONTEND_ENABLE=ON
|
||||
-DNGRAPH_DEBUG_ENABLE=OFF
|
||||
$(REPO_DIR)
|
||||
workingDirectory: $(BUILD_DIR)
|
||||
|
||||
@@ -69,6 +69,7 @@ RUN cmake .. \
|
||||
-DENABLE_PYTHON=ON \
|
||||
-DPYTHON_EXECUTABLE=/usr/bin/python3 \
|
||||
-DNGRAPH_ONNX_IMPORT_ENABLE=ON \
|
||||
-DNGRAPH_ONNX_FRONTEND_ENABLE=ON \
|
||||
-DNGRAPH_DEBUG_ENABLE=OFF \
|
||||
-DCMAKE_INSTALL_PREFIX=/openvino/dist \
|
||||
-DNGRAPH_USE_PROTOBUF_LITE=${PROTOBUF_LITE}
|
||||
|
||||
@@ -92,9 +92,15 @@ ie_coverage_genhtml(INFO_FILE "ngraph"
|
||||
|
||||
if(NGRAPH_ONNX_IMPORT_ENABLE)
|
||||
ie_coverage_extract(INPUT "openvino" OUTPUT "onnx_importer"
|
||||
PATTERNS "${OV_COVERAGE_BASE_DIRECTORY}/ngraph/frontend/onnx_common*"
|
||||
"${OV_COVERAGE_BASE_DIRECTORY}/ngraph/frontend/onnx_editor*"
|
||||
"${OV_COVERAGE_BASE_DIRECTORY}/ngraph/frontend/onnx_import*")
|
||||
PATTERNS "${OV_COVERAGE_BASE_DIRECTORY}/ngraph/frontend/onnx/onnx_common*"
|
||||
"${OV_COVERAGE_BASE_DIRECTORY}/ngraph/frontend/onnx/onnx_import*")
|
||||
ie_coverage_genhtml(INFO_FILE "onnx_importer"
|
||||
PREFIX "${OV_COVERAGE_BASE_DIRECTORY}")
|
||||
endif()
|
||||
|
||||
if(NGRAPH_ONNX_FRONTEND_ENABLE)
|
||||
ie_coverage_extract(INPUT "openvino" OUTPUT "onnx_ngraph_frontend"
|
||||
PATTERNS "${OV_COVERAGE_BASE_DIRECTORY}/ngraph/frontend/onnx/frontend*")
|
||||
ie_coverage_genhtml(INFO_FILE "onnx_ngraph_frontend"
|
||||
PREFIX "${OV_COVERAGE_BASE_DIRECTORY}")
|
||||
endif()
|
||||
@@ -125,6 +125,7 @@ else()
|
||||
endif()
|
||||
|
||||
ie_dependent_option(NGRAPH_ONNX_IMPORT_ENABLE "Enable ONNX importer" ON "protoc_available" OFF)
|
||||
ie_dependent_option(NGRAPH_ONNX_FRONTEND_ENABLE "Enable ONNX FrontEnd" OFF "NGRAPH_ONNX_IMPORT_ENABLE" OFF)
|
||||
ie_dependent_option(NGRAPH_PDPD_FRONTEND_ENABLE "Enable PaddlePaddle FrontEnd" ON "protoc_available" OFF)
|
||||
ie_dependent_option(NGRAPH_USE_PROTOBUF_LITE "Compiles and links with protobuf-lite" OFF
|
||||
"NGRAPH_ONNX_IMPORT_ENABLE OR NGRAPH_PDPD_FRONTEND_ENABLE" OFF)
|
||||
|
||||
@@ -63,7 +63,7 @@ namespace ngraph
|
||||
/// \param partiallyConverted partially converted nGraph function
|
||||
/// \return fully converted nGraph function
|
||||
virtual std::shared_ptr<ngraph::Function>
|
||||
convert(std::shared_ptr<ngraph::Function> partiallyConverted) const;
|
||||
convert(std::shared_ptr<ngraph::Function> partially_converted) const;
|
||||
|
||||
/// \brief Convert only those parts of the model that can be converted leaving others
|
||||
/// as-is. Converted parts are not normalized by additional transformations; normalize
|
||||
|
||||
@@ -68,47 +68,47 @@ namespace ngraph
|
||||
|
||||
/// \brief Returns a tensor place by a tensor name following framework conventions, or
|
||||
/// nullptr if a tensor with this name doesn't exist.
|
||||
/// \param tensorName Name of tensor
|
||||
/// \param tensor_name Name of tensor
|
||||
/// \return Tensor place corresponding to specifed tensor name
|
||||
virtual Place::Ptr get_place_by_tensor_name(const std::string& tensorName) const;
|
||||
virtual Place::Ptr get_place_by_tensor_name(const std::string& tensor_name) const;
|
||||
|
||||
/// \brief Returns an operation place by an operation name following framework
|
||||
/// conventions, or nullptr if an operation with this name doesn't exist. \param
|
||||
/// operationName Name of operation \return Place representing operation
|
||||
virtual Place::Ptr get_place_by_operation_name(const std::string& operationName);
|
||||
/// operation_name Name of operation \return Place representing operation
|
||||
virtual Place::Ptr get_place_by_operation_name(const std::string& operation_name);
|
||||
|
||||
/// \brief Returns an input port place by operation name and appropriate port index
|
||||
/// \param operationName Name of operation
|
||||
/// \param outputPortIndex Index of input port for this operation
|
||||
/// \param operation_name Name of operation
|
||||
/// \param output_port_index Index of input port for this operation
|
||||
/// \return Place representing input port of operation
|
||||
virtual Place::Ptr
|
||||
get_place_by_operation_name_and_input_port(const std::string& operationName,
|
||||
int inputPortIndex);
|
||||
get_place_by_operation_name_and_input_port(const std::string& operation_name,
|
||||
int input_port_index);
|
||||
|
||||
/// \brief Returns an output port place by operation name and appropriate port index
|
||||
/// \param operationNameNname of operation
|
||||
/// \param outputPortIndex Index of output port for this operation
|
||||
/// \param operation_name Name of operation
|
||||
/// \param output_port_index Index of output port for this operation
|
||||
/// \return Place representing output port of operation
|
||||
virtual Place::Ptr
|
||||
get_place_by_operation_name_and_output_port(const std::string& operationName,
|
||||
int outputPortIndex);
|
||||
get_place_by_operation_name_and_output_port(const std::string& operation_name,
|
||||
int output_port_index);
|
||||
|
||||
///// Naming and annotation /////
|
||||
|
||||
/// \brief Sets name for tensor. Overwrites existing names of this place
|
||||
/// \param operation Tensor place
|
||||
/// \param newName New name for this tensor
|
||||
virtual void set_name_for_tensor(Place::Ptr tensor, const std::string& newName);
|
||||
/// \param new_name New name for this tensor
|
||||
virtual void set_name_for_tensor(Place::Ptr tensor, const std::string& new_name);
|
||||
|
||||
/// \brief Adds new name for tensor
|
||||
/// \param operation Tensor place
|
||||
/// \param newName New name to be added to this place
|
||||
virtual void add_name_for_tensor(Place::Ptr tensor, const std::string& newName);
|
||||
/// \param new_name New name to be added to this place
|
||||
virtual void add_name_for_tensor(Place::Ptr tensor, const std::string& new_name);
|
||||
|
||||
/// \brief Sets name for operation. Overwrites existing names of this place
|
||||
/// \param operation Operation place
|
||||
/// \param newName New name for this operation
|
||||
virtual void set_name_for_operation(Place::Ptr operation, const std::string& newName);
|
||||
/// \param new_name New name for this operation
|
||||
virtual void set_name_for_operation(Place::Ptr operation, const std::string& new_name);
|
||||
|
||||
/// \brief Unassign specified name from tensor place(s)
|
||||
/// \param name Name of tensor
|
||||
@@ -120,27 +120,27 @@ namespace ngraph
|
||||
|
||||
/// \brief Set name for a particular dimension of a place (e.g. batch dimension)
|
||||
/// \param place Model's place
|
||||
/// \param shapeDimIndex Dimension index
|
||||
/// \param dimName Name to assign on this dimension
|
||||
/// \param shape_dim_index Dimension index
|
||||
/// \param dim_name Name to assign on this dimension
|
||||
virtual void set_name_for_dimension(Place::Ptr place,
|
||||
size_t shapeDimIndex,
|
||||
const std::string& dimName);
|
||||
size_t shape_dim_index,
|
||||
const std::string& dim_name);
|
||||
|
||||
///// Topology Editing /////
|
||||
|
||||
/// \brief Cut immediately before this place and assign this place as new input; prune
|
||||
/// all nodes that don't contribute to any output.
|
||||
/// \param place New place to be assigned as input
|
||||
/// \param newNameOptional Optional new name assigned to this input place
|
||||
/// \param new_name_optional Optional new name assigned to this input place
|
||||
virtual void cut_and_add_new_input(Place::Ptr place,
|
||||
const std::string& newNameOptional = "");
|
||||
const std::string& new_name_optional = "");
|
||||
|
||||
/// \brief Cut immediately after this place and assign this place as new output; prune
|
||||
/// all nodes that don't contribute to any output.
|
||||
/// \param place New place to be assigned as output
|
||||
/// \param newNameOptional Optional new name assigned to this output place
|
||||
/// \param new_name_optional Optional new name assigned to this output place
|
||||
virtual void cut_and_add_new_output(Place::Ptr place,
|
||||
const std::string& newNameOptional = "");
|
||||
const std::string& new_name_optional = "");
|
||||
|
||||
/// \brief Assign this place as new output or add necessary nodes to represent a new
|
||||
/// output.
|
||||
@@ -200,13 +200,13 @@ namespace ngraph
|
||||
virtual void set_tensor_value(Place::Ptr place, const void* value);
|
||||
|
||||
/// \brief Defines partial value (lower bound and upper bound) for a tensor place
|
||||
/// TODO: more details for minValue and maxValue format; who defines shape?
|
||||
/// TODO: more details for min_value and max_value format; who defines shape?
|
||||
/// \param place Tensor place
|
||||
/// \param minValue Lower bound of partial value for tensor place
|
||||
/// \param maxValue Upper bound of partial value for tensor place
|
||||
/// \param min_value Lower bound of partial value for tensor place
|
||||
/// \param max_value Upper bound of partial value for tensor place
|
||||
virtual void set_tensor_partial_value(Place::Ptr place,
|
||||
const void* minValue,
|
||||
const void* maxValue);
|
||||
const void* min_value,
|
||||
const void* max_value);
|
||||
};
|
||||
|
||||
} // namespace frontend
|
||||
|
||||
@@ -87,12 +87,12 @@ namespace ngraph
|
||||
/// \note It can be called for any kind of graph place searching for the first consuming
|
||||
/// operations.
|
||||
///
|
||||
/// \param outputPortIndex If place is an operational node it specifies which output
|
||||
/// \param output_port_index If place is an operational node it specifies which output
|
||||
/// port should be considered.
|
||||
///
|
||||
/// \return A vector with all operation node references that consumes data from this
|
||||
/// place
|
||||
virtual std::vector<Ptr> get_consuming_operations(int outputPortIndex) const;
|
||||
virtual std::vector<Ptr> get_consuming_operations(int output_port_index) const;
|
||||
|
||||
/// \brief Returns a tensor place that gets data from this place; applicable for
|
||||
/// operations, output ports and output edges which have only one output port
|
||||
@@ -103,11 +103,11 @@ namespace ngraph
|
||||
/// \brief Returns a tensor place that gets data from this place; applicable for
|
||||
/// operations, output ports and output edges
|
||||
///
|
||||
/// \param outputPortIndex Output port index if the current place is an operation node
|
||||
/// \param output_port_index Output port index if the current place is an operation node
|
||||
/// and has multiple output ports
|
||||
///
|
||||
/// \return A tensor place which hold the resulting value for this place
|
||||
virtual Ptr get_target_tensor(int outputPortIndex) const;
|
||||
virtual Ptr get_target_tensor(int output_port_index) const;
|
||||
|
||||
/// \brief Returns a tensor place that supplies data for this place; applicable for
|
||||
/// operations, input ports and input edges which have only one input port
|
||||
@@ -118,10 +118,10 @@ namespace ngraph
|
||||
/// \brief Returns a tensor place that supplies data for this place; applicable for
|
||||
/// operations, input ports and input edges
|
||||
///
|
||||
/// \param inputPortIndex Input port index for operational nodes.
|
||||
/// \param input_port_index Input port index for operational nodes.
|
||||
///
|
||||
/// \return A tensor place which supplies data for this place
|
||||
virtual Ptr get_source_tensor(int inputPortIndex) const;
|
||||
virtual Ptr get_source_tensor(int input_port_index) const;
|
||||
|
||||
/// \brief Get an operation node place that immediately produces data for this place;
|
||||
/// applicable if place has only one input port
|
||||
@@ -131,11 +131,11 @@ namespace ngraph
|
||||
|
||||
/// \brief Get an operation node place that immediately produces data for this place
|
||||
///
|
||||
/// \param inputPortIndex If a given place is itself an operation node, this specifies a
|
||||
/// port index
|
||||
/// \param input_port_index If a given place is itself an operation node, this specifies
|
||||
/// a port index
|
||||
///
|
||||
/// \return An operation place that produces data for this place
|
||||
virtual Ptr get_producing_operation(int inputPortIndex) const;
|
||||
virtual Ptr get_producing_operation(int input_port_index) const;
|
||||
|
||||
/// Returns a port that produces data for this place
|
||||
virtual Ptr get_producing_port() const;
|
||||
@@ -148,28 +148,28 @@ namespace ngraph
|
||||
|
||||
/// \brief For operation node returns reference to an input port with specified index
|
||||
///
|
||||
/// \param inputPortIndex Input port index
|
||||
/// \param input_port_index Input port index
|
||||
///
|
||||
/// \return Appropriate input port place
|
||||
virtual Ptr get_input_port(int inputPortIndex) const;
|
||||
virtual Ptr get_input_port(int input_port_index) const;
|
||||
|
||||
/// \brief For operation node returns reference to an input port with specified name;
|
||||
/// applicable if port group has only one input port
|
||||
///
|
||||
/// \param inputName Name of port group
|
||||
/// \param input_name Name of port group
|
||||
///
|
||||
/// \return Appropriate input port place
|
||||
virtual Ptr get_input_port(const std::string& inputName) const;
|
||||
virtual Ptr get_input_port(const std::string& input_name) const;
|
||||
|
||||
/// \brief For operation node returns reference to an input port with specified name and
|
||||
/// index
|
||||
///
|
||||
/// \param inputName Name of port group, each group can have multiple ports
|
||||
/// \param input_name Name of port group, each group can have multiple ports
|
||||
///
|
||||
/// \param inputPortIndex Input port index in a group
|
||||
/// \param input_port_index Input port index in a group
|
||||
///
|
||||
/// \return Appropriate input port place
|
||||
virtual Ptr get_input_port(const std::string& inputName, int inputPortIndex) const;
|
||||
virtual Ptr get_input_port(const std::string& input_name, int input_port_index) const;
|
||||
|
||||
/// \brief For operation node returns reference to an output port; applicable for
|
||||
/// operations with only one output port
|
||||
@@ -179,28 +179,29 @@ namespace ngraph
|
||||
|
||||
/// \brief For operation node returns reference to an output port with specified index
|
||||
///
|
||||
/// \param outputPortIndex Output port index
|
||||
/// \param output_port_index Output port index
|
||||
///
|
||||
/// \return Appropriate output port place
|
||||
virtual Ptr get_output_port(int outputPortIndex) const;
|
||||
virtual Ptr get_output_port(int output_port_index) const;
|
||||
|
||||
/// \brief For operation node returns reference to an output port with specified name;
|
||||
/// applicable if port group has only one output port
|
||||
///
|
||||
/// \param outputName Name of output port group
|
||||
/// \param output_name Name of output port group
|
||||
///
|
||||
/// \return Appropriate output port place
|
||||
virtual Ptr get_output_port(const std::string& outputName) const;
|
||||
virtual Ptr get_output_port(const std::string& output_name) const;
|
||||
|
||||
/// \brief For operation node returns reference to an output port with specified name
|
||||
/// and index
|
||||
///
|
||||
/// \param outputName Name of output port group, each group can have multiple ports
|
||||
/// \param output_name Name of output port group, each group can have multiple ports
|
||||
///
|
||||
/// \param outputPortIndex Output port index
|
||||
/// \param output_port_index Output port index
|
||||
///
|
||||
/// \return Appropriate output port place
|
||||
virtual Ptr get_output_port(const std::string& outputName, int outputPortIndex) const;
|
||||
virtual Ptr get_output_port(const std::string& output_name,
|
||||
int output_port_index) const;
|
||||
|
||||
/// \brief Returns all input ports that consume data flows through this place
|
||||
virtual std::vector<Place::Ptr> get_consuming_ports() const;
|
||||
|
||||
@@ -16,22 +16,22 @@ using namespace ngraph::frontend;
|
||||
//----------- FrontEndManager ---------------------------
|
||||
class FrontEndManager::Impl
|
||||
{
|
||||
std::vector<PluginHandle> m_loadedLibs; // must be a first class member (destroyed last)
|
||||
std::vector<PluginHandle> m_loaded_libs; // must be a first class member (destroyed last)
|
||||
std::map<std::string, FrontEndFactory> m_factories;
|
||||
|
||||
public:
|
||||
Impl() { registerPlugins(); }
|
||||
Impl() { register_plugins(); }
|
||||
|
||||
~Impl() = default;
|
||||
|
||||
FrontEnd::Ptr loadByFramework(const std::string& framework)
|
||||
FrontEnd::Ptr load_by_framework(const std::string& framework)
|
||||
{
|
||||
FRONT_END_INITIALIZATION_CHECK(
|
||||
m_factories.count(framework), "FrontEnd for Framework ", framework, " is not found");
|
||||
return m_factories[framework]();
|
||||
}
|
||||
|
||||
std::vector<std::string> availableFrontEnds() const
|
||||
std::vector<std::string> available_front_ends() const
|
||||
{
|
||||
std::vector<std::string> keys;
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
return keys;
|
||||
}
|
||||
|
||||
FrontEnd::Ptr loadByModel(const std::vector<std::shared_ptr<Variant>>& variants)
|
||||
FrontEnd::Ptr load_by_model(const std::vector<std::shared_ptr<Variant>>& variants)
|
||||
{
|
||||
for (const auto& factory : m_factories)
|
||||
{
|
||||
@@ -56,41 +56,41 @@ public:
|
||||
return FrontEnd::Ptr();
|
||||
}
|
||||
|
||||
void registerFrontEnd(const std::string& name, FrontEndFactory creator)
|
||||
void register_front_end(const std::string& name, FrontEndFactory creator)
|
||||
{
|
||||
m_factories.insert({name, creator});
|
||||
}
|
||||
|
||||
private:
|
||||
void registerPlugins()
|
||||
void register_plugins()
|
||||
{
|
||||
auto registerFromDir = [&](const std::string& dir) {
|
||||
auto register_from_dir = [&](const std::string& dir) {
|
||||
if (!dir.empty())
|
||||
{
|
||||
auto plugins = loadPlugins(dir);
|
||||
auto plugins = load_plugins(dir);
|
||||
for (auto& plugin : plugins)
|
||||
{
|
||||
registerFrontEnd(plugin.m_pluginInfo.m_name, plugin.m_pluginInfo.m_creator);
|
||||
m_loadedLibs.push_back(std::move(plugin.m_libHandle));
|
||||
register_front_end(plugin.m_plugin_info.m_name, plugin.m_plugin_info.m_creator);
|
||||
m_loaded_libs.push_back(std::move(plugin.m_lib_handle));
|
||||
}
|
||||
}
|
||||
};
|
||||
std::string envPath = ngraph::getenv_string("OV_FRONTEND_PATH");
|
||||
if (!envPath.empty())
|
||||
std::string env_path = ngraph::getenv_string("OV_FRONTEND_PATH");
|
||||
if (!env_path.empty())
|
||||
{
|
||||
auto start = 0u;
|
||||
auto sepPos = envPath.find(PathSeparator, start);
|
||||
while (sepPos != std::string::npos)
|
||||
auto sep_pos = env_path.find(PathSeparator, start);
|
||||
while (sep_pos != std::string::npos)
|
||||
{
|
||||
registerFromDir(envPath.substr(start, sepPos - start));
|
||||
start = sepPos + 1;
|
||||
sepPos = envPath.find(PathSeparator, start);
|
||||
register_from_dir(env_path.substr(start, sep_pos - start));
|
||||
start = sep_pos + 1;
|
||||
sep_pos = env_path.find(PathSeparator, start);
|
||||
}
|
||||
registerFromDir(envPath.substr(start, sepPos));
|
||||
register_from_dir(env_path.substr(start, sep_pos));
|
||||
}
|
||||
else
|
||||
{
|
||||
registerFromDir(getFrontendLibraryPath());
|
||||
register_from_dir(get_frontend_library_path());
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -107,23 +107,23 @@ FrontEndManager::~FrontEndManager() = default;
|
||||
|
||||
FrontEnd::Ptr FrontEndManager::load_by_framework(const std::string& framework)
|
||||
{
|
||||
return m_impl->loadByFramework(framework);
|
||||
return m_impl->load_by_framework(framework);
|
||||
}
|
||||
|
||||
FrontEnd::Ptr
|
||||
FrontEndManager::load_by_model_impl(const std::vector<std::shared_ptr<Variant>>& variants)
|
||||
{
|
||||
return m_impl->loadByModel(variants);
|
||||
return m_impl->load_by_model(variants);
|
||||
}
|
||||
|
||||
std::vector<std::string> FrontEndManager::get_available_front_ends() const
|
||||
{
|
||||
return m_impl->availableFrontEnds();
|
||||
return m_impl->available_front_ends();
|
||||
}
|
||||
|
||||
void FrontEndManager::register_front_end(const std::string& name, FrontEndFactory creator)
|
||||
{
|
||||
m_impl->registerFrontEnd(name, creator);
|
||||
m_impl->register_front_end(name, creator);
|
||||
}
|
||||
|
||||
//----------- FrontEnd ---------------------------
|
||||
@@ -158,7 +158,7 @@ std::shared_ptr<ngraph::Function> FrontEnd::convert_partially(InputModel::Ptr mo
|
||||
|
||||
std::shared_ptr<ngraph::Function> FrontEnd::decode(InputModel::Ptr model) const
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(convertDecodingOnly);
|
||||
FRONT_END_NOT_IMPLEMENTED(decode);
|
||||
}
|
||||
|
||||
void FrontEnd::normalize(std::shared_ptr<ngraph::Function> function) const
|
||||
@@ -177,39 +177,40 @@ std::vector<Place::Ptr> InputModel::get_outputs() const
|
||||
FRONT_END_NOT_IMPLEMENTED(get_outputs);
|
||||
}
|
||||
|
||||
Place::Ptr InputModel::get_place_by_tensor_name(const std::string& tensorName) const
|
||||
Place::Ptr InputModel::get_place_by_tensor_name(const std::string& tensor_name) const
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(get_place_by_tensor_name);
|
||||
}
|
||||
|
||||
Place::Ptr InputModel::get_place_by_operation_name(const std::string& operationName)
|
||||
Place::Ptr InputModel::get_place_by_operation_name(const std::string& operation_name)
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(get_place_by_operation_name);
|
||||
}
|
||||
|
||||
Place::Ptr InputModel::get_place_by_operation_name_and_input_port(const std::string& operationName,
|
||||
int inputPortIndex)
|
||||
Place::Ptr InputModel::get_place_by_operation_name_and_input_port(const std::string& operation_name,
|
||||
int input_port_index)
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(get_place_by_operation_name_and_input_port);
|
||||
}
|
||||
|
||||
Place::Ptr InputModel::get_place_by_operation_name_and_output_port(const std::string& operationName,
|
||||
int outputPortIndex)
|
||||
Place::Ptr
|
||||
InputModel::get_place_by_operation_name_and_output_port(const std::string& operation_name,
|
||||
int output_port_index)
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(get_place_by_operation_name_and_output_port);
|
||||
}
|
||||
|
||||
void InputModel::set_name_for_tensor(Place::Ptr tensor, const std::string& newName)
|
||||
void InputModel::set_name_for_tensor(Place::Ptr tensor, const std::string& new_name)
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(set_name_for_tensor);
|
||||
}
|
||||
|
||||
void InputModel::add_name_for_tensor(Place::Ptr tensor, const std::string& newName)
|
||||
void InputModel::add_name_for_tensor(Place::Ptr tensor, const std::string& new_name)
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(add_name_for_tensor);
|
||||
}
|
||||
|
||||
void InputModel::set_name_for_operation(Place::Ptr operation, const std::string& newName)
|
||||
void InputModel::set_name_for_operation(Place::Ptr operation, const std::string& new_name)
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(set_name_for_operation);
|
||||
}
|
||||
@@ -225,18 +226,18 @@ void InputModel::free_name_for_operation(const std::string& name)
|
||||
}
|
||||
|
||||
void InputModel::set_name_for_dimension(Place::Ptr place,
|
||||
size_t shapeDimIndex,
|
||||
const std::string& dimName)
|
||||
size_t shape_dim_index,
|
||||
const std::string& dim_name)
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(set_name_for_dimension);
|
||||
}
|
||||
|
||||
void InputModel::cut_and_add_new_input(Place::Ptr place, const std::string& newNameOptional)
|
||||
void InputModel::cut_and_add_new_input(Place::Ptr place, const std::string& new_name_optional)
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(cut_and_add_new_input);
|
||||
}
|
||||
|
||||
void InputModel::cut_and_add_new_output(Place::Ptr place, const std::string& newNameOptional)
|
||||
void InputModel::cut_and_add_new_output(Place::Ptr place, const std::string& new_name_optional)
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(cut_and_add_new_output);
|
||||
}
|
||||
@@ -289,8 +290,8 @@ void InputModel::set_tensor_value(Place::Ptr place, const void* value)
|
||||
}
|
||||
|
||||
void InputModel::set_tensor_partial_value(Place::Ptr place,
|
||||
const void* minValue,
|
||||
const void* maxValue)
|
||||
const void* min_value,
|
||||
const void* max_value)
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(set_tensor_partial_value);
|
||||
}
|
||||
@@ -306,7 +307,7 @@ std::vector<Place::Ptr> Place::get_consuming_operations() const
|
||||
FRONT_END_NOT_IMPLEMENTED(get_consuming_operations);
|
||||
}
|
||||
|
||||
std::vector<Place::Ptr> Place::get_consuming_operations(int outputPortIndex) const
|
||||
std::vector<Place::Ptr> Place::get_consuming_operations(int output_port_index) const
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(get_consuming_operations);
|
||||
}
|
||||
@@ -316,7 +317,7 @@ Place::Ptr Place::get_target_tensor() const
|
||||
FRONT_END_NOT_IMPLEMENTED(get_target_tensor);
|
||||
}
|
||||
|
||||
Place::Ptr Place::get_target_tensor(int outputPortIndex) const
|
||||
Place::Ptr Place::get_target_tensor(int output_port_index) const
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(get_target_tensor);
|
||||
}
|
||||
@@ -326,7 +327,7 @@ Place::Ptr Place::get_producing_operation() const
|
||||
FRONT_END_NOT_IMPLEMENTED(get_producing_operation);
|
||||
}
|
||||
|
||||
Place::Ptr Place::get_producing_operation(int inputPortIndex) const
|
||||
Place::Ptr Place::get_producing_operation(int input_port_index) const
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(get_producing_operation);
|
||||
}
|
||||
@@ -341,17 +342,17 @@ Place::Ptr Place::get_input_port() const
|
||||
FRONT_END_NOT_IMPLEMENTED(get_input_port);
|
||||
}
|
||||
|
||||
Place::Ptr Place::get_input_port(int inputPortIndex) const
|
||||
Place::Ptr Place::get_input_port(int input_port_index) const
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(get_input_port);
|
||||
}
|
||||
|
||||
Place::Ptr Place::get_input_port(const std::string& inputName) const
|
||||
Place::Ptr Place::get_input_port(const std::string& input_name) const
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(get_input_port);
|
||||
}
|
||||
|
||||
Place::Ptr Place::get_input_port(const std::string& inputName, int inputPortIndex) const
|
||||
Place::Ptr Place::get_input_port(const std::string& input_name, int input_port_index) const
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(get_input_port);
|
||||
}
|
||||
@@ -361,17 +362,17 @@ Place::Ptr Place::get_output_port() const
|
||||
FRONT_END_NOT_IMPLEMENTED(get_output_port);
|
||||
}
|
||||
|
||||
Place::Ptr Place::get_output_port(int outputPortIndex) const
|
||||
Place::Ptr Place::get_output_port(int output_port_index) const
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(get_output_port);
|
||||
}
|
||||
|
||||
Place::Ptr Place::get_output_port(const std::string& outputName) const
|
||||
Place::Ptr Place::get_output_port(const std::string& output_name) const
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(get_output_port);
|
||||
}
|
||||
|
||||
Place::Ptr Place::get_output_port(const std::string& outputName, int outputPortIndex) const
|
||||
Place::Ptr Place::get_output_port(const std::string& output_name, int output_port_index) const
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(get_output_port);
|
||||
}
|
||||
@@ -406,7 +407,7 @@ Place::Ptr Place::get_source_tensor() const
|
||||
FRONT_END_NOT_IMPLEMENTED(get_source_tensor);
|
||||
}
|
||||
|
||||
Place::Ptr Place::get_source_tensor(int inputPortIndex) const
|
||||
Place::Ptr Place::get_source_tensor(int input_port_index) const
|
||||
{
|
||||
FRONT_END_NOT_IMPLEMENTED(get_source_tensor);
|
||||
}
|
||||
|
||||
@@ -25,17 +25,17 @@ using namespace ngraph;
|
||||
using namespace ngraph::frontend;
|
||||
|
||||
#ifdef WIN32
|
||||
#define DLOPEN(fileStr) LoadLibrary(TEXT(fileStr.c_str()))
|
||||
#define DLOPEN(file_str) LoadLibrary(TEXT(file_str.c_str()))
|
||||
#define DLSYM(obj, func) GetProcAddress(obj, func)
|
||||
#define DLCLOSE(obj) FreeLibrary(obj)
|
||||
#else
|
||||
#define DLOPEN(fileStr) dlopen(file.c_str(), RTLD_LAZY)
|
||||
#define DLOPEN(file_str) dlopen(file_str.c_str(), RTLD_LAZY)
|
||||
#define DLSYM(obj, func) dlsym(obj, func)
|
||||
#define DLCLOSE(obj) dlclose(obj)
|
||||
#endif
|
||||
|
||||
// TODO: change to std::filesystem for C++17
|
||||
static std::vector<std::string> listFiles(const std::string& path)
|
||||
static std::vector<std::string> list_files(const std::string& path)
|
||||
{
|
||||
std::vector<std::string> res;
|
||||
try
|
||||
@@ -68,9 +68,9 @@ static std::vector<std::string> listFiles(const std::string& path)
|
||||
return res;
|
||||
}
|
||||
|
||||
std::vector<PluginData> ngraph::frontend::loadPlugins(const std::string& dirName)
|
||||
std::vector<PluginData> ngraph::frontend::load_plugins(const std::string& dir_name)
|
||||
{
|
||||
auto files = listFiles(dirName);
|
||||
auto files = list_files(dir_name);
|
||||
std::vector<PluginData> res;
|
||||
for (const auto& file : files)
|
||||
{
|
||||
@@ -80,32 +80,29 @@ std::vector<PluginData> ngraph::frontend::loadPlugins(const std::string& dirName
|
||||
continue;
|
||||
}
|
||||
|
||||
PluginHandle guard([shared_object, file]() {
|
||||
// std::cout << "Closing plugin library " << file << std::endl;
|
||||
DLCLOSE(shared_object);
|
||||
});
|
||||
PluginHandle guard([shared_object, file]() { DLCLOSE(shared_object); });
|
||||
|
||||
auto infoAddr = reinterpret_cast<void* (*)()>(DLSYM(shared_object, "GetAPIVersion"));
|
||||
if (!infoAddr)
|
||||
auto info_addr = reinterpret_cast<void* (*)()>(DLSYM(shared_object, "GetAPIVersion"));
|
||||
if (!info_addr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
FrontEndVersion plugInfo{reinterpret_cast<FrontEndVersion>(infoAddr())};
|
||||
FrontEndVersion plug_info{reinterpret_cast<FrontEndVersion>(info_addr())};
|
||||
|
||||
if (plugInfo != OV_FRONTEND_API_VERSION)
|
||||
if (plug_info != OV_FRONTEND_API_VERSION)
|
||||
{
|
||||
// Plugin has incompatible API version, do not load it
|
||||
continue;
|
||||
}
|
||||
|
||||
auto creatorAddr = reinterpret_cast<void* (*)()>(DLSYM(shared_object, "GetFrontEndData"));
|
||||
if (!creatorAddr)
|
||||
auto creator_addr = reinterpret_cast<void* (*)()>(DLSYM(shared_object, "GetFrontEndData"));
|
||||
if (!creator_addr)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
std::unique_ptr<FrontEndPluginInfo> fact{
|
||||
reinterpret_cast<FrontEndPluginInfo*>(creatorAddr())};
|
||||
reinterpret_cast<FrontEndPluginInfo*>(creator_addr())};
|
||||
|
||||
res.push_back(PluginData(std::move(guard), std::move(*fact)));
|
||||
}
|
||||
|
||||
@@ -7,11 +7,11 @@
|
||||
#include <frontend_manager/frontend_manager.hpp>
|
||||
|
||||
#ifdef _WIN32
|
||||
const char FileSeparator[] = "\\";
|
||||
const char PathSeparator[] = ";";
|
||||
static const char FileSeparator[] = "\\";
|
||||
static const char PathSeparator[] = ";";
|
||||
#else
|
||||
const char FileSeparator[] = "/";
|
||||
const char PathSeparator[] = ":";
|
||||
static const char FileSeparator[] = "/";
|
||||
static const char PathSeparator[] = ":";
|
||||
#endif // _WIN32
|
||||
|
||||
namespace ngraph
|
||||
@@ -23,8 +23,8 @@ namespace ngraph
|
||||
class PluginHandle
|
||||
{
|
||||
public:
|
||||
PluginHandle(std::function<void()> callOnDestruct)
|
||||
: m_callOnDestruct(callOnDestruct)
|
||||
PluginHandle(std::function<void()> call_on_destruct)
|
||||
: m_call_on_destruct(call_on_destruct)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -38,31 +38,31 @@ namespace ngraph
|
||||
|
||||
~PluginHandle()
|
||||
{
|
||||
if (m_callOnDestruct)
|
||||
if (m_call_on_destruct)
|
||||
{
|
||||
m_callOnDestruct();
|
||||
m_call_on_destruct();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
std::function<void()> m_callOnDestruct;
|
||||
std::function<void()> m_call_on_destruct;
|
||||
};
|
||||
|
||||
struct PluginData
|
||||
{
|
||||
PluginData(PluginHandle&& h, FrontEndPluginInfo&& info)
|
||||
: m_libHandle(std::move(h))
|
||||
, m_pluginInfo(info)
|
||||
: m_lib_handle(std::move(h))
|
||||
, m_plugin_info(info)
|
||||
{
|
||||
}
|
||||
|
||||
PluginHandle
|
||||
m_libHandle; // Shall be destroyed when plugin is not needed anymore to free memory
|
||||
FrontEndPluginInfo m_pluginInfo;
|
||||
m_lib_handle; // Shall be destroyed when plugin is not needed anymore to free memory
|
||||
FrontEndPluginInfo m_plugin_info;
|
||||
};
|
||||
|
||||
// Searches for available plugins in a specified directory
|
||||
std::vector<PluginData> loadPlugins(const std::string& dirName);
|
||||
std::vector<PluginData> load_plugins(const std::string& dir_name);
|
||||
|
||||
} // namespace frontend
|
||||
} // namespace ngraph
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
namespace
|
||||
{
|
||||
std::string getPathName(const std::string& s)
|
||||
std::string get_path_name(const std::string& s)
|
||||
{
|
||||
size_t i = s.rfind(FileSeparator, s.length());
|
||||
if (i != std::string::npos)
|
||||
@@ -39,30 +39,30 @@ namespace
|
||||
|
||||
} // namespace
|
||||
|
||||
static std::string _getFrontendLibraryPath()
|
||||
static std::string _get_frontend_library_path()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
CHAR ie_library_path[MAX_PATH];
|
||||
HMODULE hm = NULL;
|
||||
if (!GetModuleHandleExA(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS |
|
||||
GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
|
||||
reinterpret_cast<LPSTR>(ngraph::frontend::getFrontendLibraryPath),
|
||||
reinterpret_cast<LPSTR>(ngraph::frontend::get_frontend_library_path),
|
||||
&hm))
|
||||
{
|
||||
FRONT_END_INITIALIZATION_CHECK(false, "GetModuleHandle returned ", GetLastError());
|
||||
}
|
||||
GetModuleFileNameA(hm, (LPSTR)ie_library_path, sizeof(ie_library_path));
|
||||
return getPathName(std::string(ie_library_path));
|
||||
return get_path_name(std::string(ie_library_path));
|
||||
#elif defined(__APPLE__) || defined(__linux__)
|
||||
Dl_info info;
|
||||
dladdr(reinterpret_cast<void*>(ngraph::frontend::getFrontendLibraryPath), &info);
|
||||
return getPathName(std::string(info.dli_fname)).c_str();
|
||||
dladdr(reinterpret_cast<void*>(ngraph::frontend::get_frontend_library_path), &info);
|
||||
return get_path_name(std::string(info.dli_fname)).c_str();
|
||||
#else
|
||||
#error "Unsupported OS"
|
||||
#endif // _WIN32
|
||||
}
|
||||
|
||||
std::string ngraph::frontend::getFrontendLibraryPath()
|
||||
std::string ngraph::frontend::get_frontend_library_path()
|
||||
{
|
||||
return _getFrontendLibraryPath();
|
||||
return _get_frontend_library_path();
|
||||
}
|
||||
@@ -9,6 +9,6 @@ namespace ngraph
|
||||
{
|
||||
namespace frontend
|
||||
{
|
||||
FRONTEND_API std::string getFrontendLibraryPath();
|
||||
FRONTEND_API std::string get_frontend_library_path();
|
||||
} // namespace frontend
|
||||
} // namespace ngraph
|
||||
@@ -4,3 +4,6 @@
|
||||
|
||||
add_subdirectory(onnx_common)
|
||||
add_subdirectory(onnx_import)
|
||||
if (NGRAPH_ONNX_FRONTEND_ENABLE)
|
||||
add_subdirectory(frontend)
|
||||
endif()
|
||||
@@ -0,0 +1,45 @@
|
||||
# Copyright (C) 2021 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
#
|
||||
|
||||
file(GLOB_RECURSE LIBRARY_SRC ${CMAKE_CURRENT_SOURCE_DIR}/src/*.cpp)
|
||||
file(GLOB_RECURSE LIBRARY_PUBLIC_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/include/*.hpp)
|
||||
|
||||
set(ONNX_FRONTEND_INCLUDE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/include)
|
||||
|
||||
# Create named folders for the sources within the .vcproj
|
||||
# Empty name lists them directly under the .vcproj
|
||||
|
||||
source_group("src" FILES ${LIBRARY_SRC})
|
||||
source_group("include" FILES ${LIBRARY_HEADERS})
|
||||
source_group("public include" FILES ${LIBRARY_PUBLIC_HEADERS})
|
||||
|
||||
# Create shared library
|
||||
add_library(onnx_ngraph_frontend SHARED ${LIBRARY_SRC} ${LIBRARY_HEADERS} ${LIBRARY_PUBLIC_HEADERS})
|
||||
add_library(ngraph::onnx_ngraph_frontend ALIAS onnx_ngraph_frontend)
|
||||
|
||||
add_clang_format_target(onnx_ngraph_frontend_clang FOR_TARGETS onnx_ngraph_frontend)
|
||||
|
||||
if(COMMAND ie_add_vs_version_file)
|
||||
ie_add_vs_version_file(NAME onnx_ngraph_frontend
|
||||
FILEDESCRIPTION "nGraph ONNX frontend library")
|
||||
endif()
|
||||
|
||||
target_link_libraries(onnx_ngraph_frontend PRIVATE onnx_importer frontend_manager)
|
||||
|
||||
target_include_directories(onnx_ngraph_frontend PUBLIC $<BUILD_INTERFACE:${ONNX_FRONTEND_INCLUDE_DIR}>
|
||||
$<INSTALL_INTERFACE:${FRONTEND_INSTALL_INCLUDE}>)
|
||||
|
||||
target_include_directories(onnx_ngraph_frontend PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/src)
|
||||
|
||||
install(TARGETS onnx_ngraph_frontend EXPORT ngraphTargets
|
||||
RUNTIME DESTINATION ${NGRAPH_INSTALL_LIB} COMPONENT ngraph
|
||||
ARCHIVE DESTINATION ${NGRAPH_INSTALL_LIB} COMPONENT ngraph
|
||||
LIBRARY DESTINATION ${NGRAPH_INSTALL_LIB} COMPONENT ngraph)
|
||||
|
||||
install(DIRECTORY ${ONNX_FRONTEND_INCLUDE_DIR}/onnx_frontend
|
||||
DESTINATION ${FRONTEND_INSTALL_INCLUDE}
|
||||
COMPONENT ngraph_dev
|
||||
FILES_MATCHING PATTERN "*.hpp")
|
||||
|
||||
export(TARGETS onnx_ngraph_frontend NAMESPACE ngraph:: APPEND FILE "${NGRAPH_TARGETS_FILE}")
|
||||
@@ -0,0 +1,34 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <frontend_manager/frontend.hpp>
|
||||
|
||||
#ifdef onnx_ngraph_frontend_EXPORTS
|
||||
#define ONNX_FRONTEND_API NGRAPH_HELPER_DLL_EXPORT
|
||||
#else
|
||||
#define ONNX_FRONTEND_API NGRAPH_HELPER_DLL_IMPORT
|
||||
#endif
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
namespace frontend
|
||||
{
|
||||
class ONNX_FRONTEND_API FrontEndONNX : public FrontEnd
|
||||
{
|
||||
public:
|
||||
std::shared_ptr<ngraph::Function> convert(InputModel::Ptr model) const override;
|
||||
std::shared_ptr<ngraph::Function>
|
||||
convert(std::shared_ptr<ngraph::Function> partially_converted) const override;
|
||||
std::shared_ptr<ngraph::Function> decode(InputModel::Ptr model) const override;
|
||||
|
||||
protected:
|
||||
InputModel::Ptr
|
||||
load_impl(const std::vector<std::shared_ptr<Variant>>& params) const override;
|
||||
};
|
||||
|
||||
} // namespace frontend
|
||||
|
||||
} // namespace ngraph
|
||||
@@ -0,0 +1,56 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <frontend_manager/frontend_exceptions.hpp>
|
||||
#include <frontend_manager/frontend_manager.hpp>
|
||||
#include <input_model.hpp>
|
||||
#include <onnx_frontend/frontend.hpp>
|
||||
#include <onnx_import/onnx.hpp>
|
||||
|
||||
using namespace ngraph;
|
||||
using namespace ngraph::frontend;
|
||||
|
||||
extern "C" ONNX_FRONTEND_API FrontEndVersion GetAPIVersion()
|
||||
{
|
||||
return OV_FRONTEND_API_VERSION;
|
||||
}
|
||||
|
||||
extern "C" ONNX_FRONTEND_API void* GetFrontEndData()
|
||||
{
|
||||
FrontEndPluginInfo* res = new FrontEndPluginInfo();
|
||||
res->m_name = "onnx";
|
||||
res->m_creator = []() { return std::make_shared<FrontEndONNX>(); };
|
||||
return res;
|
||||
}
|
||||
|
||||
InputModel::Ptr FrontEndONNX::load_impl(const std::vector<std::shared_ptr<Variant>>& variants) const
|
||||
{
|
||||
NGRAPH_CHECK(variants.size() == 1,
|
||||
"Only one parameter to load function is expected. Got " +
|
||||
std::to_string(variants.size()));
|
||||
NGRAPH_CHECK(is_type<VariantWrapper<std::string>>(variants[0]),
|
||||
"Parameter to load function need to be a std::string");
|
||||
auto path = as_type_ptr<VariantWrapper<std::string>>(variants[0])->get();
|
||||
return std::make_shared<InputModelONNX>(path);
|
||||
}
|
||||
|
||||
std::shared_ptr<ngraph::Function> FrontEndONNX::convert(InputModel::Ptr model) const
|
||||
{
|
||||
auto model_onnx = std::dynamic_pointer_cast<InputModelONNX>(model);
|
||||
NGRAPH_CHECK(model_onnx != nullptr, "Invalid input model");
|
||||
return model_onnx->convert();
|
||||
}
|
||||
|
||||
std::shared_ptr<ngraph::Function>
|
||||
FrontEndONNX::convert(std::shared_ptr<ngraph::Function> partially_converted) const
|
||||
{
|
||||
return onnx_import::convert_decoded_function(partially_converted);
|
||||
}
|
||||
|
||||
std::shared_ptr<ngraph::Function> FrontEndONNX::decode(InputModel::Ptr model) const
|
||||
{
|
||||
auto model_onnx = std::dynamic_pointer_cast<InputModelONNX>(model);
|
||||
NGRAPH_CHECK(model_onnx != nullptr, "Invalid input model");
|
||||
return model_onnx->decode();
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#include <frontend_manager/frontend_exceptions.hpp>
|
||||
#include <input_model.hpp>
|
||||
#include <place.hpp>
|
||||
|
||||
using namespace ngraph;
|
||||
using namespace ngraph::frontend;
|
||||
|
||||
InputModelONNX::InputModelONNX(const std::string& path)
|
||||
: m_editor(path)
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<Place::Ptr> InputModelONNX::get_inputs() const
|
||||
{
|
||||
auto inputs = m_editor.model_inputs();
|
||||
std::vector<Place::Ptr> ret;
|
||||
ret.reserve(inputs.size());
|
||||
for (const auto& input : inputs)
|
||||
{
|
||||
ret.push_back(std::make_shared<PlaceTensorONNX>(input, m_editor));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
Place::Ptr InputModelONNX::get_place_by_tensor_name(const std::string& tensor_name) const
|
||||
{
|
||||
return std::make_shared<PlaceTensorONNX>(tensor_name, m_editor);
|
||||
}
|
||||
|
||||
void InputModelONNX::set_partial_shape(Place::Ptr place, const ngraph::PartialShape& shape)
|
||||
{
|
||||
std::map<std::string, ngraph::PartialShape> m;
|
||||
m[place->get_names()[0]] = shape;
|
||||
m_editor.set_input_shapes(m);
|
||||
}
|
||||
|
||||
void InputModelONNX::set_element_type(Place::Ptr place, const ngraph::element::Type& type)
|
||||
{
|
||||
std::map<std::string, ngraph::element::Type_t> m;
|
||||
m[place->get_names()[0]] = type;
|
||||
m_editor.set_input_types(m);
|
||||
}
|
||||
|
||||
std::shared_ptr<Function> InputModelONNX::decode()
|
||||
{
|
||||
return m_editor.decode();
|
||||
}
|
||||
|
||||
std::shared_ptr<Function> InputModelONNX::convert()
|
||||
{
|
||||
return m_editor.get_function();
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <frontend_manager/input_model.hpp>
|
||||
#include <onnx_editor/editor.hpp>
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
namespace frontend
|
||||
{
|
||||
class InputModelONNX : public InputModel
|
||||
{
|
||||
public:
|
||||
InputModelONNX(const std::string& path);
|
||||
|
||||
std::vector<Place::Ptr> get_inputs() const override;
|
||||
Place::Ptr get_place_by_tensor_name(const std::string& tensor_name) const override;
|
||||
void set_partial_shape(Place::Ptr place, const ngraph::PartialShape& shape) override;
|
||||
void set_element_type(Place::Ptr place, const ngraph::element::Type& type) override;
|
||||
|
||||
std::shared_ptr<Function> decode();
|
||||
std::shared_ptr<Function> convert();
|
||||
|
||||
private:
|
||||
onnx_editor::ONNXModelEditor m_editor;
|
||||
};
|
||||
|
||||
} // namespace frontend
|
||||
|
||||
} // namespace ngraph
|
||||
@@ -0,0 +1,78 @@
|
||||
// Copyright (C) 2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <frontend_manager/place.hpp>
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
namespace frontend
|
||||
{
|
||||
class PlaceInputEdgeONNX : public Place
|
||||
{
|
||||
public:
|
||||
PlaceInputEdgeONNX(const onnx_editor::InputEdge& edge)
|
||||
: m_edge(edge)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
onnx_editor::InputEdge m_edge;
|
||||
};
|
||||
|
||||
class PlaceOutputEdgeONNX : public Place
|
||||
{
|
||||
public:
|
||||
PlaceOutputEdgeONNX(const onnx_editor::OutputEdge& edge)
|
||||
: m_edge(edge)
|
||||
{
|
||||
}
|
||||
|
||||
private:
|
||||
onnx_editor::OutputEdge m_edge;
|
||||
};
|
||||
|
||||
class PlaceTensorONNX : public Place
|
||||
{
|
||||
public:
|
||||
PlaceTensorONNX(const std::string& name, const onnx_editor::ONNXModelEditor& editor)
|
||||
: m_name(name)
|
||||
, m_editor(editor)
|
||||
{
|
||||
}
|
||||
|
||||
std::vector<std::string> get_names() const override { return {m_name}; }
|
||||
|
||||
Place::Ptr get_producing_port() const override
|
||||
{
|
||||
return std::make_shared<PlaceOutputEdgeONNX>(m_editor.find_output_edge(m_name));
|
||||
}
|
||||
|
||||
std::vector<Place::Ptr> get_consuming_ports() const override
|
||||
{
|
||||
std::vector<Place::Ptr> ret;
|
||||
auto edges = m_editor.find_output_consumers(m_name);
|
||||
std::transform(edges.begin(),
|
||||
edges.end(),
|
||||
std::back_inserter(ret),
|
||||
[](const onnx_editor::InputEdge& edge) {
|
||||
return std::make_shared<PlaceInputEdgeONNX>(edge);
|
||||
});
|
||||
return ret;
|
||||
}
|
||||
|
||||
Ptr get_input_port(int input_port_index) const override
|
||||
{
|
||||
return std::make_shared<PlaceInputEdgeONNX>(m_editor.find_input_edge(
|
||||
onnx_editor::EditorNode(m_name), onnx_editor::EditorInput(input_port_index)));
|
||||
}
|
||||
|
||||
private:
|
||||
std::string m_name;
|
||||
const onnx_editor::ONNXModelEditor& m_editor;
|
||||
};
|
||||
} // namespace frontend
|
||||
|
||||
} // namespace ngraph
|
||||
@@ -161,6 +161,11 @@ namespace ngraph
|
||||
///
|
||||
bool is_correct_and_unambiguous_node(const EditorNode& node) const;
|
||||
|
||||
/// \brief Returns a nGraph function based on edited model
|
||||
/// decoded to framework nodes
|
||||
///
|
||||
std::shared_ptr<Function> decode();
|
||||
|
||||
private:
|
||||
void update_mapper_if_needed() const;
|
||||
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
// Copyright (C) 2018-2021 Intel Corporation
|
||||
// SPDX-License-Identifier: Apache-2.0
|
||||
//
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <onnx/onnx_pb.h>
|
||||
#include <ostream>
|
||||
#include <string>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "onnx_import/core/operator_set.hpp"
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
namespace onnx_import
|
||||
{
|
||||
/// \brief Type of container which stores opset version and domain in ONNX format
|
||||
using OpsetImports =
|
||||
::google::protobuf::RepeatedPtrField<ONNX_NAMESPACE::OperatorSetIdProto>;
|
||||
|
||||
std::string get_node_domain(const ONNX_NAMESPACE::NodeProto& node_proto);
|
||||
|
||||
std::int64_t get_opset_version(const ONNX_NAMESPACE::ModelProto& model_proto,
|
||||
const std::string& domain);
|
||||
|
||||
class Model
|
||||
{
|
||||
public:
|
||||
Model() = delete;
|
||||
explicit Model(std::shared_ptr<ONNX_NAMESPACE::ModelProto> model_proto);
|
||||
|
||||
Model(const Model&) = delete;
|
||||
Model(Model&&) = delete;
|
||||
|
||||
Model& operator=(const Model&) = delete;
|
||||
Model& operator=(Model&&) = delete;
|
||||
|
||||
const std::string& get_producer_name() const { return m_model_proto->producer_name(); }
|
||||
const ONNX_NAMESPACE::GraphProto& get_graph() const { return m_model_proto->graph(); }
|
||||
std::int64_t get_model_version() const { return m_model_proto->model_version(); }
|
||||
const OpsetImports& get_opset_imports() const;
|
||||
const std::string& get_producer_version() const
|
||||
{
|
||||
return m_model_proto->producer_version();
|
||||
}
|
||||
|
||||
/// \brief Access an operator object by its type name and domain name
|
||||
/// The function will return the operator object if it exists, or report an error
|
||||
/// in case of domain or operator absence.
|
||||
/// \param name type name of the operator object,
|
||||
/// \param domain domain name of the operator object.
|
||||
/// \return Reference to the operator object.
|
||||
/// \throw error::UnknownDomain there is no operator set defined for the given
|
||||
/// domain,
|
||||
/// \throw error::UnknownOperator the given operator type name does not exist in
|
||||
/// operator set.
|
||||
const Operator& get_operator(const std::string& name, const std::string& domain) const;
|
||||
|
||||
/// \brief Check availability of operator base on NodeProto.
|
||||
/// \return `true` if the operator is available, otherwise it returns `false`.
|
||||
bool is_operator_available(const ONNX_NAMESPACE::NodeProto& node_proto) const;
|
||||
|
||||
/// \brief Enable operators from provided domain to use by this model.
|
||||
///
|
||||
/// \note This function makes visible all currently registered in provided domain
|
||||
/// operators for use in this model.
|
||||
///
|
||||
/// \param[in] domain The domain name.
|
||||
///
|
||||
void enable_opset_domain(const std::string& domain);
|
||||
|
||||
private:
|
||||
const std::shared_ptr<ONNX_NAMESPACE::ModelProto> m_model_proto;
|
||||
std::unordered_map<std::string, OperatorSet> m_opset;
|
||||
};
|
||||
|
||||
inline std::ostream& operator<<(std::ostream& outs, const Model& model)
|
||||
{
|
||||
return (outs << "<Model: " << model.get_producer_name() << ">");
|
||||
}
|
||||
|
||||
} // namespace onnx_import
|
||||
|
||||
} // namespace ngraph
|
||||
@@ -58,7 +58,6 @@ namespace ngraph
|
||||
Node& operator=(const Node&) = delete;
|
||||
|
||||
OutputVector get_ng_inputs() const;
|
||||
OutputVector get_ng_nodes() const;
|
||||
const std::string& domain() const;
|
||||
const std::string& op_type() const;
|
||||
const std::string& get_name() const;
|
||||
|
||||
@@ -72,6 +72,14 @@ namespace ngraph
|
||||
/// \return An nGraph function that represents a single output from the created graph.
|
||||
ONNX_IMPORTER_API
|
||||
std::shared_ptr<Function> import_onnx_model(const std::string& file_path);
|
||||
|
||||
/// \brief Converts a nGraph function (onnx model decoded to function with
|
||||
/// ONNXFrameworkNode(s))
|
||||
/// to a complete function with actual compute operations
|
||||
///
|
||||
/// \return A nGraph function.
|
||||
ONNX_IMPORTER_API
|
||||
std::shared_ptr<Function> convert_decoded_function(std::shared_ptr<Function> function);
|
||||
} // namespace onnx_import
|
||||
|
||||
} // namespace ngraph
|
||||
@@ -36,8 +36,24 @@ namespace ngraph
|
||||
///
|
||||
/// \return An nGraph function that represents a single output from the created
|
||||
/// graph.
|
||||
std::shared_ptr<Function> import_onnx_model(ONNX_NAMESPACE::ModelProto& model_proto,
|
||||
const std::string& model_path);
|
||||
std::shared_ptr<Function>
|
||||
import_onnx_model(std::shared_ptr<ONNX_NAMESPACE::ModelProto> model_proto,
|
||||
const std::string& model_path);
|
||||
|
||||
/// \brief Decode ONNX model to nGraph function with ONNXFrameworkNode(s)
|
||||
///
|
||||
/// \param[in] model_proto Reference to a GraphProto object.
|
||||
/// \param[in] model_path The path to the imported onnx model.
|
||||
/// It is required if the imported model uses data saved in
|
||||
/// external files.
|
||||
///
|
||||
/// \return A nGraph function with ONNXFrameworkNodes
|
||||
ONNX_IMPORTER_API
|
||||
std::shared_ptr<Function>
|
||||
decode_to_framework_nodes(std::shared_ptr<ONNX_NAMESPACE::ModelProto> model_proto,
|
||||
const std::string& model_path);
|
||||
|
||||
std::shared_ptr<Function> convert_decoded_function(std::shared_ptr<Function> function);
|
||||
} // namespace detail
|
||||
} // namespace onnx_import
|
||||
} // namespace ngraph
|
||||
@@ -4,8 +4,8 @@
|
||||
|
||||
#include "core/attribute.hpp"
|
||||
#include "core/graph.hpp"
|
||||
#include "core/model.hpp"
|
||||
#include "ngraph/log.hpp"
|
||||
#include "onnx_import/core/model.hpp"
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
@@ -18,15 +18,14 @@ namespace ngraph
|
||||
throw error::attribute::InvalidData{m_attribute_proto->type()};
|
||||
}
|
||||
|
||||
auto model_proto = common::make_unique<ONNX_NAMESPACE::ModelProto>();
|
||||
auto model_proto = std::make_shared<ONNX_NAMESPACE::ModelProto>();
|
||||
|
||||
const auto& graph = m_attribute_proto->g();
|
||||
model_proto->mutable_graph()->CopyFrom(graph);
|
||||
|
||||
// set opset version and domain from the parent graph
|
||||
model_proto->mutable_opset_import()->CopyFrom(parent_graph.get_opset_imports());
|
||||
auto model = common::make_unique<Model>(std::move(model_proto));
|
||||
return Subgraph{std::move(model), parent_graph};
|
||||
return Subgraph{model_proto, parent_graph};
|
||||
}
|
||||
|
||||
} // namespace onnx_import
|
||||
|
||||
@@ -9,12 +9,14 @@
|
||||
|
||||
#include "core/graph.hpp"
|
||||
#include "core/null_node.hpp"
|
||||
#include "core/value_info.hpp"
|
||||
#include "default_opset.hpp"
|
||||
#include "exceptions.hpp"
|
||||
#include "ngraph/log.hpp"
|
||||
#include "ngraph/node.hpp"
|
||||
#include "ngraph/provenance.hpp"
|
||||
#include "onnx_framework_node.hpp"
|
||||
#include "onnx_import/core/node.hpp"
|
||||
#include "onnx_import/onnx_framework_node.hpp"
|
||||
#include "utils/common.hpp"
|
||||
#include "utils/provenance_tag.hpp"
|
||||
|
||||
@@ -51,15 +53,62 @@ namespace ngraph
|
||||
std::string domain = get_node_domain(node_proto);
|
||||
return (domain.empty() ? "" : domain + ".") + node_proto.op_type();
|
||||
}
|
||||
|
||||
void add_provenance_tag_to_initializer(const Tensor& tensor,
|
||||
std::shared_ptr<default_opset::Constant> node)
|
||||
{
|
||||
if (!ngraph::get_provenance_enabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string tag =
|
||||
detail::build_input_provenance_tag(tensor.get_name(), tensor.get_shape());
|
||||
|
||||
node->add_provenance_tag(tag);
|
||||
}
|
||||
|
||||
void add_provenance_tag_to_input(const ValueInfo& input,
|
||||
std::shared_ptr<ngraph::Node> node)
|
||||
{
|
||||
if (!ngraph::get_provenance_enabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string tag =
|
||||
detail::build_input_provenance_tag(input.get_name(), input.get_shape());
|
||||
|
||||
node->add_provenance_tag(tag);
|
||||
}
|
||||
|
||||
void add_provenance_tags(const Node& onnx_node, const OutputVector& ng_node_vector)
|
||||
{
|
||||
if (!ngraph::get_provenance_enabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto tag = detail::build_op_provenance_tag(onnx_node);
|
||||
const auto ng_inputs = onnx_node.get_ng_inputs();
|
||||
|
||||
ngraph::traverse_nodes(
|
||||
as_node_vector(ng_node_vector),
|
||||
[&tag](std::shared_ptr<ngraph::Node> ng_node) {
|
||||
ng_node->add_provenance_tag(tag);
|
||||
},
|
||||
as_node_vector(ng_inputs));
|
||||
}
|
||||
} // namespace detail
|
||||
|
||||
Graph::Graph(std::unique_ptr<Model>&& model)
|
||||
: Graph(std::move(model), common::make_unique<GraphCache>())
|
||||
Graph::Graph(std::shared_ptr<ONNX_NAMESPACE::ModelProto> model_proto)
|
||||
: Graph(model_proto, common::make_unique<GraphCache>())
|
||||
{
|
||||
}
|
||||
|
||||
Graph::Graph(std::unique_ptr<Model>&& model, std::unique_ptr<GraphCache>&& cache)
|
||||
: m_model{std::move(model)}
|
||||
Graph::Graph(std::shared_ptr<ONNX_NAMESPACE::ModelProto> model_proto,
|
||||
std::unique_ptr<GraphCache>&& cache)
|
||||
: m_model{common::make_unique<Model>(model_proto)}
|
||||
, m_cache{std::move(cache)}
|
||||
{
|
||||
std::map<std::string, Tensor> initializers;
|
||||
@@ -96,7 +145,7 @@ namespace ngraph
|
||||
}
|
||||
|
||||
initializers.emplace(initializer_tensor.name(), tensor);
|
||||
add_provenance_tag_to_initializer(tensor, ng_constant);
|
||||
detail::add_provenance_tag_to_initializer(tensor, ng_constant);
|
||||
m_cache->emplace_node(initializer_tensor.name(), std::move(ng_constant));
|
||||
}
|
||||
}
|
||||
@@ -104,26 +153,18 @@ namespace ngraph
|
||||
// Process all ONNX graph inputs, convert them to nGraph nodes and store in cache
|
||||
for (const auto& input : m_model->get_graph().input())
|
||||
{
|
||||
m_inputs.emplace_back(input);
|
||||
|
||||
// Check if a Constant node was already created from an initializer
|
||||
if (m_cache->contains(input.name()))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto value_info = m_inputs.back();
|
||||
ValueInfo value_info{input};
|
||||
auto ng_node = value_info.get_ng_node(m_parameters, initializers);
|
||||
add_provenance_tag_to_input(value_info, ng_node);
|
||||
detail::add_provenance_tag_to_input(value_info, ng_node);
|
||||
m_cache->emplace_node(input.name(), std::move(ng_node));
|
||||
}
|
||||
|
||||
// Process all graph outputs
|
||||
for (const auto& output : m_model->get_graph().output())
|
||||
{
|
||||
m_outputs.emplace_back(output);
|
||||
}
|
||||
|
||||
// Verify that ONNX graph contains only nodes of available operator types
|
||||
std::map<std::string, std::reference_wrapper<const ONNX_NAMESPACE::NodeProto>>
|
||||
unknown_operators;
|
||||
@@ -163,19 +204,13 @@ namespace ngraph
|
||||
// Process ONNX graph nodes, convert to nGraph nodes
|
||||
for (const auto& node_proto : m_model->get_graph().node())
|
||||
{
|
||||
m_nodes.emplace_back(node_proto, *this);
|
||||
const Node& node{m_nodes.back()};
|
||||
const Node node{node_proto, *this};
|
||||
if (node.has_subgraph())
|
||||
{
|
||||
auto subgraph = node.get_subgraph();
|
||||
auto body_func = subgraph->convert();
|
||||
}
|
||||
OutputVector ng_nodes{node.get_ng_nodes()};
|
||||
set_friendly_names(node, ng_nodes);
|
||||
for (std::size_t i{0}; i < node.get_outputs_size(); ++i)
|
||||
{
|
||||
m_cache->emplace_node(node.output(i), std::move(ng_nodes.at(i)));
|
||||
}
|
||||
OutputVector ng_nodes{make_ng_nodes(node)};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -186,11 +221,14 @@ namespace ngraph
|
||||
if ((*param_it)->get_output_target_inputs(0).size() == 0)
|
||||
{
|
||||
const auto& name = (*param_it)->get_friendly_name();
|
||||
auto out_it = std::find_if(
|
||||
m_outputs.begin(), m_outputs.end(), [&name](const ValueInfo& info) {
|
||||
return info.get_name() == name;
|
||||
});
|
||||
if (out_it == m_outputs.end())
|
||||
const auto& onnx_outputs = m_model->get_graph().output();
|
||||
auto out_it =
|
||||
std::find_if(onnx_outputs.begin(),
|
||||
onnx_outputs.end(),
|
||||
[&name](const ONNX_NAMESPACE::ValueInfoProto& output) -> bool {
|
||||
return output.name() == name;
|
||||
});
|
||||
if (out_it == onnx_outputs.end())
|
||||
{
|
||||
m_cache->remove_node(name);
|
||||
param_it = m_parameters.erase(param_it);
|
||||
@@ -213,8 +251,7 @@ namespace ngraph
|
||||
// Process ONNX graph nodes, convert to nGraph nodes
|
||||
for (const auto& node_proto : m_model->get_graph().node())
|
||||
{
|
||||
m_nodes.emplace_back(node_proto, *this);
|
||||
const Node& node{m_nodes.back()};
|
||||
const Node node{node_proto, *this};
|
||||
std::shared_ptr<frontend::ONNXFrameworkNode> framework_node;
|
||||
if (node.has_subgraph())
|
||||
{
|
||||
@@ -223,12 +260,13 @@ namespace ngraph
|
||||
auto inputs = node.get_ng_inputs();
|
||||
for (const auto& input : subgraph->get_inputs_from_parent())
|
||||
inputs.push_back(input);
|
||||
framework_node =
|
||||
std::make_shared<ngraph::frontend::ONNXSubgraphFrameworkNode>(node, inputs);
|
||||
framework_node = std::make_shared<ngraph::frontend::ONNXSubgraphFrameworkNode>(
|
||||
shared_from_this(), node, inputs);
|
||||
}
|
||||
else
|
||||
{
|
||||
framework_node = std::make_shared<ngraph::frontend::ONNXFrameworkNode>(node);
|
||||
framework_node = std::make_shared<ngraph::frontend::ONNXFrameworkNode>(
|
||||
shared_from_this(), node);
|
||||
}
|
||||
OutputVector ng_nodes{framework_node->outputs()};
|
||||
set_friendly_names(node, ng_nodes);
|
||||
@@ -245,9 +283,10 @@ namespace ngraph
|
||||
std::shared_ptr<Function> Graph::create_function()
|
||||
{
|
||||
auto function = std::make_shared<Function>(get_ng_outputs(), m_parameters, get_name());
|
||||
const auto& onnx_outputs = m_model->get_graph().output();
|
||||
for (std::size_t i{0}; i < function->get_output_size(); ++i)
|
||||
{
|
||||
function->get_output_op(i)->set_friendly_name(m_outputs.at(i).get_name());
|
||||
function->get_output_op(i)->set_friendly_name(onnx_outputs.Get(i).name());
|
||||
}
|
||||
return function;
|
||||
}
|
||||
@@ -307,7 +346,7 @@ namespace ngraph
|
||||
std::rethrow_exception(std::current_exception());
|
||||
}
|
||||
set_friendly_names(onnx_node, ng_node_vector);
|
||||
add_provenance_tags(onnx_node, ng_node_vector);
|
||||
detail::add_provenance_tags(onnx_node, ng_node_vector);
|
||||
|
||||
for (std::size_t i{0}; i < onnx_node.get_outputs_size(); ++i)
|
||||
{
|
||||
@@ -340,58 +379,14 @@ namespace ngraph
|
||||
}
|
||||
}
|
||||
|
||||
void Graph::add_provenance_tag_to_initializer(
|
||||
const Tensor& tensor, std::shared_ptr<default_opset::Constant> node) const
|
||||
{
|
||||
if (!ngraph::get_provenance_enabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string tag =
|
||||
detail::build_input_provenance_tag(tensor.get_name(), tensor.get_shape());
|
||||
|
||||
node->add_provenance_tag(tag);
|
||||
}
|
||||
|
||||
void Graph::add_provenance_tag_to_input(const ValueInfo& input,
|
||||
std::shared_ptr<ngraph::Node> node) const
|
||||
{
|
||||
if (!ngraph::get_provenance_enabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string tag =
|
||||
detail::build_input_provenance_tag(input.get_name(), input.get_shape());
|
||||
|
||||
node->add_provenance_tag(tag);
|
||||
}
|
||||
|
||||
void Graph::add_provenance_tags(const Node& onnx_node,
|
||||
const OutputVector& ng_node_vector) const
|
||||
{
|
||||
if (!ngraph::get_provenance_enabled())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const auto tag = detail::build_op_provenance_tag(onnx_node);
|
||||
const auto ng_inputs = onnx_node.get_ng_inputs();
|
||||
|
||||
ngraph::traverse_nodes(
|
||||
as_node_vector(ng_node_vector),
|
||||
[&tag](std::shared_ptr<ngraph::Node> ng_node) { ng_node->add_provenance_tag(tag); },
|
||||
as_node_vector(ng_inputs));
|
||||
}
|
||||
|
||||
const OpsetImports& Graph::get_opset_imports() const
|
||||
{
|
||||
return m_model->get_opset_imports();
|
||||
}
|
||||
|
||||
Subgraph::Subgraph(std::unique_ptr<Model>&& model, const Graph& parent_graph)
|
||||
: Graph(std::move(model), common::make_unique<GraphCache>())
|
||||
Subgraph::Subgraph(std::shared_ptr<ONNX_NAMESPACE::ModelProto> model_proto,
|
||||
const Graph& parent_graph)
|
||||
: Graph(model_proto, common::make_unique<GraphCache>())
|
||||
, m_parent_graph_cache(&parent_graph.get_graph_cache())
|
||||
{
|
||||
}
|
||||
|
||||
@@ -10,20 +10,18 @@
|
||||
#include <vector>
|
||||
|
||||
#include "core/graph_cache.hpp"
|
||||
#include "core/model.hpp"
|
||||
#include "core/value_info.hpp"
|
||||
#include "default_opset.hpp"
|
||||
#include "ngraph/op/parameter.hpp"
|
||||
#include "onnx_import/core/model.hpp"
|
||||
#include "onnx_import/core/operator_set.hpp"
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
namespace onnx_import
|
||||
{
|
||||
class Graph
|
||||
class Graph : public std::enable_shared_from_this<Graph>
|
||||
{
|
||||
public:
|
||||
Graph(std::unique_ptr<Model>&& model);
|
||||
Graph(std::shared_ptr<ONNX_NAMESPACE::ModelProto> model_proto);
|
||||
Graph() = delete;
|
||||
|
||||
Graph(const Graph&) = delete;
|
||||
@@ -31,35 +29,24 @@ namespace ngraph
|
||||
|
||||
Graph& operator=(const Graph&) = delete;
|
||||
Graph& operator=(Graph&&) = default;
|
||||
virtual std::shared_ptr<Function> convert();
|
||||
std::shared_ptr<Function> decode();
|
||||
const std::vector<Node>& get_nodes() const { return m_nodes; }
|
||||
const std::vector<ValueInfo>& get_inputs() const { return m_inputs; }
|
||||
const std::vector<ValueInfo>& get_outputs() const { return m_outputs; }
|
||||
virtual std::shared_ptr<Function> convert();
|
||||
OutputVector get_ng_outputs() const;
|
||||
const std::string& get_name() const { return m_model->get_graph().name(); }
|
||||
const GraphCache& get_graph_cache() const;
|
||||
const ParameterVector& get_ng_parameters() const { return m_parameters; }
|
||||
virtual Output<ngraph::Node> get_ng_node_from_cache(const std::string& name) const;
|
||||
const std::string& get_name() const { return m_model->get_graph().name(); }
|
||||
OutputVector make_ng_nodes(const Node& onnx_node) const;
|
||||
const GraphCache& get_graph_cache() const;
|
||||
const OpsetImports& get_opset_imports() const;
|
||||
virtual ~Graph() = default;
|
||||
|
||||
protected:
|
||||
Graph(std::unique_ptr<Model>&& model, std::unique_ptr<GraphCache>&& cache);
|
||||
Graph(std::shared_ptr<ONNX_NAMESPACE::ModelProto> model,
|
||||
std::unique_ptr<GraphCache>&& cache);
|
||||
|
||||
void set_friendly_names(const Node& onnx_node,
|
||||
const OutputVector& ng_node_vector) const;
|
||||
|
||||
void add_provenance_tag_to_initializer(
|
||||
const Tensor& initializer, std::shared_ptr<default_opset::Constant> node) const;
|
||||
|
||||
void add_provenance_tag_to_input(const ValueInfo& input,
|
||||
std::shared_ptr<ngraph::Node> node) const;
|
||||
|
||||
void add_provenance_tags(const Node& onnx_node,
|
||||
const OutputVector& ng_node_vector) const;
|
||||
|
||||
protected:
|
||||
virtual void decode_to_framework_nodes();
|
||||
void convert_to_ngraph_nodes();
|
||||
@@ -72,8 +59,6 @@ namespace ngraph
|
||||
|
||||
private:
|
||||
std::vector<Node> m_nodes;
|
||||
std::vector<ValueInfo> m_inputs;
|
||||
std::vector<ValueInfo> m_outputs;
|
||||
};
|
||||
|
||||
/// \brief Representation of ONNX subgraph. It is used for example by ONNX Loop op.
|
||||
@@ -86,7 +71,7 @@ namespace ngraph
|
||||
///
|
||||
/// \param[in] model The ONNX model object.
|
||||
/// \param[in] parent_graph The reference to the parent graph.
|
||||
Subgraph(std::unique_ptr<Model>&& model, const Graph& parent_graph);
|
||||
Subgraph(std::shared_ptr<ONNX_NAMESPACE::ModelProto> model, const Graph& parent_graph);
|
||||
|
||||
/// \brief Return nodes which are on the edge the subgraph and the parent graph.
|
||||
/// \return Vector of edge nodes from parent scope.
|
||||
|
||||
@@ -4,9 +4,9 @@
|
||||
|
||||
#include <onnx/onnx_pb.h>
|
||||
|
||||
#include "core/model.hpp"
|
||||
#include "ngraph/log.hpp"
|
||||
#include "onnx_import/onnx_framework_node.hpp"
|
||||
#include "onnx_framework_node.hpp"
|
||||
#include "onnx_import/core/model.hpp"
|
||||
#include "ops_bridge.hpp"
|
||||
|
||||
namespace ngraph
|
||||
@@ -32,8 +32,8 @@ namespace ngraph
|
||||
throw ngraph_error("Couldn't find operator set's version for domain: " + domain + ".");
|
||||
}
|
||||
|
||||
Model::Model(std::unique_ptr<ONNX_NAMESPACE::ModelProto>&& model_proto)
|
||||
: m_model_proto{std::move(model_proto)}
|
||||
Model::Model(std::shared_ptr<ONNX_NAMESPACE::ModelProto> model_proto)
|
||||
: m_model_proto{model_proto}
|
||||
{
|
||||
// Walk through the elements of opset_import field and register operator sets
|
||||
// for each domain. An exception UnknownDomain() will raise if the domain is
|
||||
|
||||
@@ -28,7 +28,7 @@ namespace ngraph
|
||||
{
|
||||
public:
|
||||
Model() = delete;
|
||||
explicit Model(std::unique_ptr<ONNX_NAMESPACE::ModelProto>&& model_proto);
|
||||
explicit Model(std::shared_ptr<ONNX_NAMESPACE::ModelProto> model_proto);
|
||||
|
||||
Model(const Model&) = delete;
|
||||
Model(Model&&) = delete;
|
||||
@@ -71,7 +71,7 @@ namespace ngraph
|
||||
void enable_opset_domain(const std::string& domain);
|
||||
|
||||
private:
|
||||
const std::unique_ptr<ONNX_NAMESPACE::ModelProto> m_model_proto;
|
||||
const std::shared_ptr<ONNX_NAMESPACE::ModelProto> m_model_proto;
|
||||
std::unordered_map<std::string, OperatorSet> m_opset;
|
||||
};
|
||||
|
||||
|
||||
@@ -53,7 +53,6 @@ namespace ngraph
|
||||
}
|
||||
|
||||
const std::vector<Attribute>& attributes() const;
|
||||
OutputVector get_ng_nodes(const Node& node) const;
|
||||
OutputVector get_ng_inputs() const;
|
||||
|
||||
const std::string& domain() const;
|
||||
@@ -172,11 +171,6 @@ namespace ngraph
|
||||
return get_subgraph_from_attribute(name);
|
||||
}
|
||||
|
||||
OutputVector Node::Impl::get_ng_nodes(const Node& node) const
|
||||
{
|
||||
return m_graph->make_ng_nodes(node);
|
||||
}
|
||||
|
||||
OutputVector Node::Impl::get_ng_inputs() const
|
||||
{
|
||||
OutputVector result;
|
||||
@@ -232,7 +226,6 @@ namespace ngraph
|
||||
}
|
||||
|
||||
OutputVector Node::get_ng_inputs() const { return m_pimpl->get_ng_inputs(); }
|
||||
OutputVector Node::get_ng_nodes() const { return m_pimpl->get_ng_nodes(*this); }
|
||||
const std::string& Node::domain() const { return m_pimpl->domain(); }
|
||||
const std::string& Node::op_type() const { return m_pimpl->op_type(); }
|
||||
const std::string& Node::get_description() const { return m_pimpl->description(); }
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
#include <onnx/defs/function.h>
|
||||
#include <onnx/defs/schema.h>
|
||||
|
||||
#include "core/model.hpp"
|
||||
#include "core/transform.hpp"
|
||||
#include "onnx_import/core/model.hpp"
|
||||
|
||||
#include "ngraph/file_util.hpp"
|
||||
#include "ops_bridge.hpp"
|
||||
|
||||
@@ -187,19 +187,20 @@ namespace
|
||||
/// \brief A helper class used to hold the ModelProto object as its field
|
||||
struct onnx_editor::ONNXModelEditor::Impl
|
||||
{
|
||||
ONNX_NAMESPACE::ModelProto m_model_proto;
|
||||
std::shared_ptr<ONNX_NAMESPACE::ModelProto> m_model_proto;
|
||||
EdgeMapper m_edge_mapper;
|
||||
bool m_is_mapper_updated = false;
|
||||
|
||||
Impl() = delete;
|
||||
|
||||
Impl(const std::string& model_path)
|
||||
: m_model_proto{onnx_common::parse_from_file(model_path)}
|
||||
: m_model_proto{std::make_shared<ONNX_NAMESPACE::ModelProto>(
|
||||
onnx_common::parse_from_file(model_path))}
|
||||
{
|
||||
}
|
||||
|
||||
void infer_shapes() { ONNX_NAMESPACE::shape_inference::InferShapes(m_model_proto); }
|
||||
void remove_shape_inference_info() { m_model_proto.mutable_graph()->clear_value_info(); }
|
||||
void infer_shapes() { ONNX_NAMESPACE::shape_inference::InferShapes(*m_model_proto.get()); }
|
||||
void remove_shape_inference_info() { m_model_proto->mutable_graph()->clear_value_info(); }
|
||||
};
|
||||
|
||||
onnx_editor::ONNXModelEditor::ONNXModelEditor(const std::string& model_path)
|
||||
@@ -222,7 +223,7 @@ void onnx_editor::ONNXModelEditor::serialize(const std::string& out_file_path) c
|
||||
throw ngraph_error("Could not open the file: " + out_file_path);
|
||||
};
|
||||
|
||||
if (!m_pimpl->m_model_proto.SerializeToOstream(&out_file))
|
||||
if (!m_pimpl->m_model_proto->SerializeToOstream(&out_file))
|
||||
{
|
||||
throw ngraph_error("Could not serialize the model to: " + out_file_path);
|
||||
}
|
||||
@@ -235,7 +236,7 @@ void onnx_editor::ONNXModelEditor::serialize(const std::string& out_file_path) c
|
||||
void onnx_editor::ONNXModelEditor::set_input_types(
|
||||
const std::map<std::string, element::Type_t>& input_types)
|
||||
{
|
||||
auto* onnx_graph = m_pimpl->m_model_proto.mutable_graph();
|
||||
auto* onnx_graph = m_pimpl->m_model_proto->mutable_graph();
|
||||
|
||||
for (const auto& input_desc : input_types)
|
||||
{
|
||||
@@ -256,7 +257,7 @@ void onnx_editor::ONNXModelEditor::set_input_types(
|
||||
void onnx_editor::ONNXModelEditor::set_input_shapes(
|
||||
const std::map<std::string, ngraph::PartialShape>& input_shapes)
|
||||
{
|
||||
auto* onnx_graph = m_pimpl->m_model_proto.mutable_graph();
|
||||
auto* onnx_graph = m_pimpl->m_model_proto->mutable_graph();
|
||||
|
||||
for (const auto& input_desc : input_shapes)
|
||||
{
|
||||
@@ -283,7 +284,7 @@ void onnx_editor::ONNXModelEditor::cut_graph_fragment(const std::vector<InputEdg
|
||||
|
||||
m_pimpl->infer_shapes();
|
||||
|
||||
SubgraphExtractor editor{*(m_pimpl->m_model_proto.mutable_graph())};
|
||||
SubgraphExtractor editor{*(m_pimpl->m_model_proto->mutable_graph())};
|
||||
editor.add_new_inputs(inputs);
|
||||
editor.add_new_outputs(outputs);
|
||||
editor.extract_subgraph(outputs);
|
||||
@@ -294,7 +295,7 @@ void onnx_editor::ONNXModelEditor::cut_graph_fragment(const std::vector<InputEdg
|
||||
|
||||
std::vector<std::string> onnx_editor::ONNXModelEditor::model_inputs() const
|
||||
{
|
||||
const auto& graph = m_pimpl->m_model_proto.graph();
|
||||
const auto& graph = m_pimpl->m_model_proto->graph();
|
||||
|
||||
std::vector<std::string> inputs_and_initializers;
|
||||
inputs_and_initializers.reserve(graph.input_size() + graph.initializer_size());
|
||||
@@ -314,7 +315,7 @@ std::vector<std::string> onnx_editor::ONNXModelEditor::model_inputs() const
|
||||
|
||||
std::string onnx_editor::ONNXModelEditor::model_string() const
|
||||
{
|
||||
return m_pimpl->m_model_proto.SerializeAsString();
|
||||
return m_pimpl->m_model_proto->SerializeAsString();
|
||||
}
|
||||
|
||||
std::shared_ptr<Function> onnx_editor::ONNXModelEditor::get_function() const
|
||||
@@ -325,7 +326,7 @@ std::shared_ptr<Function> onnx_editor::ONNXModelEditor::get_function() const
|
||||
void onnx_editor::ONNXModelEditor::set_input_values(
|
||||
const std::map<std::string, std::shared_ptr<ngraph::op::Constant>>& input_values)
|
||||
{
|
||||
auto onnx_graph = m_pimpl->m_model_proto.mutable_graph();
|
||||
auto onnx_graph = m_pimpl->m_model_proto->mutable_graph();
|
||||
|
||||
for (const auto& input : input_values)
|
||||
{
|
||||
@@ -354,7 +355,7 @@ void onnx_editor::ONNXModelEditor::update_mapper_if_needed() const
|
||||
{
|
||||
if (!m_pimpl->m_is_mapper_updated)
|
||||
{
|
||||
m_pimpl->m_edge_mapper = EdgeMapper(m_pimpl->m_model_proto.graph());
|
||||
m_pimpl->m_edge_mapper = EdgeMapper(m_pimpl->m_model_proto->graph());
|
||||
}
|
||||
m_pimpl->m_is_mapper_updated = true;
|
||||
}
|
||||
@@ -391,3 +392,8 @@ bool onnx_editor::ONNXModelEditor::is_correct_and_unambiguous_node(const EditorN
|
||||
update_mapper_if_needed();
|
||||
return m_pimpl->m_edge_mapper.is_correct_and_unambiguous_node(node);
|
||||
}
|
||||
|
||||
std::shared_ptr<Function> onnx_editor::ONNXModelEditor::decode()
|
||||
{
|
||||
return onnx_import::detail::decode_to_framework_nodes(m_pimpl->m_model_proto, m_model_path);
|
||||
}
|
||||
@@ -19,8 +19,8 @@ namespace ngraph
|
||||
std::shared_ptr<Function> import_onnx_model(std::istream& stream,
|
||||
const std::string& model_path)
|
||||
{
|
||||
ONNX_NAMESPACE::ModelProto model_proto{onnx_common::parse_from_istream(stream)};
|
||||
|
||||
auto model_proto = std::make_shared<ONNX_NAMESPACE::ModelProto>(
|
||||
onnx_common::parse_from_istream(stream));
|
||||
return detail::import_onnx_model(model_proto, model_path);
|
||||
}
|
||||
|
||||
@@ -58,6 +58,11 @@ namespace ngraph
|
||||
op_name, version, domain == "ai.onnx" ? "" : domain);
|
||||
}
|
||||
|
||||
std::shared_ptr<Function> convert_decoded_function(std::shared_ptr<Function> function)
|
||||
{
|
||||
return detail::convert_decoded_function(function);
|
||||
}
|
||||
|
||||
} // namespace onnx_import
|
||||
|
||||
} // namespace ngraph
|
||||
@@ -14,7 +14,7 @@
|
||||
// limitations under the License.
|
||||
//*****************************************************************************
|
||||
|
||||
#include <onnx_import/onnx_framework_node.hpp>
|
||||
#include <onnx_framework_node.hpp>
|
||||
|
||||
namespace ngraph
|
||||
{
|
||||
@@ -25,7 +25,7 @@ namespace ngraph
|
||||
std::shared_ptr<Node>
|
||||
ONNXFrameworkNode::clone_with_new_inputs(const OutputVector& inputs) const
|
||||
{
|
||||
return std::make_shared<ONNXFrameworkNode>(m_node, inputs);
|
||||
return std::make_shared<ONNXFrameworkNode>(m_graph, m_node, inputs);
|
||||
}
|
||||
|
||||
NGRAPH_RTTI_DEFINITION(ONNXSubgraphFrameworkNode, "ONNXSubgraphFrameworkNode", 1);
|
||||
|
||||
+28
-11
@@ -17,6 +17,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <core/graph.hpp>
|
||||
#include <ngraph/function.hpp>
|
||||
#include <ngraph/graph_util.hpp>
|
||||
#include <ngraph/visibility.hpp>
|
||||
#include <ngraph_ops/framework_node.hpp>
|
||||
#include <onnx_import/core/node.hpp>
|
||||
@@ -41,19 +43,32 @@ namespace ngraph
|
||||
public:
|
||||
NGRAPH_RTTI_DECLARATION;
|
||||
|
||||
ONNXFrameworkNode(const onnx_import::Node& node)
|
||||
ONNXFrameworkNode(std::shared_ptr<onnx_import::Graph> graph,
|
||||
const onnx_import::Node& node)
|
||||
: FrameworkNode(node.get_ng_inputs(), node.get_outputs_size())
|
||||
, m_node(node)
|
||||
, m_graph(graph)
|
||||
{
|
||||
}
|
||||
|
||||
ONNXFrameworkNode(const onnx_import::Node& node, const OutputVector& inputs)
|
||||
ONNXFrameworkNode(std::shared_ptr<onnx_import::Graph> graph,
|
||||
const onnx_import::Node& node,
|
||||
const OutputVector& inputs)
|
||||
: FrameworkNode(inputs, node.get_outputs_size())
|
||||
, m_node(node)
|
||||
, m_graph(graph)
|
||||
{
|
||||
}
|
||||
|
||||
const onnx_import::Node& get_onnx_node() const { return m_node; }
|
||||
OutputVector get_ng_nodes() const
|
||||
{
|
||||
OutputVector ng_nodes{m_graph->make_ng_nodes(m_node)};
|
||||
if (ng_nodes.size() > get_output_size())
|
||||
{
|
||||
ng_nodes.resize(get_output_size());
|
||||
}
|
||||
return ng_nodes;
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<Node>
|
||||
clone_with_new_inputs(const OutputVector& inputs) const override;
|
||||
@@ -68,8 +83,11 @@ namespace ngraph
|
||||
return true;
|
||||
}
|
||||
|
||||
private:
|
||||
protected:
|
||||
onnx_import::Node m_node;
|
||||
|
||||
private:
|
||||
std::shared_ptr<onnx_import::Graph> m_graph;
|
||||
};
|
||||
|
||||
class ONNXSubgraphFrameworkNode : public ONNXFrameworkNode
|
||||
@@ -77,19 +95,18 @@ namespace ngraph
|
||||
public:
|
||||
NGRAPH_RTTI_DECLARATION;
|
||||
|
||||
ONNXSubgraphFrameworkNode(const onnx_import::Node& node, const OutputVector& inputs)
|
||||
: ONNXFrameworkNode(node, inputs)
|
||||
ONNXSubgraphFrameworkNode(std::shared_ptr<onnx_import::Graph> graph,
|
||||
const onnx_import::Node& node,
|
||||
const OutputVector& inputs)
|
||||
: ONNXFrameworkNode(graph, node, inputs)
|
||||
{
|
||||
}
|
||||
|
||||
void infer_inputs_from_parent()
|
||||
{
|
||||
get_onnx_node().get_subgraph()->infer_inputs_from_parent();
|
||||
}
|
||||
void infer_inputs_from_parent() { m_node.get_subgraph()->infer_inputs_from_parent(); }
|
||||
|
||||
std::shared_ptr<Function> get_subgraph_body() const
|
||||
{
|
||||
auto subgraph = get_onnx_node().get_subgraph();
|
||||
auto subgraph = m_node.get_subgraph();
|
||||
return std::make_shared<Function>(subgraph->get_ng_outputs(),
|
||||
subgraph->get_ng_parameters(),
|
||||
subgraph->get_name());
|
||||
@@ -5,10 +5,10 @@
|
||||
#include <onnx/onnx_pb.h>
|
||||
|
||||
#include "core/graph.hpp"
|
||||
#include "core/model.hpp"
|
||||
#include "core/null_node.hpp"
|
||||
#include "core/transform.hpp"
|
||||
#include "onnx_import/onnx_framework_node.hpp"
|
||||
#include "onnx_framework_node.hpp"
|
||||
#include "onnx_import/core/model.hpp"
|
||||
#include "onnx_import/utils/onnx_internal.hpp"
|
||||
|
||||
namespace ngraph
|
||||
@@ -61,7 +61,7 @@ namespace ngraph
|
||||
}
|
||||
}
|
||||
|
||||
void convert_decoded_function(std::shared_ptr<Function> function)
|
||||
std::shared_ptr<Function> convert_decoded_function(std::shared_ptr<Function> function)
|
||||
{
|
||||
for (const auto& node : function->get_ordered_ops())
|
||||
{
|
||||
@@ -75,12 +75,7 @@ namespace ngraph
|
||||
subgraph_node->infer_inputs_from_parent();
|
||||
convert_decoded_function(subgraph_node->get_subgraph_body());
|
||||
}
|
||||
const auto& onnx_node = raw_node->get_onnx_node();
|
||||
OutputVector ng_nodes{onnx_node.get_ng_nodes()};
|
||||
if (ng_nodes.size() > raw_node->get_output_size())
|
||||
{
|
||||
ng_nodes.resize(raw_node->get_output_size());
|
||||
}
|
||||
auto ng_nodes = raw_node->get_ng_nodes();
|
||||
replace_node(raw_node, ng_nodes);
|
||||
}
|
||||
else
|
||||
@@ -90,22 +85,37 @@ namespace ngraph
|
||||
node->revalidate_and_infer_types();
|
||||
}
|
||||
}
|
||||
remove_dangling_parameters(function);
|
||||
remove_dangling_results(function);
|
||||
detail::remove_dangling_parameters(function);
|
||||
detail::remove_dangling_results(function);
|
||||
|
||||
return function;
|
||||
}
|
||||
|
||||
std::shared_ptr<Function> import_onnx_model(ONNX_NAMESPACE::ModelProto& model_proto,
|
||||
const std::string& model_path)
|
||||
void apply_transformations(ONNX_NAMESPACE::ModelProto& model_proto,
|
||||
const std::string& model_path)
|
||||
{
|
||||
transform::expand_onnx_functions(model_proto);
|
||||
transform::fixup_legacy_operators(model_proto);
|
||||
transform::update_external_data_paths(model_proto, model_path);
|
||||
}
|
||||
|
||||
auto p_model_proto = common::make_unique<ONNX_NAMESPACE::ModelProto>(model_proto);
|
||||
auto model = common::make_unique<Model>(std::move(p_model_proto));
|
||||
Graph graph{std::move(model)};
|
||||
std::shared_ptr<Function>
|
||||
import_onnx_model(std::shared_ptr<ONNX_NAMESPACE::ModelProto> model_proto,
|
||||
const std::string& model_path)
|
||||
{
|
||||
apply_transformations(*model_proto, model_path);
|
||||
Graph graph{model_proto};
|
||||
return graph.convert();
|
||||
}
|
||||
|
||||
std::shared_ptr<Function>
|
||||
decode_to_framework_nodes(std::shared_ptr<ONNX_NAMESPACE::ModelProto> model_proto,
|
||||
const std::string& model_path)
|
||||
{
|
||||
apply_transformations(*model_proto, model_path);
|
||||
auto graph = std::make_shared<Graph>(model_proto);
|
||||
return graph->decode();
|
||||
}
|
||||
} // namespace detail
|
||||
} // namespace onnx_import
|
||||
} // namespace ngraph
|
||||
@@ -0,0 +1,97 @@
|
||||
# Copyright (C) 2021 Intel Corporation
|
||||
# SPDX-License-Identifier: Apache-2.0
|
||||
|
||||
import os
|
||||
import onnx
|
||||
import numpy as np
|
||||
from onnx.helper import make_graph, make_model, make_tensor_value_info
|
||||
import pytest
|
||||
|
||||
from ngraph.frontend import FrontEndManager
|
||||
from tests.runtime import get_runtime
|
||||
|
||||
|
||||
def create_onnx_model():
|
||||
add = onnx.helper.make_node("Add", inputs=["x", "y"], outputs=["z"])
|
||||
const_tensor = onnx.helper.make_tensor("const_tensor", onnx.TensorProto.FLOAT, (2, 2), [0.5, 1, 1.5, 2.0])
|
||||
const_node = onnx.helper.make_node("Constant", [], outputs=["const_node"],
|
||||
value=const_tensor, name="const_node")
|
||||
mul = onnx.helper.make_node("Mul", inputs=["z", "const_node"], outputs=["out"])
|
||||
input_tensors = [
|
||||
make_tensor_value_info("x", onnx.TensorProto.FLOAT, (2, 2)),
|
||||
make_tensor_value_info("y", onnx.TensorProto.FLOAT, (2, 2)),
|
||||
]
|
||||
output_tensors = [make_tensor_value_info("out", onnx.TensorProto.FLOAT, (2, 2))]
|
||||
graph = make_graph([add, const_node, mul], "graph", input_tensors, output_tensors)
|
||||
return make_model(graph, producer_name="ngraph ONNX Importer")
|
||||
|
||||
|
||||
def run_function(function, *inputs, expected):
|
||||
runtime = get_runtime()
|
||||
computation = runtime.computation(function)
|
||||
actual = computation(*inputs)
|
||||
assert len(actual) == len(expected)
|
||||
for i in range(len(actual)):
|
||||
np.testing.assert_allclose(expected[i], actual[i], rtol=1e-3, atol=1e-6)
|
||||
|
||||
|
||||
fem = FrontEndManager()
|
||||
onnx_model_filename = "model.onnx"
|
||||
|
||||
|
||||
def setup_module():
|
||||
onnx.save_model(create_onnx_model(), onnx_model_filename)
|
||||
|
||||
|
||||
def teardown_module():
|
||||
os.remove(onnx_model_filename)
|
||||
|
||||
|
||||
def skip_if_onnx_frontend_is_disabled():
|
||||
front_ends = fem.get_available_front_ends()
|
||||
if "onnx" not in front_ends:
|
||||
pytest.skip()
|
||||
|
||||
|
||||
def test_convert():
|
||||
skip_if_onnx_frontend_is_disabled()
|
||||
|
||||
fe = fem.load_by_framework(framework="onnx")
|
||||
assert fe
|
||||
|
||||
model = fe.load(onnx_model_filename)
|
||||
assert model
|
||||
|
||||
function = fe.convert(model)
|
||||
assert function
|
||||
|
||||
a = np.array([[1, 2], [3, 4]], dtype=np.float32)
|
||||
b = np.array([[2, 3], [4, 5]], dtype=np.float32)
|
||||
expected = np.array([[1.5, 5], [10.5, 18]], dtype=np.float32)
|
||||
run_function(function, a, b, expected=[expected])
|
||||
|
||||
|
||||
def test_decode_and_convert():
|
||||
skip_if_onnx_frontend_is_disabled()
|
||||
|
||||
fe = fem.load_by_framework(framework="onnx")
|
||||
assert fe
|
||||
|
||||
model = fe.load(onnx_model_filename)
|
||||
assert model
|
||||
|
||||
decoded_function = fe.decode(model)
|
||||
assert decoded_function
|
||||
for op in decoded_function.get_ordered_ops():
|
||||
assert op.get_type_name() in ["Parameter", "Constant", "ONNXFrameworkNode",
|
||||
"ONNXSubgraphFrameworkNode", "Result"]
|
||||
|
||||
function = fe.convert(decoded_function)
|
||||
assert function
|
||||
for op in function.get_ordered_ops():
|
||||
assert op.get_type_name() not in ["ONNXFrameworkNode", "ONNXSubgraphFrameworkNode"]
|
||||
|
||||
a = np.array([[1, 2], [3, 4]], dtype=np.float32)
|
||||
b = np.array([[2, 3], [4, 5]], dtype=np.float32)
|
||||
expected = np.array([[1.5, 5], [10.5, 18]], dtype=np.float32)
|
||||
run_function(function, a, b, expected=[expected])
|
||||
File renamed without changes.
Reference in new issue
Block a user