onnx-ir 0.1.9__tar.gz → 0.1.10__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.9/src/onnx_ir.egg-info → onnx_ir-0.1.10}/PKG-INFO +1 -1
  2. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/__init__.py +1 -1
  3. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/_convenience/_constructors.py +4 -1
  4. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/_core.py +90 -3
  5. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/passes/common/constant_manipulation.py +5 -0
  6. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/passes/common/naming.py +1 -7
  7. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/serde.py +33 -7
  8. {onnx_ir-0.1.9 → onnx_ir-0.1.10/src/onnx_ir.egg-info}/PKG-INFO +1 -1
  9. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/LICENSE +0 -0
  10. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/MANIFEST.in +0 -0
  11. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/README.md +0 -0
  12. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/pyproject.toml +0 -0
  13. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/setup.cfg +0 -0
  14. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/_convenience/__init__.py +0 -0
  15. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/_display.py +0 -0
  16. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/_enums.py +0 -0
  17. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/_graph_comparison.py +0 -0
  18. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/_graph_containers.py +0 -0
  19. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/_io.py +0 -0
  20. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/_linked_list.py +0 -0
  21. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/_metadata.py +0 -0
  22. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/_name_authority.py +0 -0
  23. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/_polyfill.py +0 -0
  24. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/_protocols.py +0 -0
  25. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/_tape.py +0 -0
  26. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/_thirdparty/asciichartpy.py +0 -0
  27. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/_type_casting.py +0 -0
  28. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/_version_utils.py +0 -0
  29. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/convenience.py +0 -0
  30. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/external_data.py +0 -0
  31. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/passes/__init__.py +0 -0
  32. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/passes/_pass_infra.py +0 -0
  33. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/passes/common/__init__.py +0 -0
  34. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/passes/common/_c_api_utils.py +0 -0
  35. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/passes/common/clear_metadata_and_docstring.py +0 -0
  36. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/passes/common/common_subexpression_elimination.py +0 -0
  37. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/passes/common/identity_elimination.py +0 -0
  38. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/passes/common/initializer_deduplication.py +0 -0
  39. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/passes/common/inliner.py +0 -0
  40. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/passes/common/onnx_checker.py +0 -0
  41. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/passes/common/shape_inference.py +0 -0
  42. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/passes/common/topological_sort.py +0 -0
  43. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/passes/common/unused_removal.py +0 -0
  44. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/py.typed +0 -0
  45. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/tape.py +0 -0
  46. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/tensor_adapters.py +0 -0
  47. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/testing.py +0 -0
  48. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir/traversal.py +0 -0
  49. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir.egg-info/SOURCES.txt +0 -0
  50. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir.egg-info/dependency_links.txt +0 -0
  51. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/src/onnx_ir.egg-info/requires.txt +0 -0
  52. {onnx_ir-0.1.9 → onnx_ir-0.1.10}/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.9
3
+ Version: 0.1.10
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
@@ -168,4 +168,4 @@ def __set_module() -> None:
168
168
 
169
169
 
170
170
  __set_module()
171
- __version__ = "0.1.9"
171
+ __version__ = "0.1.10"
@@ -224,6 +224,7 @@ def val(
224
224
  *,
225
225
  type: ir.TypeProtocol | None = None,
226
226
  const_value: ir.TensorProtocol | None = None,
227
+ metadata_props: dict[str, str] | None = None,
227
228
  ) -> ir.Value:
