Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
80 commits
Select commit Hold shift + click to select a range
1432bab
Initial implementation of passing GraphIterator
Jul 15, 2025
0158e89
First implementation of GraphIterator calling mechanism
Sep 3, 2025
006cfcd
Improvements
Jul 26, 2025
ad19f34
Trying to accept Decoder as a source for Node
Jul 26, 2025
be3b07c
Change behavior of Node to support decoder as a source
Jul 26, 2025
1e9c30f
Modified get_attribute_value for initial support of Decoder
Jul 26, 2025
60bf72c
Adding support of Constant creation for attributes
Jul 26, 2025
aa1ee84
Updated creating constants from Decoder's get_attribute
Jul 26, 2025
612b84d
Using FRONT_END_NOT_IMPLEMENTED
Jul 26, 2025
bf9167d
Implemented missing has_attribute and get_ov_inputs()
Jul 26, 2025
29378a6
First working implementation for one-layer Abs.onnx
Jul 26, 2025
96745dd
Fixed dafault_value behavior for attributes
Jul 26, 2025
4ecc6c8
Cleanup and fixed behavior for output tensors
Jul 26, 2025
77c88c0
Fixes to support mul+add model
Jul 26, 2025
79fbe60
Fixed issue with initializators
Jul 26, 2025
1637371
Added support of tensors without ValueInfo
Jul 26, 2025
9b4e8e7
Implemented get_output_names wrapper for Decoder
Jul 26, 2025
36fab19
Cleanup
Jul 26, 2025
723274a
Added names for outputs
Jul 26, 2025
3db248d
Added attributes parsing
Jul 26, 2025
cc39468
Code optimization
Jul 27, 2025
4132c83
Added a parent-child relations between classes
Jul 27, 2025
18bc42b
Added a possibility to return an iterator graph attributes
Jul 27, 2025
a01625d
Fixed generation of a nested GraphIteratorProto for GRAPH attributes
Aug 29, 2025
3ba0e5d
Moved ov::Model creation to InputModel
Aug 29, 2025
5cf02cb
Added possibility to return ov::Model when a GRAPH attribute requested
Aug 29, 2025
5f29f5e
Intermediate work
Sep 1, 2025
9b35112
Switched to use a common approach with TranslateSession
Sep 1, 2025
0d0249f
Broken if
Sep 1, 2025
0af879d
Cleanup
Sep 1, 2025
0215d91
Moved GraphIteratorProto to the ONNX Frontend
Sep 3, 2025
1d463d9
Cleanup
Sep 1, 2025
fd023f7
Decoding tensors to constants
Sep 2, 2025
0ac5462
Fixing an inputs
Sep 2, 2025
148da02
Some updates
Sep 2, 2025
f8c97a6
Fixes
Sep 3, 2025
15d34fc
Fixes around different output count
Sep 2, 2025
8969c0f
Added get_attribute_any
Sep 2, 2025
e739abf
Fixed a constant shape
Sep 2, 2025
a337884
Fixed Scan operation
Sep 2, 2025
3387a98
Fixed Random operations
Sep 2, 2025
0068acb
Supporting a Loop operation
Sep 2, 2025
4ba435f
Introduced an MMAP Cache
Sep 3, 2025
b2a57c2
Separated logic of construction and initialization
Sep 3, 2025
5809d83
Implemented support of externally stored data files
Sep 3, 2025
df27b44
Small refactoring
Sep 3, 2025
e772bf4
Removed unused get_subgraph() and get_subgraph_size() logic
Sep 3, 2025
01de02f
Added enable_mmap to unify::InputModel
Sep 3, 2025
cf432d3
InputModel now is responsible for a keeping cache
Sep 3, 2025
1a7ab29
Re-done external memory management
Sep 3, 2025
67db232
Removed dangling inputs
Sep 3, 2025
ed40865
Fixed exception message
Sep 3, 2025
090eb47
Fixed object copying
Sep 3, 2025
0a4c63f
Fixed exception
Sep 3, 2025
4263260
Code style
Sep 3, 2025
bb7ae68
Compilation fixes
Sep 3, 2025
2f4ddcb
Fixes
Sep 3, 2025
bc3a839
Compilation fixes
Sep 3, 2025
fa04eb5
Fixed initialization order
Sep 4, 2025
8fb7355
Restored behavior of get_attribute for legacy path
Sep 4, 2025
07b94fe
Compilation fixes
Sep 4, 2025
d39052b
Removed fields for future use
Sep 4, 2025
5bf52c3
Fixed copy
Sep 4, 2025
9870b54
Added override keyword
Sep 4, 2025
742e585
Cleanup of test
Sep 4, 2025
f2ff281
Fixed namespaces
Sep 4, 2025
bd574b4
Reordered namespaces
Sep 4, 2025
64834cd
Implemented usage of FrameworkNodes
Sep 4, 2025
744d614
Allow to work with nested translatesessions
Sep 6, 2025
9e20b20
Reworked TranslateSession for correct handling chains of parameters
Sep 6, 2025
79a90b4
Fixed constants handling, raw data handling, some issues with valuein…
Sep 7, 2025
091a4a4
Fixed external size calculation
Sep 7, 2025
a3ba5db
Typo
Sep 7, 2025
a017969
Removed an unnecessary headers from cmake
Sep 7, 2025
1256e4a
Update graph_iterator_proto.cpp
Sep 9, 2025
1392849
Merge branch 'master' into onnx_gi
mvafin Oct 6, 2025
1b138ef
Apply suggestions from code review
mvafin Oct 6, 2025
c181ba7
Apply suggestions from code review
mvafin Oct 6, 2025
7c8a247
Apply suggestions from code review
mvafin Oct 6, 2025
9081a15
Update src/frontends/onnx/frontend/src/core/decoder_proto.hpp
mvafin Oct 6, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
// Copyright (C) 2018-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//
#pragma once

