Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PyOV] Add more ov.Model constructors #25635

Merged
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
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
69 changes: 69 additions & 0 deletions src/bindings/python/src/pyopenvino/graph/model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,16 @@ static ov::SinkVector cast_to_sink_vector(const std::vector<std::shared_ptr<ov::
return sinks;
}

static ov::SinkVector cast_to_sink_vector(const ov::OutputVector& outputs) {
ov::SinkVector sinks;
for (const auto& output : outputs) {
auto sink = std::dynamic_pointer_cast<ov::op::Sink>(output.get_node_shared_ptr());
OPENVINO_ASSERT(sink != nullptr, "Output node handle {} is not instance of Sink");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
OPENVINO_ASSERT(sink != nullptr, "Output node handle {} is not instance of Sink");
OPENVINO_ASSERT(sink != nullptr, "Output {} is not instance of Sink");

?

What {} means in error message?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually nothing, @almilosz removed it

sinks.push_back(sink);
}
return sinks;
}

static std::vector<std::shared_ptr<ov::Node>> cast_to_node_vector(const ov::SinkVector& sinks) {
std::vector<std::shared_ptr<ov::Node>> nodes;
for (const auto& sink : sinks) {
Expand Down Expand Up @@ -259,6 +269,65 @@ void regclass_graph_Model(py::module m) {
:param name: String to set as model's friendly name.
:type name: str
)");

model.def(py::init([](const ov::OutputVector& results,
const ov::OutputVector& nodes,
const ov::ParameterVector& parameters,
const ov::op::util::VariableVector& variables,
const std::string& name) {
set_tensor_names(parameters);
const auto sinks = cast_to_sink_vector(nodes);
auto model = std::make_shared<ov::Model>(results, sinks, parameters, name);
set_correct_variables_for_assign_ops(model, sinks);
return model;
}),
py::arg("results"),
py::arg("sinks"),
py::arg("parameters"),
py::arg("variables") = ov::op::util::VariableVector(),
py::arg("name") = "",
R"(
Create user-defined Model which is a representation of a model

:param results: List of outputs.
:type results: List[openvino.runtime.Output]
:param sinks: List of Output sink node handles.
:type sinks: List[openvino.runtime.Output]
:param variables: List of variables.
:type variables: List[op.util.Variable]
:param name: String to set as model's friendly name.
:type name: str
)");

model.def(py::init([](const ov::ResultVector& results,
const ov::OutputVector& nodes,
const ov::ParameterVector& parameters,
const ov::op::util::VariableVector& variables,
const std::string& name) {
set_tensor_names(parameters);
const auto sinks = cast_to_sink_vector(nodes);
auto model = std::make_shared<ov::Model>(results, sinks, parameters, name);
set_correct_variables_for_assign_ops(model, sinks);
return model;
}),
py::arg("results"),
py::arg("sinks"),
py::arg("parameters"),
py::arg("variables") = ov::op::util::VariableVector(),
py::arg("name") = "",
R"(
Create user-defined Model which is a representation of a model

:param results: List of results.
:type results: List[op.Result]
:param sinks: List of Output sink node handles.
:type sinks: List[openvino.runtime.Output]
:param variables: List of variables.
:type variables: List[op.util.Variable]
:param name: String to set as model's friendly name.
:type name: str
)");

model.def(py::init([](const ov::ResultVector& results,
const std::vector<std::shared_ptr<ov::Node>>& nodes,
const ov::ParameterVector& parameters,
Expand Down
18 changes: 17 additions & 1 deletion src/bindings/python/tests/test_graph/test_basic.py
Original file line number Diff line number Diff line change
Expand Up @@ -572,12 +572,18 @@ def test_sink_model_ctors():
assert model.get_friendly_name() == "TestModel"


def test_sink_model_ctor_without_init_subgraph():
@pytest.fixture
def setup_sink_model():
input_data = ops.parameter([2, 2], name="input_data", dtype=np.float32)
rv = ops.read_value("var_id_667", np.float32, [2, 2])
add = ops.add(rv, input_data, name="MemoryAdd")
node = ops.assign(add, "var_id_667")
res = ops.result(add, "res")
return input_data, res, node


def test_sink_model_ctor_without_init_subgraph(setup_sink_model):
input_data, res, node = setup_sink_model
model = Model(results=[res], sinks=[node], parameters=[input_data], name="TestModel")

var_info = VariableInfo()
Expand Down Expand Up @@ -608,6 +614,16 @@ def test_sink_model_ctor_without_init_subgraph():
assert model.get_friendly_name() == "TestModel"


def test_model_ctors(setup_sink_model):
input_data, res, node = setup_sink_model

model = Model(results=[res], sinks=[node.output(0)], parameters=[input_data], name="TestModel")
assert model.sinks[0].get_output_shape(0) == Shape([2, 2])

model = Model(results=[model.output(0)], sinks=[node.output(0)], parameters=[input_data], name="TestModel")
assert model.sinks[0].get_output_shape(0) == Shape([2, 2])


def test_strides_iteration_methods():
data = np.array([1, 2, 3])
strides = Strides(data)
Expand Down
Loading