228
229
  """Create a :class:`~onnx_ir.Value` with the given name and type.
229
230
 
@@ -253,6 +254,7 @@ def val(
253
254
  type: The type of the value. Only one of dtype and type can be specified.
254
255
  const_value: The constant tensor that initializes the value. Supply this argument
255
256
  when you want to create an initializer. The type and shape can be obtained from the tensor.
257
+ metadata_props: The metadata properties that will be serialized to the ONNX proto.
256
258
 
257
259
  Returns:
258
260
  A Value object.
@@ -279,10 +281,11 @@ def val(
279
281
  type=const_tensor_type,
280
282
  shape=_core.Shape(const_value.shape), # type: ignore
281
283
  const_value=const_value,
284
+ metadata_props=metadata_props,
282
285
  )
283
286
 
284
287
  if type is None and dtype is not None:
285
288
  type = _core.TensorType(dtype)
286
289
  if shape is not None and not isinstance(shape, _core.Shape):
287
290
  shape = _core.Shape(shape)
288
- return _core.Value(name=name, type=type, shape=shape)
291
+ return _core.Value(name=name, type=type, shape=shape, metadata_props=metadata_props)
@@ -165,6 +165,11 @@ class TensorBase(abc.ABC, _protocols.TensorProtocol, _display.PrettyPrintable):
165
165
 
166
166
  @property
167
167
  def metadata_props(self) -> dict[str, str]:
168
+ """The metadata properties of the tensor.
169
+
170
+ The metadata properties are used to store additional information about the tensor.
171
+ Unlike ``meta``, this property is serialized to the ONNX proto.
172
+ """
168
173
  if self._metadata_props is None:
169
174
  self._metadata_props = {}
170
175
  return self._metadata_props
@@ -1214,6 +1219,12 @@ class Shape(_protocols.ShapeProtocol, _display.PrettyPrintable):
1214
1219
 
1215
1220
  Use :meth:`get_denotation` and :meth:`set_denotation` to access and modify the denotations.
1216
1221
 
1222
+ .. note::
1223
+ Two shapes can be compared for equality. Be careful when comparing shapes with
1224
+ unknown dimensions (``None``), as they may not be considered semantically equal
1225
+ even if all dimensions are the same. You can use :meth:`has_unknown_dim` to
1226
+ check if a shape has any unknown dimensions.
1227
+
1217
1228
  Example::
1218
1229
 
1219
1230
  >>> import onnx_ir as ir
@@ -1422,6 +1433,29 @@ class Shape(_protocols.ShapeProtocol, _display.PrettyPrintable):
1422
1433
  return not self.is_static()
1423
1434
  return not self.is_static(dim)
1424
1435
 
1436
+ def is_unknown_dim(self, dim: int) -> bool:
1437
+ """Return True if the dimension is unknown (None).
1438
+
1439
+ A dynamic dimension without a symbolic name is considered unknown.
1440
+
1441
+ .. versionadded:: 0.1.10
1442
+
1443
+ Args:
1444
+ dim: The index of the dimension.
1445
+ """
1446
+ dim_obj = self._dims[dim]
1447
+ return isinstance(dim_obj, SymbolicDim) and dim_obj.value is None
1448
+
1449
+ def has_unknown_dim(self) -> bool:
1450
+ """Return True if any dimension is unknown (None).
1451
+
1452
+ You can use :meth:`is_unknown_dim` to check if a specific dimension is unknown.
1453
+
1454
+ .. versionadded:: 0.1.10
1455
+ """
1456
+ # We can use "in" directly because SymbolicDim implements __eq__ with None
1457
+ return None in self._dims
1458
+
1425
1459
 
1426
1460
  def _quoted(string: str) -> str:
1427
1461
  """Return a quoted string.
@@ -2022,9 +2056,18 @@ class Value(_protocols.ValueProtocol, _display.PrettyPrintable):
2022
2056
  type: _protocols.TypeProtocol | None = None,
2023
2057
  doc_string: str | None = None,
2024
2058
  const_value: _protocols.TensorProtocol | None = None,
2059
+ metadata_props: dict[str, str] | None = None,
2025
2060
  ) -> None:
2026
2061
  """Initialize a value.
2027
2062
 
2063
+ When assigning a name to the value, the name of the backing `const_value` (Tensor)
2064
+ will also be updated. If the value is an initializer of a graph, the initializers
2065
+ dictionary of the graph will also be updated.
2066
+
2067
+ .. versionchanged:: 0.1.10
2068
+ Assigning a name to the value will also update the graph initializer entry
2069
+ if the value is an initializer of a graph.
2070
+
2028
2071
  Args:
2029
2072
  producer: The node that produces the value.
2030
2073
  It can be ``None`` when the value is initialized first than its producer.
@@ -2034,11 +2077,12 @@ class Value(_protocols.ValueProtocol, _display.PrettyPrintable):
2034
2077
  type: The type of the value.
2035
2078
  doc_string: The documentation string.
2036
2079
  const_value: The constant tensor if the value is constant.
2080
+ metadata_props: Metadata that will be serialized to the ONNX file.
2037
2081
  """
2038
2082
  self._producer: Node | None = producer
2039
2083
  self._index: int | None = index
2040
2084
  self._metadata: _metadata.MetadataStore | None = None
2041
- self._metadata_props: dict[str, str] | None = None
2085
+ self._metadata_props: dict[str, str] | None = metadata_props
2042
2086
 
2043
2087
  self._name: str | None = name
2044
2088
  self._shape: Shape | None = shape
@@ -2172,7 +2216,23 @@ class Value(_protocols.ValueProtocol, _display.PrettyPrintable):
2172
2216
  def name(self, value: str | None) -> None:
2173
2217
  if self._const_value is not None:
2174
2218
  self._const_value.name = value
2219
+ old_name = self._name
2175
2220
  self._name = value
2221
+ if self.is_initializer():
2222
+ if value is None:
2223
+ raise ValueError(
2224
+ "Initializer value cannot have name set to None. Please pop() the value from initializers first"
2225
+ )
2226
+ # Rename the initializer entry in the graph
2227
+ graph = self._graph
2228
+ assert graph is not None
2229
+ assert old_name is not None
2230
+ if value in graph.initializers and graph.initializers[value] is not self:
2231
+ raise ValueError(
2232
+ f"Cannot rename initializer to '{value}': an initializer with that name already exists."
2233
+ )
2234
+ graph.initializers.pop(old_name)
2235
+ graph.initializers[value] = self
2176
2236
 
2177
2237
  @property
2178
2238
  def type(self) -> _protocols.TypeProtocol | None:
@@ -2226,9 +2286,16 @@ class Value(_protocols.ValueProtocol, _display.PrettyPrintable):
2226
2286
  def const_value(
2227
2287
  self,
2228
2288
  ) -> _protocols.TensorProtocol | None:
2229
- """A concrete value.
2289
+ """The backing constant tensor for the value.
2290
+
2291
+ If the ``Value`` has a ``const_value`` and is part of a graph initializers
2292
+ dictionary, the value is an initialized value. Its ``const_value``
2293
+ will appear as an ``initializer`` in the GraphProto when serialized.
2230
2294
 
2231
- The value can be backed by different raw data types, such as numpy arrays.
2295
+ If the ``Value`` is not part of a graph initializers dictionary, the ``const_value``
2296
+ field will be ignored during serialization.
2297
+
2298
+ ``const_value`` can be backed by different raw data types, such as numpy arrays.
2232
2299
  The only guarantee is that it conforms TensorProtocol.