#include "openvino/core/partial_shape.hpp"
#include "openvino/core/type/element_type.hpp"
#include "openvino/frontend/decoder.hpp"
#include "openvino/frontend/onnx/visibility.hpp"

namespace ov {
namespace frontend {
namespace onnx {

struct ONNX_FRONTEND_API TensorMetaInfo {
ov::PartialShape m_partial_shape;
ov::element::Type m_element_type;
const uint8_t* m_tensor_data;
size_t m_tensor_data_size;
const std::string* m_tensor_name;
std::shared_ptr<std::string> m_external_location;
bool m_is_raw;
};

class ONNX_FRONTEND_API DecoderBase : public ov::frontend::DecoderBase {
public:
using Ptr = std::shared_ptr<DecoderBase>;
~DecoderBase() override;
};

struct ONNX_FRONTEND_API SparseTensorInfo {
ov::PartialShape m_partial_shape;
ov::frontend::onnx::DecoderBase::Ptr m_values, m_indices;
};

// DecoderBaseOperation corresponds to operation node to retrieve its attributes and information about input and output
// tensors
class ONNX_FRONTEND_API DecoderBaseOperation : public ov::frontend::onnx::DecoderBase {
public:
/// \brief Get input tensor name by index
/// Operation nodes are connected between each other by tensors.
/// Each tensor must have unique name in a graph.
/// The tensor name uniqueness is provided by developer during GraphIterator construction.
/// This method returns tensor name that comes to this operation node by input index idx
/// If idx is out-of-range, it throws std::exception inherited exception
virtual const std::string& get_input_tensor_name(size_t idx) const = 0;

/// \brief Get input tensor type by index
/// If idx is out-of-range, it throws std::exception inherited exception
virtual ov::element::Type get_input_tensor_type(size_t idx) const = 0;

/// \brief Get output tensor name by index
/// Operation nodes are connected between each other by tensors.
/// Each tensor must have unique name in a graph.
/// The tensor name uniqueness is provided by developer during GraphIterator construction.
/// This method returns tensor name that outputs by output index idx from this operation
/// If idx is out-of-range, it throws std::exception inherited exception
virtual const std::string& get_output_tensor_name(size_t idx) const = 0;

/// \brief Get output tensor type by index
/// If idx is out-of-range, it throws std::exception inherited exception
virtual ov::element::Type get_output_tensor_type(size_t idx) const = 0;

/// \brief Get input tensor info
/// returns TensorInfo by input idx index that corresponds to a tensor
/// (it can correspond to Constant, Parameter or intermediate tensor connecting a producer and this current node)
/// If idx is out-of-range, it throws std::exception inherited exception
virtual const TensorMetaInfo& get_input_tensor_info(size_t idx) const = 0;

/// \brief Get output tensor info
/// returns TensorInfo by output idx index that corresponds to a tensor
/// (it can correspond to intermediate tensor connecting this current node and a consumer)
/// If idx is out-of-range, it throws std::exception inherited exception
virtual const TensorMetaInfo& get_output_tensor_info(size_t idx) const = 0;

/// \brief Get a number of outputs
virtual size_t get_output_size() const = 0;

/// \brief Returns operation's opset version
virtual uint64_t get_op_set() const = 0;

/// \brief Returns operation's domain
virtual const std::string& get_domain() const = 0;

/// \brief Returns true if node has attribute
virtual bool has_attribute(const std::string& name) const = 0;

virtual void experimental_get_internal_structures(const void** node_def) const = 0;

~DecoderBaseOperation() override;
};

// DecoderBaseTensor corresponds to tensor node to retrieve information about type, shapem quantization and sparsity
// information
class ONNX_FRONTEND_API DecoderBaseTensor : public ov::frontend::onnx::DecoderBase {
public:
/// \brief Get tensor info
virtual const TensorMetaInfo& get_tensor_info() const = 0;

/// \brief Get input index for tensor
/// returns index of this input in the list of inputs in the model
/// it must be from 0 to n-1, where n - number of inputs in the model
/// if it is not input, returns -1
virtual int64_t get_input_idx() const = 0;

/// \brief Get output index for tensor
/// returns index of this output in the list of outputs in the model
/// it must be from 0 to m-1, where m - number of outputs in the model
/// if it is not input, returns -1
virtual int64_t get_output_idx() const = 0;

~DecoderBaseTensor() override;
};

} // namespace onnx
} // namespace frontend
} // namespace ov
Original file line number Diff line number Diff line change
Expand Up @@ -18,17 +18,25 @@ namespace onnx {
class ONNX_FRONTEND_API FrontEnd : public ov::frontend::FrontEnd {
public:
using Ptr = std::shared_ptr<FrontEnd>;
std::shared_ptr<ov::Model> convert(const InputModel::Ptr& model) const override;
std::shared_ptr<ov::Model> convert(const ov::frontend::InputModel::Ptr& model) const override;
void convert(const std::shared_ptr<ov::Model>& partially_converted) const override;
std::shared_ptr<ov::Model> convert_partially(const InputModel::Ptr& input_model) const override;
std::shared_ptr<ov::Model> decode(const InputModel::Ptr& input_model) const override;
std::shared_ptr<ov::Model> convert_partially(const ov::frontend::InputModel::Ptr& input_model) const override;
std::shared_ptr<ov::Model> decode(const ov::frontend::InputModel::Ptr& input_model) const override;
std::string get_name() const override;
bool supported_impl(const std::vector<ov::Any>& variants) const override;
void add_extension(const std::shared_ptr<ov::Extension>& extension) override;
void normalize(const std::shared_ptr<ov::Model>& model) const override;

protected:
InputModel::Ptr load_impl(const std::vector<ov::Any>& params) const override;
ov::frontend::InputModel::Ptr load_impl(const std::vector<ov::Any>& params) const override;

void translate_graph(const InputModel::Ptr& model,
bool fail_fast,
bool /* no_conversion */, // future use
std::shared_ptr<ov::Model>& ov_model) const;
std::shared_ptr<ov::Model> convert_unify(const InputModel::Ptr& model) const;
std::shared_ptr<ov::Model> convert_partially_unify(const InputModel::Ptr& input_model) const;
std::shared_ptr<ov::Model> decode_unify(const InputModel::Ptr& input_model) const;

// m_other_extensions should be the first member here,
// m_other_extensions can contain SO Extension (holder for other Extensions),
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
// Copyright (C) 2018-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#pragma once

#include "openvino/core/runtime_attribute.hpp"
#include "openvino/frontend/onnx/decoder.hpp"
#include "openvino/frontend/onnx/visibility.hpp"

namespace ov {
namespace frontend {
namespace onnx {

/// Abstract representation for an input model graph that gives nodes in topologically sorted order
/// It returns decoders for model inputs and outputs (DecoderBaseTensor objects) and for operation nodes
/// (DecoderBaseOperation objects) DecoderBaseOperation objects for operation nodes must be sorted in topological order
/// from producing nodes to consumer nodes when `get_decoder()` is called. DecoderBaseTensor objects for inputs and
/// outputs must be returned first by `get_decoder()` method. Order of DecoderBaseTensor objects for inputs and outputs
/// defines their order in the original model, i.e. model input index and model output index.
/// For example, calling `get_decoder()` during iterating GraphIterator returns
/// DecoderBaseTensor (for input 0), ..., DecoderBaseTensor (for input n-1),
/// DecoderBaseTensor (for output 0), ..., DecoderBaseTensor (for output m-1),
/// DecoderBaseOperation (for op 1), ..., DecoderBaseOperation (for op k),
/// where n - number of inputs in the model, m - number of outputs in the model k - number of operation nodes.
/// NOTE: constants are ignored and no decoder object is returned for constant.
class ONNX_FRONTEND_API GraphIterator : ::ov::RuntimeAttribute {
public:
using Ptr = std::shared_ptr<GraphIterator>;

/// \brief Get a number of operation nodes in the graph
virtual size_t size() const = 0;

/// \brief Set iterator to the start position
virtual void reset() = 0;

/// \brief Move to the next node in the graph
virtual void next() = 0;

/// \brief Returns true if iterator goes out of the range of available nodes
virtual bool is_end() const = 0;

/// \brief Return a pointer to a decoder of the current node
virtual std::shared_ptr<DecoderBase> get_decoder() const = 0;

/// \brief Returns opset version of requested domain, stored in a ModelProto
/// If there are no domain found returns -1
virtual int64_t get_opset_version(const std::string& domain) const = 0;

/// \brief Destructor
virtual ~GraphIterator();
};

} // namespace onnx
} // namespace frontend
} // namespace ov
13 changes: 13 additions & 0 deletions src/frontends/onnx/frontend/src/core/decoder.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
// Copyright (C) 2018-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include "openvino/frontend/onnx/decoder.hpp"

using namespace ov::frontend::onnx;

DecoderBase::~DecoderBase() = default;

DecoderBaseOperation::~DecoderBaseOperation() = default;

DecoderBaseTensor::~DecoderBaseTensor() = default;
130 changes: 130 additions & 0 deletions src/frontends/onnx/frontend/src/core/decoder_proto.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
// Copyright (C) 2018-2025 Intel Corporation
// SPDX-License-Identifier: Apache-2.0
//

#include "decoder_proto.hpp"

#include <onnx/onnx_pb.h>

#include <fstream>
#include <openvino/frontend/graph_iterator.hpp>

#include "graph_iterator_proto.hpp"
#include "openvino/frontend/onnx/graph_iterator.hpp"
#include "openvino/util/wstring_convert_util.hpp"

namespace ov {
namespace frontend {
namespace onnx {

const std::string empty_name = "";
const std::string DEFAULT_DOMAIN = "";
const std::string EMPTY_NAME = "";
const std::string EMPTY_OP_TYPE = "";

ov::Any DecoderProto::get_attribute(const std::string& name) const {
for (const auto& attr : m_node->attribute()) {
if (!attr.has_name() || attr.name() != name)
continue;
if (!attr.has_type()) {
throw std::runtime_error("Attribute \"" + name + "\" doesn't have a type");
}
switch (attr.type()) {
case AttributeProto_AttributeType::AttributeProto_AttributeType_FLOAT:
if (attr.has_f())
return attr.f();
else
throw std::runtime_error("Attribute doesn't have value");
break;
case AttributeProto_AttributeType::AttributeProto_AttributeType_FLOATS:
return std::vector<float>{attr.floats().begin(), attr.floats().end()};
case AttributeProto_AttributeType::AttributeProto_AttributeType_INT:
if (attr.has_i())
return attr.i();
else
throw std::runtime_error("Attribute doesn't have value");
break;
case AttributeProto_AttributeType::AttributeProto_AttributeType_INTS:
return std::vector<int64_t>{attr.ints().begin(), attr.ints().end()};
case AttributeProto_AttributeType::AttributeProto_AttributeType_STRING:
if (attr.has_s())
return attr.s();
else
throw std::runtime_error("Attribute doesn't have value");
break;
case AttributeProto_AttributeType::AttributeProto_AttributeType_STRINGS:
return std::vector<std::string>{attr.strings().begin(), attr.strings().end()};
case AttributeProto_AttributeType::AttributeProto_AttributeType_GRAPH:
if (attr.has_g())
return static_cast<ov::frontend::onnx::GraphIterator::Ptr>(
std::make_shared<GraphIteratorProto>(m_parent, &attr.g()));
else
throw std::runtime_error("Attribute doesn't have value");
break;
case AttributeProto_AttributeType::AttributeProto_AttributeType_TENSOR:
return static_cast<ov::frontend::onnx::DecoderBase::Ptr>(
std::make_shared<DecoderProtoTensor>(&attr.t(), m_parent, 0, 0));
case AttributeProto_AttributeType::AttributeProto_AttributeType_SPARSE_TENSOR: {
ov::frontend::onnx::SparseTensorInfo sparse_tensor_info{};
auto& sparse_tensor = attr.sparse_tensor();
sparse_tensor_info.m_partial_shape =
ov::PartialShape{std::vector<int64_t>(sparse_tensor.dims().begin(), sparse_tensor.dims().end())};
if (sparse_tensor.has_values()) {
sparse_tensor_info.m_values = static_cast<ov::frontend::onnx::DecoderBase::Ptr>(
std::make_shared<DecoderProtoTensor>(&sparse_tensor.values(), m_parent, 0, 0));
}
if (sparse_tensor.has_indices()) {
sparse_tensor_info.m_indices = static_cast<ov::frontend::onnx::DecoderBase::Ptr>(
std::make_shared<DecoderProtoTensor>(&sparse_tensor.indices(), m_parent, 0, 0));
}
return sparse_tensor_info;
}
default:
throw std::runtime_error("Unsupported attribute type " +
::ONNX_NAMESPACE::AttributeProto_AttributeType_Name(attr.type()));
}
}
return nullptr;
}

size_t DecoderProto::get_input_size() const {
return m_input_info.size();
}

size_t DecoderProto::get_output_size() const {
return m_output_info.size();
}

void DecoderProto::get_input_node(size_t input_port_idx,
std::string& producer_name,
std::string& producer_output_port_name,
size_t& producer_output_port_index) const {}

const std::string& DecoderProto::get_op_type() const {
if (m_node->has_op_type()) {
return m_node->op_type();
} else {
return EMPTY_OP_TYPE;
}
}

const std::string& DecoderProto::get_op_name() const {
if (m_node->has_name()) {
return m_node->name();
} else {
return EMPTY_NAME;
}
}

bool DecoderProto::has_attribute(const std::string& name) const {
for (const auto& attr : m_node->attribute()) {
if (attr.has_name() && attr.name() == name) {
return true;
}
}
return false;
}

} // namespace onnx
} // namespace frontend
} // namespace ov
Loading
Loading