-
Notifications
You must be signed in to change notification settings - Fork 3.1k
[Python API] Added implicit input reshaping API and extended reshape() Unit Tests.
#32648
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
base: master
Are you sure you want to change the base?
Changes from 19 commits
9034b31
326382d
fea21a4
0191c57
6fd0438
0c9e259
506f599
eaa8ec1
9c9115f
ce80c25
a98a4ac
041ddca
3f1361f
f29e8b3
46e4cd7
1074c44
84e2e72
3f7fc15
2a279f6
a93273a
43b8877
ad81015
11dd04c
df977ff
56a45f2
649c3ba
7372886
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -533,44 +533,139 @@ void regclass_graph_Model(py::module m) { | |||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| model.def( | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| "reshape", | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| [](ov::Model& self, const py::list& partial_shape, const py::dict& variables_shapes) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const auto new_shape = Common::partial_shape_from_list(partial_shape); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| const auto& inputs = self.inputs(); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (partial_shape.size() == 0) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| throw std::runtime_error("Shapes list cannot be empty."); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bool is_multi_input_format = false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bool has_list = false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bool has_int = false; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| for (size_t i = 0; i < partial_shape.size(); ++i) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| py::handle elem = partial_shape[i]; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (py::isinstance<py::list>(elem)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| has_list = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else if (py::isinstance<py::int_>(elem)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| has_int = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else if (!py::isinstance<py::tuple>(elem)) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| throw std::runtime_error("Invalid shape format"); | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| if (has_list) { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| is_multi_input_format = true; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } else { | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| is_multi_input_format = !has_int; | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| bool has_list = false; | |
| bool has_int = false; | |
| for (size_t i = 0; i < partial_shape.size(); ++i) { | |
| py::handle elem = partial_shape[i]; | |
| if (py::isinstance<py::list>(elem)) { | |
| has_list = true; | |
| } else if (py::isinstance<py::int_>(elem)) { | |
| has_int = true; | |
| } else if (!py::isinstance<py::tuple>(elem)) { | |
| throw std::runtime_error("Invalid shape format"); | |
| } | |
| } | |
| if (has_list) { | |
| is_multi_input_format = true; | |
| } else { | |
| is_multi_input_format = !has_int; | |
| } | |
| bool all_containers = true; | |
| bool has_int = false; | |
| for (size_t i = 0; i < partial_shape.size(); ++i) { | |
| py::handle elem = partial_shape[i]; | |
| if (py::isinstance<py::int_>(elem)) { | |
| has_int = true; | |
| all_containers = false; | |
| } else if (py::isinstance<py::list>(elem) || py::isinstance<py::tuple>(elem)) { | |
| // list/tuple are treated as shape containers at the top level | |
| } else { | |
| throw std::runtime_error("Invalid shape format"); | |
| } | |
| } | |
| // Multi-input format is used only when the number of provided shapes | |
| // matches the number of model inputs and all top-level elements are | |
| // shape containers (lists/tuples). Otherwise treat as a flat shape. | |
| is_multi_input_format = (partial_shape.size() == inputs.size()) && all_containers; |
Outdated
Copilot
AI
Feb 25, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The multi-input parsing path only supports int and (lower, upper) tuples, and explicitly rejects list-based intervals. This is inconsistent with the existing reshape dimension syntax described in the docstring (and typically supported elsewhere via partial_shape_from_handle(...)). To avoid behavior divergence between flat vs multi-input forms, reuse the existing parsing helpers per shape (e.g., parse each inner shape with the same logic used by get_variables_shapes), instead of introducing a reduced/parallel parser.
Outdated
Copilot
AI
Feb 25, 2026
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The updated docstring claims [min, max], openvino.Dimension, and str forms are supported for dimensions, but the newly added multi-input parsing rejects list-based dims and any non-int/tuple dim types. Either expand the implementation to match the documented accepted forms (preferred), or update the docstring to reflect the narrower support.
| (2) `[min, max]`, dynamic dimension where `min` specifies lower bound and `max` specifies upper bound; | |
| the range includes both `min` and `max`; using `-1` for `min` or `max` means no known bound (3) `(min, | |
| max)`, the same as above (4) `-1` is a dynamic dimension without known bounds (4) | |
| `openvino.Dimension` (5) `str` using next syntax: | |
| '?' - to define fully dynamic dimension | |
| '1' - to define dimension which length is 1 | |
| '1..10' - to define bounded dimension | |
| '..10' or '1..' to define dimension with only lower or only upper limit | |
| (2) `(min, max)`, dynamic dimension where `min` specifies lower bound and `max` specifies upper bound; | |
| the range includes both `min` and `max`; using `-1` for `min` or `max` means no known bound | |
| (3) `-1` is a dynamic dimension without known bounds |
Uh oh!
There was an error while loading. Please reload this page.