2233
2300
  """
2234
2301
  return self._const_value
@@ -2258,6 +2325,11 @@ class Value(_protocols.ValueProtocol, _display.PrettyPrintable):
2258
2325
 
2259
2326
  @property
2260
2327
  def metadata_props(self) -> dict[str, str]:
2328
+ """The metadata properties of the value.
2329
+
2330
+ The metadata properties are used to store additional information about the value.
2331
+ Unlike ``meta``, this property is serialized to the ONNX proto.
2332
+ """
2261
2333
  if self._metadata_props is None:
2262
2334
  self._metadata_props = {}
2263
2335
  return self._metadata_props
@@ -2805,6 +2877,11 @@ class Graph(_protocols.GraphProtocol, Sequence[Node], _display.PrettyPrintable):
2805
2877
 
2806
2878
  @property
2807
2879
  def metadata_props(self) -> dict[str, str]:
2880
+ """The metadata properties of the graph.
2881
+
2882
+ The metadata properties are used to store additional information about the graph.
2883
+ Unlike ``meta``, this property is serialized to the ONNX proto.
2884
+ """
2808
2885
  if self._metadata_props is None:
2809
2886
  self._metadata_props = {}
2810
2887
  return self._metadata_props
@@ -3057,6 +3134,11 @@ class Model(_protocols.ModelProtocol, _display.PrettyPrintable):
3057
3134
 
3058
3135
  @property
3059
3136
  def metadata_props(self) -> dict[str, str]:
3137
+ """The metadata properties of the model.
3138
+
3139
+ The metadata properties are used to store additional information about the model.
3140
+ Unlike ``meta``, this property is serialized to the ONNX proto.
3141
+ """
3060
3142
  if self._metadata_props is None:
3061
3143
  self._metadata_props = {}
3062
3144
  return self._metadata_props
@@ -3250,6 +3332,11 @@ class Function(_protocols.FunctionProtocol, Sequence[Node], _display.PrettyPrint
3250
3332
 
3251
3333
  @property
3252
3334
  def metadata_props(self) -> dict[str, str]:
3335
+ """The metadata properties of the function.
3336
+
3337
+ The metadata properties are used to store additional information about the function.
3338
+ Unlike ``meta``, this property is serialized to the ONNX proto.
3339
+ """
3253
3340
  return self._graph.metadata_props
3254
3341
 
3255
3342
  def all_nodes(self) -> Iterator[Node]:
@@ -69,7 +69,12 @@ class LiftConstantsToInitializersPass(ir.passes.InPlacePass):
69
69
  shape=tensor.shape, # type: ignore[arg-type]
70
70
  type=ir.TensorType(tensor.dtype),
71
71
  const_value=tensor,
72
+ # Preserve metadata from Constant value into the onnx model
73
+ metadata_props=node.outputs[0].metadata_props.copy(),
72
74
  )
75
+ # Preserve value meta from the Constant output for intermediate analysis
76
+ initializer.meta.update(node.outputs[0].meta)
77
+
73
78
  assert node.graph is not None
74
79
  node.graph.register_initializer(initializer)
75
80
  # Replace the constant node with the initializer
@@ -193,14 +193,8 @@ class NameFixPass(ir.passes.InPlacePass):
193
193
  if not value.name:
194
194
  modified = self._assign_value_name(value, used_value_names, value_counter)
195
195
  else:
196
- old_name = value.name
197
196
  modified = self._fix_duplicate_value_name(value, used_value_names, value_counter)
198
- if modified:
199
- assert value.graph is not None
200
- if value.is_initializer():
201
- value.graph.initializers.pop(old_name)
202
- # Add the initializer back with the new name
203
- value.graph.initializers.add(value)
197
+ # initializers dictionary is updated automatically when the Value is renamed
204
198
 
205
199
  # Record the final name for this value
206
200
  assert value.name is not None
@@ -709,8 +709,7 @@ def _deserialize_graph(
709
709
  annotation.tensor_name: annotation for annotation in proto.quantization_annotation
710
710
  }
711
711
 
712
- # Create values for initializers and inputs
713
- initializer_tensors = [deserialize_tensor(tensor) for tensor in proto.initializer]
712
+ # Create values for inputs
714
713
  inputs = [_core.Value(name=info.name) for info in proto.input]
715
714
  for info, value in zip(proto.input, inputs):
716
715
  deserialize_value_info_proto(info, value)
@@ -725,6 +724,11 @@ def _deserialize_graph(
725
724
  # Enter the graph scope by pushing the values for this scope to the stack
726
725
  scoped_values.append(values)
727
726
 
727
+ # Build the value info dictionary to allow for quick lookup for this graph scope
728
+ value_info = {info.name: info for info in proto.value_info}
729
+
730
+ # Create values for initializers
731
+ initializer_tensors = [deserialize_tensor(tensor) for tensor in proto.initializer]
728
732
  initializer_values = []
729
733
  for i, tensor in enumerate(initializer_tensors):
730
734
  initializer_name = tensor.name
@@ -750,6 +754,8 @@ def _deserialize_graph(
750
754
  shape=tensor.shape, # type: ignore[arg-type]
751
755
  const_value=tensor,
752
756
  )
757
+ if initializer_name in value_info:
758
+ deserialize_value_info_proto(value_info[initializer_name], initializer_value)
753
759
  if initializer_value.name in quantization_annotations:
754
760
  _deserialize_quantization_annotation(
755
761
  quantization_annotations[initializer_value.name], initializer_value
@@ -757,9 +763,6 @@ def _deserialize_graph(
757
763
  values[initializer_name] = initializer_value
758
764
  initializer_values.append(initializer_value)
759
765
 
760
- # Build the value info dictionary to allow for quick lookup for this graph scope
761
- value_info = {info.name: info for info in proto.value_info}
762
-
763
766
  # Declare values for all node outputs from this graph scope. This is necessary
764
767
  # to handle the case where a node in a subgraph uses a value that is declared out
765
768
  # of order in the outer graph. Declaring the values first allows us to find the
@@ -1390,7 +1393,12 @@ def _should_create_value_info_for_value(value: _protocols.ValueProtocol) -> bool
1390
1393
  True if value info should be created for the value.
1391
1394
  """
