onnx-ir 0.1.11__tar.gz → 0.1.12__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of onnx-ir might be problematic. Click here for more details.

Files changed (52) hide show
  1. {onnx_ir-0.1.11/src/onnx_ir.egg-info → onnx_ir-0.1.12}/PKG-INFO +1 -2
  2. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/README.md +0 -1
  3. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/__init__.py +1 -1
  4. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/_convenience/__init__.py +25 -14
  5. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/_core.py +49 -0
  6. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/_protocols.py +11 -0
  7. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/passes/common/common_subexpression_elimination.py +3 -2
  8. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/passes/common/constant_manipulation.py +1 -1
  9. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/passes/common/identity_elimination.py +4 -10
  10. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/passes/common/initializer_deduplication.py +2 -2
  11. {onnx_ir-0.1.11 → onnx_ir-0.1.12/src/onnx_ir.egg-info}/PKG-INFO +1 -2
  12. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/LICENSE +0 -0
  13. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/MANIFEST.in +0 -0
  14. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/pyproject.toml +0 -0
  15. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/setup.cfg +0 -0
  16. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/_convenience/_constructors.py +0 -0
  17. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/_display.py +0 -0
  18. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/_enums.py +0 -0
  19. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/_graph_comparison.py +0 -0
  20. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/_graph_containers.py +0 -0
  21. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/_io.py +0 -0
  22. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/_linked_list.py +0 -0
  23. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/_metadata.py +0 -0
  24. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/_name_authority.py +0 -0
  25. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/_polyfill.py +0 -0
  26. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/_tape.py +0 -0
  27. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/_thirdparty/asciichartpy.py +0 -0
  28. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/_type_casting.py +0 -0
  29. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/_version_utils.py +0 -0
  30. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/convenience.py +0 -0
  31. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/external_data.py +0 -0
  32. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/passes/__init__.py +0 -0
  33. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/passes/_pass_infra.py +0 -0
  34. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/passes/common/__init__.py +0 -0
  35. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/passes/common/_c_api_utils.py +0 -0
  36. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/passes/common/clear_metadata_and_docstring.py +0 -0
  37. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/passes/common/inliner.py +0 -0
  38. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/passes/common/naming.py +0 -0
  39. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/passes/common/onnx_checker.py +0 -0
  40. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/passes/common/shape_inference.py +0 -0
  41. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/passes/common/topological_sort.py +0 -0
  42. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/passes/common/unused_removal.py +0 -0
  43. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/py.typed +0 -0
  44. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/serde.py +0 -0
  45. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/tape.py +0 -0
  46. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/tensor_adapters.py +0 -0
  47. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/testing.py +0 -0
  48. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir/traversal.py +0 -0
  49. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir.egg-info/SOURCES.txt +0 -0
  50. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir.egg-info/dependency_links.txt +0 -0
  51. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir.egg-info/requires.txt +0 -0
  52. {onnx_ir-0.1.11 → onnx_ir-0.1.12}/src/onnx_ir.egg-info/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: onnx-ir
3
- Version: 0.1.11
3
+ Version: 0.1.12
4
4
  Summary: Efficient in-memory representation for ONNX
5
5
  Author-email: ONNX Contributors <onnx-technical-discuss@lists.lfaidata.foundation>
6
6
  License-Expression: Apache-2.0
@@ -20,7 +20,6 @@ Dynamic: license-file
20
20
  # <img src="docs/_static/logo-light.png" alt="ONNX IR" width="250"/>
21
21
 
