onnx-ir 0.1.7__tar.gz → 0.1.8__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.7/src/onnx_ir.egg-info → onnx_ir-0.1.8}/PKG-INFO +6 -2
  2. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/README.md +5 -1
  3. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/__init__.py +1 -1
  4. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/_core.py +5 -0
  5. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/_enums.py +146 -1
  6. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/passes/common/initializer_deduplication.py +22 -10
  7. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/serde.py +3 -2
  8. {onnx_ir-0.1.7 → onnx_ir-0.1.8/src/onnx_ir.egg-info}/PKG-INFO +6 -2
  9. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/LICENSE +0 -0
  10. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/MANIFEST.in +0 -0
  11. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/pyproject.toml +0 -0
  12. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/setup.cfg +0 -0
  13. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/_convenience/__init__.py +0 -0
  14. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/_convenience/_constructors.py +0 -0
  15. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/_display.py +0 -0
  16. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/_graph_comparison.py +0 -0
  17. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/_graph_containers.py +0 -0
  18. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/_io.py +0 -0
  19. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/_linked_list.py +0 -0
  20. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/_metadata.py +0 -0
  21. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/_name_authority.py +0 -0
  22. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/_polyfill.py +0 -0
  23. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/_protocols.py +0 -0
  24. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/_tape.py +0 -0
  25. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/_thirdparty/asciichartpy.py +0 -0
  26. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/_type_casting.py +0 -0
  27. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/_version_utils.py +0 -0
  28. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/convenience.py +0 -0
  29. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/external_data.py +0 -0
  30. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/passes/__init__.py +0 -0
  31. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/passes/_pass_infra.py +0 -0
  32. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/passes/common/__init__.py +0 -0
  33. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/passes/common/_c_api_utils.py +0 -0
  34. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/passes/common/clear_metadata_and_docstring.py +0 -0
  35. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/passes/common/common_subexpression_elimination.py +0 -0
  36. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/passes/common/constant_manipulation.py +0 -0
  37. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/passes/common/identity_elimination.py +0 -0
  38. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/passes/common/inliner.py +0 -0
  39. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/passes/common/naming.py +0 -0
  40. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/passes/common/onnx_checker.py +0 -0
  41. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/passes/common/shape_inference.py +0 -0
  42. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/passes/common/topological_sort.py +0 -0
  43. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/passes/common/unused_removal.py +0 -0
  44. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/py.typed +0 -0
  45. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/tape.py +0 -0
  46. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/tensor_adapters.py +0 -0
  47. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/testing.py +0 -0
  48. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir/traversal.py +0 -0
  49. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir.egg-info/SOURCES.txt +0 -0
  50. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir.egg-info/dependency_links.txt +0 -0
  51. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/src/onnx_ir.egg-info/requires.txt +0 -0
  52. {onnx_ir-0.1.7 → onnx_ir-0.1.8}/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.7
3
+ Version: 0.1.8
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
@@ -22,7 +22,7 @@ Requires-Dist: typing_extensions>=4.10
22
22
  Requires-Dist: ml_dtypes
23
23
  Dynamic: license-file
24
24
 
25
- # ONNX IR
25
+ # <img src="docs/_static/logo-light.png" alt="ONNX IR" width="250"/>
26
26
 