1392
1395
  # No need to serialize value info if it is not set
1393
- if value.shape is None and value.type is None:
1396
+ if (
1397
+ value.shape is None
1398
+ and value.type is None
1399
+ and not value.metadata_props
1400
+ and not value.doc_string
1401
+ ):
1394
1402
  return False
1395
1403
  if not value.name:
1396
1404
  logger.debug("Did not serialize '%s' because its name is empty", value)
@@ -1967,11 +1975,26 @@ def serialize_type(type_protocol: _protocols.TypeProtocol) -> onnx.TypeProto:
1967
1975
  @_capture_errors(lambda type_proto, from_: repr(from_))
1968
1976
  def serialize_shape_into(type_proto: onnx.TypeProto, from_: _protocols.ShapeProtocol) -> None:
1969
1977
  value_field = type_proto.WhichOneof("value")
1978
+ if value_field is None:
1979
+ # We cannot write the shape because we do not know where to write it
1980
+ logger.warning(
1981
+ # TODO(justinchuby): Show more context about the value when move everything to an object
1982
+ "The value type for shape %s is not known. Please set type for the value. Skipping serialization",
1983
+ from_,
1984
+ )
1985
+ return
1970
1986
  tensor_type = getattr(type_proto, value_field)
1971
1987
  while not isinstance(tensor_type.elem_type, int):
1972
1988
  # Find the leaf type that has the shape field
1973
1989
  type_proto = tensor_type.elem_type
1974
1990
  value_field = type_proto.WhichOneof("value")
1991
+ if value_field is None:
1992
+ logger.warning(
1993
+ # TODO(justinchuby): Show more context about the value when move everything to an object
1994
+ "The value type for shape %s is not known. Please set type for the value. Skipping serialization",
1995
+ from_,
1996
+ )
1997
+ return
1975
1998
  tensor_type = getattr(type_proto, value_field)
1976
1999
  # When from is empty, we still need to set the shape field to an empty list by touching it
1977
2000
  tensor_type.shape.ClearField("dim")
@@ -1992,5 +2015,8 @@ def serialize_dimension_into(
1992
2015
  dim_proto.dim_value = dim
1993
2016
  elif isinstance(dim, (_core.SymbolicDim, _protocols.SymbolicDimProtocol)):
1994
2017
  if dim.value is not None:
1995
- # TODO(justinchuby): None is probably not a valid value for dim_param
1996
2018
  dim_proto.dim_param = str(dim.value)
2019
+ # NOTE: None is a valid value for symbolic dimension:
2020
+ # A dimension MAY have neither dim_value nor dim_param set. Such a dimension
2021
+ # represents an unknown dimension unrelated to other unknown dimensions.
2022
+ # Here we will just leave the dim_proto empty.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: onnx-ir
3
- Version: 0.1.9
3
+ Version: 0.1.10
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
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
File without changes