22
22
  [![PyPI - Version](https://img.shields.io/pypi/v/onnx-ir.svg)](https://pypi.org/project/onnx-ir)
23
- [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/onnx-ir.svg)](https://pypi.org/project/onnx-ir)
24
23
  [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
25
24
  [![codecov](https://codecov.io/gh/onnx/ir-py/graph/badge.svg?token=SPQ3G9T78Z)](https://codecov.io/gh/onnx/ir-py)
26
25
  [![PyPI Downloads](https://static.pepy.tech/badge/onnx-ir/month)](https://pepy.tech/projects/onnx-ir)
@@ -1,7 +1,6 @@
1
1
  # <img src="docs/_static/logo-light.png" alt="ONNX IR" width="250"/>
2
2
 
3
3
  [![PyPI - Version](https://img.shields.io/pypi/v/onnx-ir.svg)](https://pypi.org/project/onnx-ir)
4
- [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/onnx-ir.svg)](https://pypi.org/project/onnx-ir)
5
4
  [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
6
5
  [![codecov](https://codecov.io/gh/onnx/ir-py/graph/badge.svg?token=SPQ3G9T78Z)](https://codecov.io/gh/onnx/ir-py)
7
6
  [![PyPI Downloads](https://static.pepy.tech/badge/onnx-ir/month)](https://pepy.tech/projects/onnx-ir)
@@ -168,4 +168,4 @@ def __set_module() -> None:
168
168
 
169
169
 
170
170
  __set_module()
171
- __version__ = "0.1.11"
171
+ __version__ = "0.1.12"
@@ -280,6 +280,7 @@ def convert_attributes(
280
280
  def replace_all_uses_with(
281
281
  values: _protocols.ValueProtocol | Sequence[_protocols.ValueProtocol],
282
282
  replacements: _protocols.ValueProtocol | Sequence[_protocols.ValueProtocol],
283
+ replace_graph_outputs: bool = False,
283
284
  ) -> None:
284
285
  """Replace all uses of the given values with the replacements.
285
286
 
@@ -318,9 +319,22 @@ def replace_all_uses_with(
318
319
  replaced are part of the graph outputs. Be sure to remove the old nodes
319
320
  from the graph using ``graph.remove()`` if they are no longer needed.
320
321
 
322
+ .. versionadded:: 0.1.12
323
+ The ``replace_graph_outputs`` parameter is added.
324
+
325
+ .. versionadded:: 0.1.12
326
+ ValueError is raised when ``replace_graph_outputs`` is False && when the value to
327
+ replace is a graph output.
328
+
321
329
  Args:
322
330
  values: The value or values to be replaced.
323
331
  replacements: The new value or values to use as inputs.
332
+ replace_graph_outputs: If True, graph outputs that reference the values
333
+ being replaced will also be updated to reference the replacements.
334
+
335
+ Raises:
336
+ ValueError: When ``replace_graph_outputs`` is False && when the value to
337
+ replace is a graph output.
324
338
  """
325
339
  if not isinstance(values, Sequence):
326
340
  values = (values,)
@@ -329,8 +343,7 @@ def replace_all_uses_with(
329
343
  if len(values) != len(replacements):
330
344
  raise ValueError("The number of values and replacements must match.")
331
345
  for value, replacement in zip(values, replacements):
332
- for user_node, index in tuple(value.uses()):
333
- user_node.replace_input_with(index, replacement)
346
+ value.replace_all_uses_with(replacement, replace_graph_outputs=replace_graph_outputs)
334
347
 
335
348
 
336
349
  def create_value_mapping(graph: _core.Graph) -> dict[str, _core.Value]:
@@ -397,20 +410,18 @@ def replace_nodes_and_values(
397
410
  """
398
411
  for old_value, new_value in zip(old_values, new_values):
399
412
  # Propagate relevant info from old value to new value
400
- # TODO(Rama): Perhaps this should be a separate utility function. Also, consider
401
- # merging old and new type/shape info.
402
- new_value.type = old_value.type
403
- new_value.shape = old_value.shape
404
- new_value.const_value = old_value.const_value
405
- new_value.name = old_value.name
413
+ # TODO(Rama): Perhaps this should be a separate utility function.
414
+ new_value.type = old_value.type if old_value.type is not None else new_value.type
415
+ new_value.shape = old_value.shape if old_value.shape is not None else new_value.shape
416
+ new_value.const_value = (
417
+ old_value.const_value
418
+ if old_value.const_value is not None
419
+ else new_value.const_value
420
+ )
421
+ new_value.name = old_value.name if old_value.name is not None else new_value.name
406
422
 
407
423
  # Reconnect the users of the deleted values to use the new values
408
- replace_all_uses_with(old_values, new_values)
409
- # Update graph/function outputs if the node generates output
410
- replacement_mapping = dict(zip(old_values, new_values))
411
- for idx, graph_or_function_output in enumerate(graph_or_function.outputs):
412
- if graph_or_function_output in replacement_mapping:
413
- graph_or_function.outputs[idx] = replacement_mapping[graph_or_function_output]
424
+ replace_all_uses_with(old_values, new_values, replace_graph_outputs=True)
414
425
 
415
426
  # insert new nodes after the index node
416
427
  graph_or_function.insert_after(insertion_point, new_nodes)
@@ -2448,6 +2448,55 @@ class Value(_protocols.ValueProtocol, _display.PrettyPrintable):
2448
2448
  """Whether the value is an initializer of a graph."""
2449
2449
  return self._is_initializer
2450
2450
 
2451
+ def replace_all_uses_with(
2452
+ self, replacement: Value, /, replace_graph_outputs: bool = False
2453
+ ) -> None:
2454
+ """Replace all uses of this value with another value.
2455
+
2456
+ If the value is an output of a graph and ``replace_graph_outputs`` is ``True``,
2457
+ the graph output will also be replaced. Be careful when a value appears multiple times
2458
+ in the graph outputs - this is invalid. An identity node will need to be added on each
2459
+ duplicated outputs to ensure a valid ONNX graph.
2460
+
2461
+ You may also want to assign the name of this value to the replacement value
2462
+ to maintain the name when it is a graph output.
2463
+
2464
+ To replace usage of a sequence of values with another sequence of values, consider using
2465
+ :func:`onnx_ir.convenience.replace_all_uses_with`.
2466
+
2467
+ .. versionadded:: 0.1.12
2468
+
2469
+ Args:
2470
+ replacement: The value to replace all uses with.
2471
+ replace_graph_outputs: If True, graph outputs that reference this value
2472
+ will also be updated to reference the replacement.
2473
+
2474
+ Raises:
2475
+ ValueError: When ``replace_graph_outputs`` is False && when the value to
2476
+ replace is a graph output.
2477
+ """
2478
+ # NOTE: Why we don't replace the value name when the value is an output:
2479
+ # When the replacement value is already an output of the graph, renaming it
2480
+ # to the name of this value will cause name conflicts. It is better to let
2481
+ # the user handle the renaming explicitly and insert identity nodes if needed.
2482
+ if self.is_graph_output():
2483
+ graph = self.graph
2484
+ assert graph is not None
2485
+
2486
+ if not replace_graph_outputs:
2487
+ raise ValueError(
2488
+ f"{self!r} is an output of graph {graph.name!r}. "
2489
+ "Set replace_graph_outputs=True or replace the graph output frist before "
2490
+ "calling replace_all_uses_with."
2491
+ )
2492
+
2493
+ for i, output in enumerate(graph.outputs):
2494
+ if output is self:
2495
+ graph.outputs[i] = replacement
2496
+
2497
+ for user_node, index in self.uses():
2498
+ user_node.replace_input_with(index, replacement)
2499
+
2451
2500
 
2452
2501
  @deprecated("Input is deprecated since 0.1.9. Use ir.val(...) instead.")
2453
2502
  def Input(
@@ -203,6 +203,17 @@ class ValueProtocol(Protocol):
203
203
  """Whether this value is an output of a graph."""
204
204
  ...
205
205
 
206
+ def replace_all_uses_with(
207
+ self, new_value: ValueProtocol | None, replace_graph_outputs: bool = False
208
+ ) -> None:
209
+ """Replace all uses of this value with the given new value.
210
+
211
+ Args:
212
+ new_value: The new value to replace this value with.
213
+ replace_graph_outputs: Whether to replace graph outputs that use this value.
214
+ """
215
+ ...
216
+
206
217
 
207
218
  @typing.runtime_checkable
208
219
  class NodeProtocol(Protocol):
@@ -150,8 +150,6 @@ def _remove_node_and_replace_values(
150
150
  remove_values: The values to replace.
151
151
  new_values: The values to replace with.
152
152
  """
153
- # Reconnect the users of the deleted values to use the new values
154
- ir.convenience.replace_all_uses_with(remove_values, new_values)
155
153
  # Update graph/function outputs if the node generates output
156
154
  if any(remove_value.is_graph_output() for remove_value in remove_values):
157
155
  replacement_mapping = dict(zip(remove_values, new_values))
@@ -185,6 +183,9 @@ def _remove_node_and_replace_values(
185
183
  new_value.name = graph_output.name
186
184
  graph.outputs[idx] = new_value
187
185
 
186
+ # Reconnect the users of the deleted values to use the new values
187
+ ir.convenience.replace_all_uses_with(remove_values, new_values)
188
+
188
189
  graph.remove(remove_node, safe=True)
189
190
 
190
191
 
@@ -78,7 +78,7 @@ class LiftConstantsToInitializersPass(ir.passes.InPlacePass):
78
78
  assert node.graph is not None
79
79
  node.graph.register_initializer(initializer)
80
80
  # Replace the constant node with the initializer
81
- ir.convenience.replace_all_uses_with(node.outputs[0], initializer)
81
+ node.outputs[0].replace_all_uses_with(initializer)
82
82
  node.graph.remove(node, safe=True)
83
83
  count += 1
84
84
  logger.debug(
@@ -105,20 +105,14 @@ class IdentityEliminationPass(ir.passes.InPlacePass):
105
105
 
106
106
  # Case 1 & 2 (merged): Eliminate the identity node
107
107
  # Replace all uses of output with input
108
- ir.convenience.replace_all_uses_with(output_value, input_value)
108
+ ir.convenience.replace_all_uses_with(
109
+ output_value, input_value, replace_graph_outputs=True
110
+ )
109
111
 
110
112
  # If output is a graph output, we need to rename input and update graph outputs
111
113
  if output_is_graph_output:
112
- # Store the original output name
113
- original_output_name = output_value.name
114
-
115
114
  # Update the input value to have the output's name
116
- input_value.name = original_output_name
117
-
118
- # Update graph outputs to point to the input value
119
- for idx, graph_output in enumerate(graph_like.outputs):
120
- if graph_output is output_value:
121
- graph_like.outputs[idx] = input_value
115
+ input_value.name = output_value.name
122
116
 
123
117
  # Remove the identity node
124
118
  graph_like.remove(node, safe=True)
@@ -100,7 +100,7 @@ class DeduplicateInitializersPass(ir.passes.InPlacePass):
100
100
  if key in initializers:
101
101
  modified = True
102
102
  initializer_to_keep = initializers[key] # type: ignore[index]
103
- ir.convenience.replace_all_uses_with(initializer, initializer_to_keep)
103
+ initializer.replace_all_uses_with(initializer_to_keep)
104
104
  assert initializer.name is not None
105
105
  graph.initializers.pop(initializer.name)
106
106
  logger.info(
@@ -165,7 +165,7 @@ class DeduplicateHashedInitializersPass(ir.passes.InPlacePass):
165
165
  continue
166
166
  modified = True
167
167
  initializer_to_keep = initializers[key] # type: ignore[index]
168
- ir.convenience.replace_all_uses_with(initializer, initializer_to_keep)
168
+ initializer.replace_all_uses_with(initializer_to_keep)
169
169
  assert initializer.name is not None
170
170
  graph.initializers.pop(initializer.name)
171
171
  logger.info(
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: onnx-ir
3
- Version: 0.1.11
3
+ Version: 0.1.12
4
4
  Summary: Efficient in-memory representation for ONNX
5
5
  Author-email: ONNX Contributors <onnx-technical-discuss@lists.lfaidata.foundation>
6
6
  License-Expression: Apache-2.0
@@ -20,7 +20,6 @@ Dynamic: license-file
20
20
  # <img src="docs/_static/logo-light.png" alt="ONNX IR" width="250"/>
21
21
 
22
22
  [![PyPI - Version](https://img.shields.io/pypi/v/onnx-ir.svg)](https://pypi.org/project/onnx-ir)
23
- [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/onnx-ir.svg)](https://pypi.org/project/onnx-ir)
24
23
  [![Ruff](https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json)](https://github.com/astral-sh/ruff)
25
24
  [![codecov](https://codecov.io/gh/onnx/ir-py/graph/badge.svg?token=SPQ3G9T78Z)](https://codecov.io/gh/onnx/ir-py)
26
25
  [![PyPI Downloads](https://static.pepy.tech/badge/onnx-ir/month)](https://pepy.tech/projects/onnx-ir)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes