Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
9034b31
Done
Jarvis2001 Nov 2, 2025
326382d
Formatting
Jarvis2001 Nov 12, 2025
fea21a4
Formatting
Jarvis2001 Nov 12, 2025
0191c57
Merge branch 'master' into variable-shape
Jarvis2001 Nov 25, 2025
6fd0438
Merge branch 'openvinotoolkit:master' into variable-shape
Jarvis2001 Dec 9, 2025
0c9e259
Modified tests, added helper functions
Jarvis2001 Dec 11, 2025
506f599
Merge branch 'openvinotoolkit:master' into variable-shape
Jarvis2001 Dec 18, 2025
eaa8ec1
Merge branch 'openvinotoolkit:master' into variable-shape
Jarvis2001 Dec 22, 2025
9c9115f
Fixed linter errors and added one test
Jarvis2001 Dec 29, 2025
ce80c25
-
Jarvis2001 Dec 29, 2025
a98a4ac
Merge branch 'master' into variable-shape
Jarvis2001 Jan 26, 2026
041ddca
No linter issues now I hope. The CI failed due to whitespace on line …
Jarvis2001 Jan 28, 2026
3f1361f
Merge branch 'master' into variable-shape
Jarvis2001 Jan 28, 2026
f29e8b3
fixed the linter errors(line too long) in test_model.py
Jarvis2001 Jan 28, 2026
46e4cd7
fixed linter E501 in helper.py
Jarvis2001 Jan 28, 2026
1074c44
Merge branch 'master' into variable-shape
Jarvis2001 Feb 8, 2026
84e2e72
Merge branch 'master' into variable-shape
Jarvis2001 Feb 14, 2026
3f7fc15
Merge branch 'master' into variable-shape
Jarvis2001 Feb 20, 2026
2a279f6
Merge branch 'master' into variable-shape
mlukasze Feb 25, 2026
a93273a
Fix linter and CI issues
Practice2001 Feb 25, 2026
43b8877
Reapply Practice2001 changes under Jarvis2001
Jarvis2001 Feb 25, 2026
ad81015
Reapply Practice2001 changes under Jarvis2001
Jarvis2001 Feb 25, 2026
11dd04c
Revert "Fix linter and CI issues"
Jarvis2001 Feb 26, 2026
df977ff
Applied changes suggested by copilot. Reformatted test on line 815 in…
Jarvis2001 Feb 26, 2026
56a45f2
Small changes
Jarvis2001 Feb 26, 2026
649c3ba
Merge branch 'master' into variable-shape
Jarvis2001 Mar 6, 2026
7372886
Merge branch 'master' into variable-shape
Jarvis2001 Mar 13, 2026
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
98 changes: 97 additions & 1 deletion src/bindings/python/src/pyopenvino/graph/model.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -489,6 +489,102 @@ void regclass_graph_Model(py::module m) {

model.def("validate_nodes_and_infer_types", &ov::Model::validate_nodes_and_infer_types);

model.def(
"reshape",
[](ov::Model& self, py::list shapes_list) {
const auto& inputs = self.inputs();

if (inputs.empty())
throw std::runtime_error("Model has no inputs.");

if (shapes_list.size() == 0)
throw std::runtime_error("Shapes list cannot be empty.");

// Check if first element is a list/tuple (multi-input format)
py::handle first_elem = shapes_list[0];
bool is_multi_input_format =
(py::isinstance<py::list>(first_elem) || py::isinstance<py::tuple>(first_elem));

// flat format? use existing reshape logic
if (!is_multi_input_format) {
const auto new_shape = Common::partial_shape_from_list(shapes_list);
py::gil_scoped_release release;
self.reshape(new_shape);
return;
}

// Multi-input format
std::map<std::string, ov::PartialShape> new_shapes_map;

auto parse_dimension = [](py::handle dim_obj) -> ov::Dimension {
if (py::isinstance<py::list>(dim_obj)) {
throw std::runtime_error("Unexpected nested list in dimension specification.");
}

if (py::isinstance<py::tuple>(dim_obj)) {
py::tuple t = dim_obj.cast<py::tuple>();
if (t.size() != 2) {
throw std::runtime_error(
"Two elements are expected in tuple(lower, upper) for dynamic dimension, but " +
std::to_string(t.size()) + " elements were given.");
}
if (!py::isinstance<py::int_>(t[0]) || !py::isinstance<py::int_>(t[1])) {
throw std::runtime_error("Tuple elements must be integers.");
}
int lower = t[0].cast<int>();
int upper = t[1].cast<int>();
return ov::Dimension(lower, upper);
}

if (py::isinstance<py::int_>(dim_obj)) {
return ov::Dimension(dim_obj.cast<int>());
}

throw std::runtime_error("Invalid dimension type. Must be int or (lower, upper) tuple.");
};

auto parse_shape = [&parse_dimension](py::sequence shape_seq) -> ov::PartialShape {
std::vector<ov::Dimension> dims;
for (size_t i = 0; i < shape_seq.size(); ++i) {
dims.push_back(parse_dimension(shape_seq[i]));
}
return ov::PartialShape(dims);
};

// Multi-input: [[shape1], [shape2], ...]
if (shapes_list.size() != inputs.size()) {
throw std::runtime_error("Number of shapes does not match number of model inputs.");
}

for (size_t i = 0; i < shapes_list.size(); ++i) {
py::handle shape_handle = shapes_list[i];

if (!py::isinstance<py::list>(shape_handle) && !py::isinstance<py::tuple>(shape_handle)) {
throw std::runtime_error("Each shape must be a list or tuple.");
}

py::sequence shape_seq = shape_handle.cast<py::sequence>();
new_shapes_map[inputs[i].get_any_name()] = parse_shape(shape_seq);
}

py::gil_scoped_release release;
self.reshape(new_shapes_map);
},
py::arg("shapes"),
R"(
Reshape model inputs using a list of input shapes.

This method supports:
- Multi-input models: [[shape1], [shape2], ...]
- Single-input: [dim1, dim2, ...]

Dynamic dimensions: -1 or (min, max)

Examples:
>>> model.reshape([[2, 2], [1, 3, 224, 244], [10]])
>>> model.reshape([2, 2])
)");

model.def(
"reshape",
[](ov::Model& self, const ov::PartialShape& partial_shape, const py::dict& variables_shapes) {
Expand Down Expand Up @@ -727,7 +823,7 @@ void regclass_graph_Model(py::module m) {
:type partial_shapes: dict[keys, values]
:param variables_shapes: New shapes for variables
:type variables_shapes: dict[keys, values]
)");
)");

model.def("get_output_size",
&ov::Model::get_output_size,
Expand Down
Loading
Loading