27
27
  [![PyPI - Version](https://img.shields.io/pypi/v/onnx-ir.svg)](https://pypi.org/project/onnx-ir)
28
28
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/onnx-ir.svg)](https://pypi.org/project/onnx-ir)
@@ -60,6 +60,10 @@ pip install git+https://github.com/onnx/ir-py.git
60
60
  - Pythonic and familiar APIs: Classes define Pythonic apis and still map to ONNX protobuf concepts in an intuitive way.
61
61
  - No protobuf dependency: The IR does not require protobuf once the model is converted to the IR representation, decoupling from the serialization format.
62
62
 
63
+ ## Concept Diagram
64
+
65
+ ![Concept Diagram](docs/resource/onnx-ir-entities.svg)
66
+
63
67
  ## Code Organization 🗺️
64
68
 
65
69
  - [`_protocols.py`](src/onnx_ir/_protocols.py): Interfaces defined for all entities in the IR.
@@ -1,4 +1,4 @@
1
- # ONNX IR
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
4
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/onnx-ir.svg)](https://pypi.org/project/onnx-ir)
@@ -36,6 +36,10 @@ pip install git+https://github.com/onnx/ir-py.git
36
36
  - Pythonic and familiar APIs: Classes define Pythonic apis and still map to ONNX protobuf concepts in an intuitive way.
37
37
  - No protobuf dependency: The IR does not require protobuf once the model is converted to the IR representation, decoupling from the serialization format.
38
38
 
39
+ ## Concept Diagram
40
+
41
+ ![Concept Diagram](docs/resource/onnx-ir-entities.svg)
42
+
39
43
  ## Code Organization 🗺️
40
44
 
41
45
  - [`_protocols.py`](src/onnx_ir/_protocols.py): Interfaces defined for all entities in the IR.
@@ -167,4 +167,4 @@ def __set_module() -> None:
167
167
 
168
168
 
169
169
  __set_module()
170
- __version__ = "0.1.7"
170
+ __version__ = "0.1.8"
@@ -836,6 +836,11 @@ class StringTensor(TensorBase, _protocols.TensorProtocol): # pylint: disable=to
836
836
  """The shape of the tensor. Immutable."""
837
837
  return self._shape
838
838
 
839
+ @property
840
+ def nbytes(self) -> int:
841
+ """The number of bytes in the tensor."""
842
+ return sum(len(string) for string in self.string_data())
843
+
839
844
  @property
840
845
  def raw(self) -> Sequence[bytes] | npt.NDArray[np.bytes_]:
841
846
  """Backing data of the tensor. Immutable."""
@@ -5,6 +5,7 @@
5
5
  from __future__ import annotations
6
6
 
7
7
  import enum
8
+ from typing import Any
8
9
 
9
10
  import ml_dtypes
10
11
  import numpy as np
@@ -77,7 +78,7 @@ class DataType(enum.IntEnum):
77
78
  if dtype in _NP_TYPE_TO_DATA_TYPE:
78
79
  return cls(_NP_TYPE_TO_DATA_TYPE[dtype])
79
80
 
80
- if np.issubdtype(dtype, np.str_):
81
+ if np.issubdtype(dtype, np.str_) or np.issubdtype(dtype, np.bytes_):
81
82
  return DataType.STRING
82
83
 
83
84
  # Special cases for handling custom dtypes defined in ONNX (as of onnx 1.18)
@@ -131,6 +132,146 @@ class DataType(enum.IntEnum):
131
132
  raise TypeError(f"Bitwidth not available for ONNX data type: {self}")
132
133
  return _BITWIDTH_MAP[self]
133
134
 
135
+ @property
136
+ def exponent_bitwidth(self) -> int:
137
+ """Returns the bit width of the exponent for floating-point types.
138
+
139
+ .. versionadded:: 0.1.8
140
+
141
+ Raises:
142
+ TypeError: If the data type is not supported.
143
+ """
144
+ if self.is_floating_point():
145
+ return ml_dtypes.finfo(self.numpy()).nexp
146
+
147
+ raise TypeError(f"Exponent not available for ONNX data type: {self}")
148
+
149
+ @property
150
+ def mantissa_bitwidth(self) -> int:
151
+ """Returns the bit width of the mantissa for floating-point types.
152
+
153
+ .. versionadded:: 0.1.8
154
+
155
+ Raises:
156
+ TypeError: If the data type is not supported.
157
+ """
158
+ if self.is_floating_point():
159
+ return ml_dtypes.finfo(self.numpy()).nmant
160
+
161
+ raise TypeError(f"Mantissa not available for ONNX data type: {self}")
162
+
163
+ @property
164
+ def eps(self) -> int | np.floating[Any]:
165
+ """Returns the difference between 1.0 and the next smallest representable float larger than 1.0 for the ONNX data type.
166
+
167
+ Returns 1 for integers.
168
+
169
+ .. versionadded:: 0.1.8
170
+
171
+ Raises:
172
+ TypeError: If the data type is not a numeric data type.
173
+ """
174
+ if self.is_integer():
175
+ return 1
176
+
177
+ if self.is_floating_point():
178
+ return ml_dtypes.finfo(self.numpy()).eps
179
+
180
+ raise TypeError(f"Eps not available for ONNX data type: {self}")
181
+
182
+ @property
183
+ def tiny(self) -> int | np.floating[Any]:
184
+ """Returns the smallest positive non-zero value for the ONNX data type.
185
+
186
+ Returns 1 for integers.
187
+
188
+ .. versionadded:: 0.1.8
189
+
190
+ Raises:
191
+ TypeError: If the data type is not a numeric data type.
192
+ """
193
+ if self.is_integer():
194
+ return 1
195
+
196
+ if self.is_floating_point():
197
+ return ml_dtypes.finfo(self.numpy()).tiny
198
+
199
+ raise TypeError(f"Tiny not available for ONNX data type: {self}")
200
+
201
+ @property
202
+ def min(self) -> int | np.floating[Any]:
203
+ """Returns the minimum representable value for the ONNX data type.
204
+
205
+ .. versionadded:: 0.1.8
206
+
207
+ Raises:
208
+ TypeError: If the data type is not a numeric data type.
209
+ """
210
+ if self.is_integer():
211
+ return ml_dtypes.iinfo(self.numpy()).min
212
+
213
+ if self.is_floating_point():
214
+ return ml_dtypes.finfo(self.numpy()).min
215
+
216
+ raise TypeError(f"Minimum not available for ONNX data type: {self}")
217
+
218
+ @property
219
+ def max(self) -> int | np.floating[Any]:
220
+ """Returns the maximum representable value for the ONNX data type.
221
+
222
+ .. versionadded:: 0.1.8
223
+
224
+ Raises:
225
+ TypeError: If the data type is not a numeric data type.
226
+ """
227
+ if self.is_integer():
228
+ return ml_dtypes.iinfo(self.numpy()).max
229
+
230
+ if self.is_floating_point():
231
+ return ml_dtypes.finfo(self.numpy()).max
232
+
233
+ raise TypeError(f"Maximum not available for ONNX data type: {self}")
234
+
235
+ @property
236
+ def precision(self) -> int:
237
+ """Returns the precision for the ONNX dtype if supported.
238
+
239
+ For floats returns the approximate number of decimal digits to which
240
+ this kind of float is precise. Returns 0 for integers.
241
+
242
+ .. versionadded:: 0.1.8
243
+
244
+ Raises:
245
+ TypeError: If the data type is not a numeric data type.
246
+ """
247
+ if self.is_integer():
248
+ return 0
249
+
250
+ if self.is_floating_point():
251
+ return ml_dtypes.finfo(self.numpy()).precision
252
+
253
+ raise TypeError(f"Precision not available for ONNX data type: {self}")
254
+
255
+ @property
256
+ def resolution(self) -> int | np.floating[Any]:
257
+ """Returns the resolution for the ONNX dtype if supported.
258
+
259
+ Returns the approximate decimal resolution of this type, i.e.,
260
+ 10**-precision. Returns 1 for integers.
261
+
262
+ .. versionadded:: 0.1.8
263
+
264
+ Raises:
265
+ TypeError: If the data type is not a numeric data type.
266
+ """
267
+ if self.is_integer():
268
+ return 1
269
+
270
+ if self.is_floating_point():
271
+ return ml_dtypes.finfo(self.numpy()).resolution
272
+
273
+ raise TypeError(f"Resolution not available for ONNX data type: {self}")
274
+
134
275
  def numpy(self) -> np.dtype:
135
276
  """Returns the numpy dtype for the ONNX data type.
136
277
 
@@ -215,6 +356,10 @@ class DataType(enum.IntEnum):
215
356
  DataType.FLOAT8E8M0,
216
357
  }
217
358
 
359
+ def is_string(self) -> bool:
360
+ """Returns True if the data type is a string type."""
361
+ return self == DataType.STRING
362
+
218
363
  def __repr__(self) -> str:
219
364
  return self.name
220
365
 
@@ -10,6 +10,8 @@ __all__ = ["DeduplicateInitializersPass", "DeduplicateHashedInitializersPass"]
10
10
  import hashlib
11
11
  import logging
12
12
 
13
+ import numpy as np
14
+
13
15
  import onnx_ir as ir
14
16
 
15
17
  logger = logging.getLogger(__name__)
@@ -42,17 +44,27 @@ def _should_skip_initializer(initializer: ir.Value, size_limit: int) -> bool:
42
44
  size_limit,
43
45
  )
44
46
  return True
45
-
46
- if const_val.dtype == ir.DataType.STRING:
47
- # Skip string initializers as they don't have a bytes representation
48
- logger.warning(
49
- "Skipped deduplication of string initializer '%s' (unsupported yet)",
50
- initializer.name,
51
- )
52
- return True
53
47
  return False
54
48
 
55
49
 
50
+ def _tobytes(val):
51
+ """StringTensor does not support tobytes. Use 'string_data' instead.
52
+
53
+ However, 'string_data' yields a list of bytes which cannot be hashed, i.e.,
54
+ cannot be used to index into a dict. To generate keys for identifying
55
+ tensors in initializer deduplication the following converts the list of
56
+ bytes to an array of fixed-length strings which can be flattened into a
57
+ bytes-string. This, together with the tensor shape, is sufficient for
58
+ identifying tensors for deduplication, but it differs from the
59
+ representation used for serializing tensors (that is string_data) by adding
60
+ padding bytes so that each string occupies the same number of consecutive
61
+ bytes in the flattened .tobytes representation.
62
+ """
63
+ if val.dtype.is_string():
64
+ return np.array(val.string_data()).tobytes()
65
+ return val.tobytes()
66
+
67
+
56
68
  class DeduplicateInitializersPass(ir.passes.InPlacePass):
57
69
  """Remove duplicated initializer tensors from the main graph and all subgraphs.
58
70
 
@@ -84,7 +96,7 @@ class DeduplicateInitializersPass(ir.passes.InPlacePass):
84
96
  const_val = initializer.const_value
85
97
  assert const_val is not None
86
98
 
87
- key = (const_val.dtype, tuple(const_val.shape), const_val.tobytes())
99
+ key = (const_val.dtype, tuple(const_val.shape), _tobytes(const_val))
88
100
  if key in initializers:
89
101
  modified = True
90
102
  initializer_to_keep = initializers[key] # type: ignore[index]
@@ -143,7 +155,7 @@ class DeduplicateHashedInitializersPass(ir.passes.InPlacePass):
143
155
  key = (const_val.dtype, tensor_dims, tensor_digest)
144
156
 
145
157
  if key in initializers:
146
- if initializers[key].const_value.tobytes() != const_val.tobytes():
158
+ if _tobytes(initializers[key].const_value) != _tobytes(const_val):
147
159
  logger.warning(
148
160
  "Initializer deduplication failed: "
149
161
  "hashes match but values differ with values %s and %s",
@@ -1784,11 +1784,12 @@ def _fill_in_value_for_attribute(
1784
1784
  ) -> None:
1785
1785
  if type_ == _enums.AttributeType.INT:
1786
1786
  # value: int
1787
- attribute_proto.i = value
1787
+ # Cast bool to int, for example
1788
+ attribute_proto.i = int(value)
1788
1789
  attribute_proto.type = onnx.AttributeProto.INT
1789
1790
  elif type_ == _enums.AttributeType.FLOAT:
1790
1791
  # value: float
1791
- attribute_proto.f = value
1792
+ attribute_proto.f = float(value)
1792
1793
  attribute_proto.type = onnx.AttributeProto.FLOAT
1793
1794
  elif type_ == _enums.AttributeType.STRING:
1794
1795
  # value: str
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: onnx-ir
3
- Version: 0.1.7
3
+ Version: 0.1.8
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
@@ -22,7 +22,7 @@ Requires-Dist: typing_extensions>=4.10
22
22
  Requires-Dist: ml_dtypes
23
23
  Dynamic: license-file
24
24
 
25
- # ONNX IR
25
+ # <img src="docs/_static/logo-light.png" alt="ONNX IR" width="250"/>
26
26
 
27
27
  [![PyPI - Version](https://img.shields.io/pypi/v/onnx-ir.svg)](https://pypi.org/project/onnx-ir)
28
28
  [![PyPI - Python Version](https://img.shields.io/pypi/pyversions/onnx-ir.svg)](https://pypi.org/project/onnx-ir)
@@ -60,6 +60,10 @@ pip install git+https://github.com/onnx/ir-py.git
60
60
  - Pythonic and familiar APIs: Classes define Pythonic apis and still map to ONNX protobuf concepts in an intuitive way.
61
61
  - No protobuf dependency: The IR does not require protobuf once the model is converted to the IR representation, decoupling from the serialization format.
62
62
 
63
+ ## Concept Diagram
64
+
65
+ ![Concept Diagram](docs/resource/onnx-ir-entities.svg)
66
+
63
67
  ## Code Organization 🗺️
64
68
 
65
69
  - [`_protocols.py`](src/onnx_ir/_protocols.py): Interfaces defined for all entities in the 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