onnx-ir 0.1.8__py3-none-any.whl → 0.1.10__py3-none-any.whl
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.
- onnx_ir/__init__.py +3 -2
- onnx_ir/_convenience/__init__.py +4 -4
- onnx_ir/_convenience/_constructors.py +78 -4
- onnx_ir/_core.py +148 -44
- onnx_ir/_enums.py +5 -8
- onnx_ir/passes/common/constant_manipulation.py +5 -0
- onnx_ir/passes/common/naming.py +1 -7
- onnx_ir/serde.py +62 -14
- {onnx_ir-0.1.8.dist-info → onnx_ir-0.1.10.dist-info}/METADATA +2 -2
- {onnx_ir-0.1.8.dist-info → onnx_ir-0.1.10.dist-info}/RECORD +13 -13
- {onnx_ir-0.1.8.dist-info → onnx_ir-0.1.10.dist-info}/WHEEL +0 -0
- {onnx_ir-0.1.8.dist-info → onnx_ir-0.1.10.dist-info}/licenses/LICENSE +0 -0
- {onnx_ir-0.1.8.dist-info → onnx_ir-0.1.10.dist-info}/top_level.txt +0 -0
onnx_ir/__init__.py
CHANGED
|
@@ -78,6 +78,7 @@ __all__ = [
|
|
|
78
78
|
# Convenience constructors
|
|
79
79
|
"tensor",
|
|
80
80
|
"node",
|
|
81
|
+
"val",
|
|
81
82
|
# Pass infrastructure
|
|
82
83
|
"passes",
|
|
83
84
|
# IO
|
|
@@ -90,7 +91,7 @@ __all__ = [
|
|
|
90
91
|
import types
|
|
91
92
|
|
|
92
93
|
from onnx_ir import convenience, external_data, passes, serde, tape, traversal
|
|
93
|
-
from onnx_ir._convenience._constructors import node, tensor
|
|
94
|
+
from onnx_ir._convenience._constructors import node, tensor, val
|
|
94
95
|
from onnx_ir._core import (
|
|
95
96
|
Attr,
|
|
96
97
|
AttrFloat32,
|
|
@@ -167,4 +168,4 @@ def __set_module() -> None:
|
|
|
167
168
|
|
|
168
169
|
|
|
169
170
|
__set_module()
|
|
170
|
-
__version__ = "0.1.
|
|
171
|
+
__version__ = "0.1.10"
|
onnx_ir/_convenience/__init__.py
CHANGED
|
@@ -226,7 +226,7 @@ def convert_attributes(
|
|
|
226
226
|
... "type_protos": [ir.TensorType(ir.DataType.FLOAT), ir.TensorType(ir.DataType.FLOAT)],
|
|
227
227
|
... }
|
|
228
228
|
>>> convert_attributes(attrs)
|
|
229
|
-
[Attr('int', INT, 1), Attr('float', FLOAT, 1.0), Attr('str', STRING, 'hello'), Attr('ints', INTS,
|
|
229
|
+
[Attr('int', INT, 1), Attr('float', FLOAT, 1.0), Attr('str', STRING, 'hello'), Attr('ints', INTS, (1, 2, 3)), Attr('floats', FLOATS, (1.0, 2.0, 3.0)), Attr('strings', STRINGS, ('hello', 'world')), Attr('tensor', TENSOR, Tensor<DOUBLE,[3]>(array([1., 2., 3.]), name=None)), Attr('tensor_proto', TENSOR, TensorProtoTensor<FLOAT,[3]>(array([1., 2., 3.], dtype=float32), name='proto')), Attr('graph', GRAPH, Graph(
|
|
230
230
|
name='graph0',
|
|
231
231
|
inputs=(
|
|
232
232
|
<BLANKLINE>
|
|
@@ -235,7 +235,7 @@ def convert_attributes(
|
|
|
235
235
|
<BLANKLINE>
|
|
236
236
|
),
|
|
237
237
|
len()=0
|
|
238
|
-
)), Attr('graphs', GRAPHS,
|
|
238
|
+
)), Attr('graphs', GRAPHS, (Graph(
|
|
239
239
|
name='graph1',
|
|
240
240
|
inputs=(
|
|
241
241
|
<BLANKLINE>
|
|
@@ -253,7 +253,7 @@ def convert_attributes(
|
|
|
253
253
|
<BLANKLINE>
|
|
254
254
|
),
|
|
255
255
|
len()=0
|
|
256
|
-
)
|
|
256
|
+
))), Attr('type_proto', TYPE_PROTO, Tensor(FLOAT)), Attr('type_protos', TYPE_PROTOS, (Tensor(FLOAT), Tensor(FLOAT)))]
|
|
257
257
|
|
|
258
258
|
.. important::
|
|
259
259
|
An empty sequence should be created with an explicit type by initializing
|
|
@@ -293,7 +293,7 @@ def replace_all_uses_with(
|
|
|
293
293
|
We want to replace the node A with a new node D::
|
|
294
294
|
|
|
295
295
|
>>> import onnx_ir as ir
|
|
296
|
-
>>> input = ir.
|
|
296
|
+
>>> input = ir.val("input")
|
|
297
297
|
>>> node_a = ir.Node("", "A", [input])
|
|
298
298
|
>>> node_b = ir.Node("", "B", node_a.outputs)
|
|
299
299
|
>>> node_c = ir.Node("", "C", node_a.outputs)
|
|
@@ -25,7 +25,7 @@ if typing.TYPE_CHECKING:
|
|
|
25
25
|
|
|
26
26
|
def tensor(
|
|
27
27
|
value: npt.ArrayLike | onnx.TensorProto | ir.DLPackCompatible | ir.ArrayCompatible,
|
|
28
|
-
dtype:
|
|
28
|
+
dtype: ir.DataType | None = None,
|
|
29
29
|
name: str | None = None,
|
|
30
30
|
doc_string: str | None = None,
|
|
31
31
|
) -> _protocols.TensorProtocol:
|
|
@@ -159,7 +159,7 @@ def node(
|
|
|
159
159
|
doc_string: str | None = None,
|
|
160
160
|
metadata_props: dict[str, str] | None = None,
|
|
161
161
|
) -> ir.Node:
|
|
162
|
-
"""Create
|
|
162
|
+
"""Create a :class:`~onnx_ir.Node`.
|
|
163
163
|
|
|
164
164
|
This is a convenience constructor for creating a Node that supports Python
|
|
165
165
|
objects as attributes.
|
|
@@ -167,8 +167,8 @@ def node(
|
|
|
167
167
|
Example::
|
|
168
168
|
|
|
169
169
|
>>> import onnx_ir as ir
|
|
170
|
-
>>> input_a = ir.
|
|
171
|
-
>>> input_b = ir.
|
|
170
|
+
>>> input_a = ir.val("A", shape=[1, 2], type=ir.TensorType(ir.DataType.INT32))
|
|
171
|
+
>>> input_b = ir.val("B", shape=[1, 2], type=ir.TensorType(ir.DataType.INT32))
|
|
172
172
|
>>> node = ir.node(
|
|
173
173
|
... "SomeOp",
|
|
174
174
|
... inputs=[input_a, input_b],
|
|
@@ -215,3 +215,77 @@ def node(
|
|
|
215
215
|
doc_string=doc_string,
|
|
216
216
|
metadata_props=metadata_props,
|
|
217
217
|
)
|
|
218
|
+
|
|
219
|
+
|
|
220
|
+
def val(
|
|
221
|
+
name: str | None,
|
|
222
|
+
dtype: ir.DataType | None = None,
|
|
223
|
+
shape: ir.Shape | Sequence[int | str | None] | None = None,
|
|
224
|
+
*,
|
|
225
|
+
type: ir.TypeProtocol | None = None,
|
|
226
|
+
const_value: ir.TensorProtocol | None = None,
|
|
227
|
+
metadata_props: dict[str, str] | None = None,
|
|
228
|
+
) -> ir.Value:
|
|
229
|
+
"""Create a :class:`~onnx_ir.Value` with the given name and type.
|
|
230
|
+
|
|
231
|
+
This is a convenience constructor for creating a Value that allows you to specify
|
|
232
|
+
dtype and shape in a more relaxed manner. Whereas to create a Value directly, you
|
|
233
|
+
need to create a :class:`~onnx_ir.TypeProtocol` and :class:`~onnx_ir.Shape` object
|
|
234
|
+
first, this function allows you to specify dtype as a :class:`~onnx_ir.DataType`
|
|
235
|
+
and shape as a sequence of integers or symbolic dimensions.
|
|
236
|
+
|
|
237
|
+
Example::
|
|
238
|
+
|
|
239
|
+
>>> import onnx_ir as ir
|
|
240
|
+
>>> t = ir.val("x", ir.DataType.FLOAT, ["N", 42, 3])
|
|
241
|
+
>>> t.name
|
|
242
|
+
'x'
|
|
243
|
+
>>> t.type
|
|
244
|
+
Tensor(FLOAT)
|
|
245
|
+
>>> t.shape
|
|
246
|
+
Shape([SymbolicDim(N), 42, 3])
|
|
247
|
+
|
|
248
|
+
.. versionadded:: 0.1.9
|
|
249
|
+
|
|
250
|
+
Args:
|
|
251
|
+
name: The name of the value.
|
|
252
|
+
dtype: The data type of the TensorType of the value. This is used only when type is None.
|
|
253
|
+
shape: The shape of the value.
|
|
254
|
+
type: The type of the value. Only one of dtype and type can be specified.
|
|
255
|
+
const_value: The constant tensor that initializes the value. Supply this argument
|
|
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.
|
|
258
|
+
|
|
259
|
+
Returns:
|
|
260
|
+
A Value object.
|
|
261
|
+
"""
|
|
262
|
+
if const_value is not None:
|
|
263
|
+
const_tensor_type = _core.TensorType(const_value.dtype)
|
|
264
|
+
if type is not None and type != const_tensor_type:
|
|
265
|
+
raise ValueError(
|
|
266
|
+
f"The type does not match the const_value. type={type} but const_value has type {const_tensor_type}. "
|
|
267
|
+
"You do not have to specify the type when const_value is provided."
|
|
268
|
+
)
|
|
269
|
+
if dtype is not None and dtype != const_value.dtype:
|
|
270
|
+
raise ValueError(
|
|
271
|
+
f"The dtype does not match the const_value. dtype={dtype} but const_value has dtype {const_value.dtype}. "
|
|
272
|
+
"You do not have to specify the dtype when const_value is provided."
|
|
273
|
+
)
|
|
274
|
+
if shape is not None and _core.Shape(shape) != const_value.shape:
|
|
275
|
+
raise ValueError(
|
|
276
|
+
f"The shape does not match the const_value. shape={shape} but const_value has shape {const_value.shape}. "
|
|
277
|
+
"You do not have to specify the shape when const_value is provided."
|
|
278
|
+
)
|
|
279
|
+
return _core.Value(
|
|
280
|
+
name=name,
|
|
281
|
+
type=const_tensor_type,
|
|
282
|
+
shape=_core.Shape(const_value.shape), # type: ignore
|
|
283
|
+
const_value=const_value,
|
|
284
|
+
metadata_props=metadata_props,
|
|
285
|
+
)
|
|
286
|
+
|
|
287
|
+
if type is None and dtype is not None:
|
|
288
|
+
type = _core.TensorType(dtype)
|
|
289
|
+
if shape is not None and not isinstance(shape, _core.Shape):
|
|
290
|
+
shape = _core.Shape(shape)
|
|
291
|
+
return _core.Value(name=name, type=type, shape=shape, metadata_props=metadata_props)
|
onnx_ir/_core.py
CHANGED
|
@@ -45,7 +45,7 @@ from typing import (
|
|
|
45
45
|
|
|
46
46
|
import ml_dtypes
|
|
47
47
|
import numpy as np
|
|
48
|
-
from typing_extensions import TypeIs
|
|
48
|
+
from typing_extensions import TypeIs, deprecated
|
|
49
49
|
|
|
50
50
|
import onnx_ir
|
|
51
51
|
from onnx_ir import (
|
|
@@ -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 =
|
|
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
|
-
"""
|
|
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.
|
|
2294
|
+
|
|
2295
|
+
If the ``Value`` is not part of a graph initializers dictionary, the ``const_value``
|
|
2296
|
+
field will be ignored during serialization.
|
|
2230
2297
|
|
|
2231
|
-
|
|
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
|
|
@@ -2275,6 +2347,7 @@ class Value(_protocols.ValueProtocol, _display.PrettyPrintable):
|
|
|
2275
2347
|
return self._is_initializer
|
|
2276
2348
|
|
|
2277
2349
|
|
|
2350
|
+
@deprecated("Input is deprecated since 0.1.9. Use ir.val(...) instead.")
|
|
2278
2351
|
def Input(
|
|
2279
2352
|
name: str | None = None,
|
|
2280
2353
|
shape: Shape | None = None,
|
|
@@ -2804,6 +2877,11 @@ class Graph(_protocols.GraphProtocol, Sequence[Node], _display.PrettyPrintable):
|
|
|
2804
2877
|
|
|
2805
2878
|
@property
|
|
2806
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
|
+
"""
|
|
2807
2885
|
if self._metadata_props is None:
|
|
2808
2886
|
self._metadata_props = {}
|
|
2809
2887
|
return self._metadata_props
|
|
@@ -3056,6 +3134,11 @@ class Model(_protocols.ModelProtocol, _display.PrettyPrintable):
|
|
|
3056
3134
|
|
|
3057
3135
|
@property
|
|
3058
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
|
+
"""
|
|
3059
3142
|
if self._metadata_props is None:
|
|
3060
3143
|
self._metadata_props = {}
|
|
3061
3144
|
return self._metadata_props
|
|
@@ -3249,6 +3332,11 @@ class Function(_protocols.FunctionProtocol, Sequence[Node], _display.PrettyPrint
|
|
|
3249
3332
|
|
|
3250
3333
|
@property
|
|
3251
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
|
+
"""
|
|
3252
3340
|
return self._graph.metadata_props
|
|
3253
3341
|
|
|
3254
3342
|
def all_nodes(self) -> Iterator[Node]:
|
|
@@ -3397,6 +3485,31 @@ class Attr(
|
|
|
3397
3485
|
*,
|
|
3398
3486
|
doc_string: str | None = None,
|
|
3399
3487
|
) -> None:
|
|
3488
|
+
# Quick checks to ensure that INT and FLOAT attributes are stored as int and float,
|
|
3489
|
+
# not np.int32, np.float32, bool, etc.
|
|
3490
|
+
# This also allows errors to be raised at the time of construction instead of later
|
|
3491
|
+
# during serialization.
|
|
3492
|
+
# TODO(justinchuby): Use case matching when we drop support for Python 3.9
|
|
3493
|
+
if value is None:
|
|
3494
|
+
# Value can be None for reference attributes or when it is used as a
|
|
3495
|
+
# placeholder for schemas
|
|
3496
|
+
pass
|
|
3497
|
+
elif type == _enums.AttributeType.INT:
|
|
3498
|
+
value = int(value)
|
|
3499
|
+
elif type == _enums.AttributeType.FLOAT:
|
|
3500
|
+
value = float(value)
|
|
3501
|
+
elif type == _enums.AttributeType.INTS:
|
|
3502
|
+
value = tuple(int(v) for v in value)
|
|
3503
|
+
elif type == _enums.AttributeType.FLOATS:
|
|
3504
|
+
value = tuple(float(v) for v in value)
|
|
3505
|
+
elif type in {
|
|
3506
|
+
_enums.AttributeType.STRINGS,
|
|
3507
|
+
_enums.AttributeType.TENSORS,
|
|
3508
|
+
_enums.AttributeType.GRAPHS,
|
|
3509
|
+
_enums.AttributeType.TYPE_PROTOS,
|
|
3510
|
+
}:
|
|
3511
|
+
value = tuple(value)
|
|
3512
|
+
|
|
3400
3513
|
self._name = name
|
|
3401
3514
|
self._type = type
|
|
3402
3515
|
self._value = value
|
|
@@ -3458,7 +3571,7 @@ class Attr(
|
|
|
3458
3571
|
return f"@{self.ref_attr_name}"
|
|
3459
3572
|
if self.type == _enums.AttributeType.GRAPH:
|
|
3460
3573
|
return textwrap.indent("\n" + str(self.value), " " * 4)
|
|
3461
|
-
return
|
|
3574
|
+
return repr(self.value)
|
|
3462
3575
|
|
|
3463
3576
|
def __repr__(self) -> str:
|
|
3464
3577
|
if self.is_ref():
|
|
@@ -3472,8 +3585,8 @@ class Attr(
|
|
|
3472
3585
|
raise TypeError(
|
|
3473
3586
|
f"Attribute '{self.name}' is not of type FLOAT. Actual type: {self.type}"
|
|
3474
3587
|
)
|
|
3475
|
-
#
|
|
3476
|
-
return
|
|
3588
|
+
# value is guaranteed to be a float in the constructor
|
|
3589
|
+
return self.value
|
|
3477
3590
|
|
|
3478
3591
|
def as_int(self) -> int:
|
|
3479
3592
|
"""Get the attribute value as an int."""
|
|
@@ -3481,8 +3594,8 @@ class Attr(
|
|
|
3481
3594
|
raise TypeError(
|
|
3482
3595
|
f"Attribute '{self.name}' is not of type INT. Actual type: {self.type}"
|
|
3483
3596
|
)
|
|
3484
|
-
#
|
|
3485
|
-
return
|
|
3597
|
+
# value is guaranteed to be an int in the constructor
|
|
3598
|
+
return self.value
|
|
3486
3599
|
|
|
3487
3600
|
def as_string(self) -> str:
|
|
3488
3601
|
"""Get the attribute value as a string."""
|
|
@@ -3490,9 +3603,10 @@ class Attr(
|
|
|
3490
3603
|
raise TypeError(
|
|
3491
3604
|
f"Attribute '{self.name}' is not of type STRING. Actual type: {self.type}"
|
|
3492
3605
|
)
|
|
3493
|
-
|
|
3606
|
+
value = self.value
|
|
3607
|
+
if not isinstance(value, str):
|
|
3494
3608
|
raise TypeError(f"Value of attribute '{self!r}' is not a string.")
|
|
3495
|
-
return
|
|
3609
|
+
return value
|
|
3496
3610
|
|
|
3497
3611
|
def as_tensor(self) -> _protocols.TensorProtocol:
|
|
3498
3612
|
"""Get the attribute value as a tensor."""
|
|
@@ -3500,9 +3614,10 @@ class Attr(
|
|
|
3500
3614
|
raise TypeError(
|
|
3501
3615
|
f"Attribute '{self.name}' is not of type TENSOR. Actual type: {self.type}"
|
|
3502
3616
|
)
|
|
3503
|
-
|
|
3617
|
+
value = self.value
|
|
3618
|
+
if not isinstance(value, _protocols.TensorProtocol):
|
|
3504
3619
|
raise TypeError(f"Value of attribute '{self!r}' is not a tensor.")
|
|
3505
|
-
return
|
|
3620
|
+
return value
|
|
3506
3621
|
|
|
3507
3622
|
def as_graph(self) -> Graph:
|
|
3508
3623
|
"""Get the attribute value as a graph."""
|
|
@@ -3510,75 +3625,64 @@ class Attr(
|
|
|
3510
3625
|
raise TypeError(
|
|
3511
3626
|
f"Attribute '{self.name}' is not of type GRAPH. Actual type: {self.type}"
|
|
3512
3627
|
)
|
|
3513
|
-
|
|
3628
|
+
value = self.value
|
|
3629
|
+
if not isinstance(value, Graph):
|
|
3514
3630
|
raise TypeError(f"Value of attribute '{self!r}' is not a graph.")
|
|
3515
|
-
return
|
|
3631
|
+
return value
|
|
3516
3632
|
|
|
3517
|
-
def as_floats(self) ->
|
|
3633
|
+
def as_floats(self) -> tuple[float, ...]:
|
|
3518
3634
|
"""Get the attribute value as a sequence of floats."""
|
|
3519
3635
|
if self.type != _enums.AttributeType.FLOATS:
|
|
3520
3636
|
raise TypeError(
|
|
3521
3637
|
f"Attribute '{self.name}' is not of type FLOATS. Actual type: {self.type}"
|
|
3522
3638
|
)
|
|
3523
|
-
|
|
3524
|
-
|
|
3525
|
-
# Do not use isinstance check on elements because it may prevent np.int32 etc. from being used
|
|
3526
|
-
# Create a copy of the list to prevent mutation
|
|
3527
|
-
return [float(v) for v in self.value]
|
|
3639
|
+
# value is guaranteed to be a sequence of float in the constructor
|
|
3640
|
+
return self.value
|
|
3528
3641
|
|
|
3529
|
-
def as_ints(self) ->
|
|
3642
|
+
def as_ints(self) -> tuple[int, ...]:
|
|
3530
3643
|
"""Get the attribute value as a sequence of ints."""
|
|
3531
3644
|
if self.type != _enums.AttributeType.INTS:
|
|
3532
3645
|
raise TypeError(
|
|
3533
3646
|
f"Attribute '{self.name}' is not of type INTS. Actual type: {self.type}"
|
|
3534
3647
|
)
|
|
3535
|
-
|
|
3536
|
-
|
|
3537
|
-
# Do not use isinstance check on elements because it may prevent np.int32 etc. from being used
|
|
3538
|
-
# Create a copy of the list to prevent mutation
|
|
3539
|
-
return list(self.value)
|
|
3648
|
+
# value is guaranteed to be a sequence of int in the constructor
|
|
3649
|
+
return self.value
|
|
3540
3650
|
|
|
3541
|
-
def as_strings(self) ->
|
|
3651
|
+
def as_strings(self) -> tuple[str, ...]:
|
|
3542
3652
|
"""Get the attribute value as a sequence of strings."""
|
|
3543
3653
|
if self.type != _enums.AttributeType.STRINGS:
|
|
3544
3654
|
raise TypeError(
|
|
3545
3655
|
f"Attribute '{self.name}' is not of type STRINGS. Actual type: {self.type}"
|
|
3546
3656
|
)
|
|
3547
|
-
if not isinstance(self.value, Sequence):
|
|
3548
|
-
raise TypeError(f"Value of attribute '{self!r}' is not a Sequence.")
|
|
3549
3657
|
if onnx_ir.DEBUG:
|
|
3550
3658
|
if not all(isinstance(x, str) for x in self.value):
|
|
3551
3659
|
raise TypeError(f"Value of attribute '{self!r}' is not a Sequence of strings.")
|
|
3552
|
-
#
|
|
3553
|
-
return
|
|
3660
|
+
# value is guaranteed to be a sequence in the constructor
|
|
3661
|
+
return self.value
|
|
3554
3662
|
|
|
3555
|
-
def as_tensors(self) ->
|
|
3663
|
+
def as_tensors(self) -> tuple[_protocols.TensorProtocol, ...]:
|
|
3556
3664
|
"""Get the attribute value as a sequence of tensors."""
|
|
3557
3665
|
if self.type != _enums.AttributeType.TENSORS:
|
|
3558
3666
|
raise TypeError(
|
|
3559
3667
|
f"Attribute '{self.name}' is not of type TENSORS. Actual type: {self.type}"
|
|
3560
3668
|
)
|
|
3561
|
-
if not isinstance(self.value, Sequence):
|
|
3562
|
-
raise TypeError(f"Value of attribute '{self!r}' is not a Sequence.")
|
|
3563
3669
|
if onnx_ir.DEBUG:
|
|
3564
3670
|
if not all(isinstance(x, _protocols.TensorProtocol) for x in self.value):
|
|
3565
3671
|
raise TypeError(f"Value of attribute '{self!r}' is not a Sequence of tensors.")
|
|
3566
|
-
#
|
|
3567
|
-
return
|
|
3672
|
+
# value is guaranteed to be a sequence in the constructor
|
|
3673
|
+
return tuple(self.value)
|
|
3568
3674
|
|
|
3569
|
-
def as_graphs(self) ->
|
|
3675
|
+
def as_graphs(self) -> tuple[Graph, ...]:
|
|
3570
3676
|
"""Get the attribute value as a sequence of graphs."""
|
|
3571
3677
|
if self.type != _enums.AttributeType.GRAPHS:
|
|
3572
3678
|
raise TypeError(
|
|
3573
3679
|
f"Attribute '{self.name}' is not of type GRAPHS. Actual type: {self.type}"
|
|
3574
3680
|
)
|
|
3575
|
-
if not isinstance(self.value, Sequence):
|
|
3576
|
-
raise TypeError(f"Value of attribute '{self!r}' is not a Sequence.")
|
|
3577
3681
|
if onnx_ir.DEBUG:
|
|
3578
3682
|
if not all(isinstance(x, Graph) for x in self.value):
|
|
3579
3683
|
raise TypeError(f"Value of attribute '{self!r}' is not a Sequence of graphs.")
|
|
3580
|
-
#
|
|
3581
|
-
return
|
|
3684
|
+
# value is guaranteed to be a sequence in the constructor
|
|
3685
|
+
return tuple(self.value)
|
|
3582
3686
|
|
|
3583
3687
|
|
|
3584
3688
|
# NOTE: The following functions are just for convenience
|
|
@@ -3605,7 +3709,7 @@ def RefAttr(
|
|
|
3605
3709
|
return Attr(name, type, None, ref_attr_name=ref_attr_name, doc_string=doc_string)
|
|
3606
3710
|
|
|
3607
3711
|
|
|
3608
|
-
def AttrFloat32(name: str, value: float, doc_string: str | None = None) -> Attr:
|
|
3712
|
+
def AttrFloat32(name: str, value: float | np.floating, doc_string: str | None = None) -> Attr:
|
|
3609
3713
|
"""Create a float attribute."""
|
|
3610
3714
|
# NOTE: The function name is capitalized to maintain API backward compatibility.
|
|
3611
3715
|
return Attr(
|
|
@@ -3616,7 +3720,7 @@ def AttrFloat32(name: str, value: float, doc_string: str | None = None) -> Attr:
|
|
|
3616
3720
|
)
|
|
3617
3721
|
|
|
3618
3722
|
|
|
3619
|
-
def AttrInt64(name: str, value: int, doc_string: str | None = None) -> Attr:
|
|
3723
|
+
def AttrInt64(name: str, value: int | np.integer, doc_string: str | None = None) -> Attr:
|
|
3620
3724
|
"""Create an int attribute."""
|
|
3621
3725
|
# NOTE: The function name is capitalized to maintain API backward compatibility.
|
|
3622
3726
|
return Attr(
|
onnx_ir/_enums.py
CHANGED
|
@@ -357,7 +357,10 @@ class DataType(enum.IntEnum):
|
|
|
357
357
|
}
|
|
358
358
|
|
|
359
359
|
def is_string(self) -> bool:
|
|
360
|
-
"""Returns True if the data type is a string type.
|
|
360
|
+
"""Returns True if the data type is a string type.
|
|
361
|
+
|
|
362
|
+
.. versionadded:: 0.1.8
|
|
363
|
+
"""
|
|
361
364
|
return self == DataType.STRING
|
|
362
365
|
|
|
363
366
|
def __repr__(self) -> str:
|
|
@@ -419,15 +422,9 @@ _NP_TYPE_TO_DATA_TYPE = {
|
|
|
419
422
|
np.dtype(ml_dtypes.float8_e8m0fnu): DataType.FLOAT8E8M0,
|
|
420
423
|
np.dtype(ml_dtypes.int4): DataType.INT4,
|
|
421
424
|
np.dtype(ml_dtypes.uint4): DataType.UINT4,
|
|
425
|
+
np.dtype(ml_dtypes.float4_e2m1fn): DataType.FLOAT4E2M1,
|
|
422
426
|
}
|
|
423
427
|
|
|
424
|
-
# TODO(after min req for ml_dtypes>=0.5): Move this inside _NP_TYPE_TO_DATA_TYPE
|
|
425
|
-
_NP_TYPE_TO_DATA_TYPE.update(
|
|
426
|
-
{np.dtype(ml_dtypes.float4_e2m1fn): DataType.FLOAT4E2M1}
|
|
427
|
-
if hasattr(ml_dtypes, "float4_e2m1fn")
|
|
428
|
-
else {}
|
|
429
|
-
)
|
|
430
|
-
|
|
431
428
|
# ONNX DataType to Numpy dtype.
|
|
432
429
|
_DATA_TYPE_TO_NP_TYPE = {v: k for k, v in _NP_TYPE_TO_DATA_TYPE.items()}
|
|
433
430
|
|
|
@@ -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
|
onnx_ir/passes/common/naming.py
CHANGED
|
@@ -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
|
-
|
|
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
|
onnx_ir/serde.py
CHANGED
|
@@ -709,9 +709,8 @@ def _deserialize_graph(
|
|
|
709
709
|
annotation.tensor_name: annotation for annotation in proto.quantization_annotation
|
|
710
710
|
}
|
|
711
711
|
|
|
712
|
-
# Create values for
|
|
713
|
-
|
|
714
|
-
inputs = [_core.Input(info.name) for info in proto.input]
|
|
712
|
+
# Create values for inputs
|
|
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)
|
|
717
716
|
|
|
@@ -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
|
|
@@ -869,7 +872,7 @@ def deserialize_function(proto: onnx.FunctionProto) -> _core.Function:
|
|
|
869
872
|
Returns:
|
|
870
873
|
An IR Function object representing the ONNX function.
|
|
871
874
|
"""
|
|
872
|
-
inputs = [_core.
|
|
875
|
+
inputs = [_core.Value(name=name) for name in proto.input]
|
|
873
876
|
values: dict[str, _core.Value] = {v.name: v for v in inputs} # type: ignore[misc]
|
|
874
877
|
value_info = {info.name: info for info in getattr(proto, "value_info", [])}
|
|
875
878
|
|
|
@@ -1143,7 +1146,19 @@ def _deserialize_attribute(
|
|
|
1143
1146
|
if type_ == _enums.AttributeType.FLOAT:
|
|
1144
1147
|
return _core.AttrFloat32(name, proto.f, doc_string=doc_string)
|
|
1145
1148
|
if type_ == _enums.AttributeType.STRING:
|
|
1146
|
-
|
|
1149
|
+
try:
|
|
1150
|
+
return _core.AttrString(name, proto.s.decode("utf-8"), doc_string=doc_string)
|
|
1151
|
+
except UnicodeDecodeError:
|
|
1152
|
+
# Even though onnx.ai/onnx/repo-docs/IR.html#attributes requires the attribute
|
|
1153
|
+
# for strings to be utf-8 encoded bytes, custom ops may still store arbitrary data there
|
|
1154
|
+
logger.warning(
|
|
1155
|
+
"Attribute %r contains invalid UTF-8 bytes. ONNX spec requires string attributes "
|
|
1156
|
+
"to be UTF-8 encoded so the model is invalid. We will skip decoding the attribute and "
|
|
1157
|
+
"use the bytes as attribute value",
|
|
1158
|
+
name,
|
|
1159
|
+
)
|
|
1160
|
+
return _core.Attr(name, type_, proto.s, doc_string=doc_string)
|
|
1161
|
+
|
|
1147
1162
|
if type_ == _enums.AttributeType.INTS:
|
|
1148
1163
|
return _core.AttrInt64s(name, proto.ints, doc_string=doc_string)
|
|
1149
1164
|
if type_ == _enums.AttributeType.FLOATS:
|
|
@@ -1378,7 +1393,12 @@ def _should_create_value_info_for_value(value: _protocols.ValueProtocol) -> bool
|
|
|
1378
1393
|
True if value info should be created for the value.
|
|
1379
1394
|
"""
|
|
1380
1395
|
# No need to serialize value info if it is not set
|
|
1381
|
-
if
|
|
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
|
+
):
|
|
1382
1402
|
return False
|
|
1383
1403
|
if not value.name:
|
|
1384
1404
|
logger.debug("Did not serialize '%s' because its name is empty", value)
|
|
@@ -1784,16 +1804,26 @@ def _fill_in_value_for_attribute(
|
|
|
1784
1804
|
) -> None:
|
|
1785
1805
|
if type_ == _enums.AttributeType.INT:
|
|
1786
1806
|
# value: int
|
|
1787
|
-
|
|
1788
|
-
attribute_proto.i = int(value)
|
|
1807
|
+
attribute_proto.i = value
|
|
1789
1808
|
attribute_proto.type = onnx.AttributeProto.INT
|
|
1790
1809
|
elif type_ == _enums.AttributeType.FLOAT:
|
|
1791
1810
|
# value: float
|
|
1792
|
-
attribute_proto.f =
|
|
1811
|
+
attribute_proto.f = value
|
|
1793
1812
|
attribute_proto.type = onnx.AttributeProto.FLOAT
|
|
1794
1813
|
elif type_ == _enums.AttributeType.STRING:
|
|
1795
1814
|
# value: str
|
|
1796
|
-
|
|
1815
|
+
if type(value) is bytes:
|
|
1816
|
+
# Even though onnx.ai/onnx/repo-docs/IR.html#attributes requires the attribute
|
|
1817
|
+
# for strings to be utf-8 encoded bytes, custom ops may still store arbitrary data there
|
|
1818
|
+
logger.warning(
|
|
1819
|
+
"Value in attribute %r should be a string but is instead bytes. ONNX "
|
|
1820
|
+
"spec requires string attributes to be UTF-8 encoded so the model is invalid. "
|
|
1821
|
+
"We will skip encoding the attribute and use the bytes as attribute value",
|
|
1822
|
+
attribute_proto.name,
|
|
1823
|
+
)
|
|
1824
|
+
attribute_proto.s = value
|
|
1825
|
+
else:
|
|
1826
|
+
attribute_proto.s = value.encode("utf-8")
|
|
1797
1827
|
attribute_proto.type = onnx.AttributeProto.STRING
|
|
1798
1828
|
elif type_ == _enums.AttributeType.INTS:
|
|
1799
1829
|
# value: Sequence[int]
|
|
@@ -1945,11 +1975,26 @@ def serialize_type(type_protocol: _protocols.TypeProtocol) -> onnx.TypeProto:
|
|
|
1945
1975
|
@_capture_errors(lambda type_proto, from_: repr(from_))
|
|
1946
1976
|
def serialize_shape_into(type_proto: onnx.TypeProto, from_: _protocols.ShapeProtocol) -> None:
|
|
1947
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
|
|
1948
1986
|
tensor_type = getattr(type_proto, value_field)
|
|
1949
1987
|
while not isinstance(tensor_type.elem_type, int):
|
|
1950
1988
|
# Find the leaf type that has the shape field
|
|
1951
1989
|
type_proto = tensor_type.elem_type
|
|
1952
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
|
|
1953
1998
|
tensor_type = getattr(type_proto, value_field)
|
|
1954
1999
|
# When from is empty, we still need to set the shape field to an empty list by touching it
|
|
1955
2000
|
tensor_type.shape.ClearField("dim")
|
|
@@ -1970,5 +2015,8 @@ def serialize_dimension_into(
|
|
|
1970
2015
|
dim_proto.dim_value = dim
|
|
1971
2016
|
elif isinstance(dim, (_core.SymbolicDim, _protocols.SymbolicDimProtocol)):
|
|
1972
2017
|
if dim.value is not None:
|
|
1973
|
-
# TODO(justinchuby): None is probably not a valid value for dim_param
|
|
1974
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.
|
|
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
|
|
@@ -19,7 +19,7 @@ License-File: LICENSE
|
|
|
19
19
|
Requires-Dist: numpy
|
|
20
20
|
Requires-Dist: onnx>=1.16
|
|
21
21
|
Requires-Dist: typing_extensions>=4.10
|
|
22
|
-
Requires-Dist: ml_dtypes
|
|
22
|
+
Requires-Dist: ml_dtypes>=0.5.0
|
|
23
23
|
Dynamic: license-file
|
|
24
24
|
|
|
25
25
|
# <img src="docs/_static/logo-light.png" alt="ONNX IR" width="250"/>
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
onnx_ir/__init__.py,sha256=
|
|
2
|
-
onnx_ir/_core.py,sha256=
|
|
1
|
+
onnx_ir/__init__.py,sha256=N-6BRNeRjjU17-iaezMOq1ErVq8irJltkubTpAbZ2BY,3441
|
|
2
|
+
onnx_ir/_core.py,sha256=9AnsXuoiFzypp9U_al7yU46OU0iqrGq0rJzLw4FHmcI,143517
|
|
3
3
|
onnx_ir/_display.py,sha256=230bMN_hVy47Ug3HkA4o5Tf5Hr21AnBEoq5w0fxjyTs,1300
|
|
4
|
-
onnx_ir/_enums.py,sha256=
|
|
4
|
+
onnx_ir/_enums.py,sha256=E7WQ7yQzulBeimamc9q_k4fEUoyH_2PWtaOMpwck_W0,13915
|
|
5
5
|
onnx_ir/_graph_comparison.py,sha256=8_D1gu547eCDotEUqxfIJhUGU_Ufhfji7sfsSraOj3g,727
|
|
6
6
|
onnx_ir/_graph_containers.py,sha256=PRKrshRZ5rzWCgRs1TefzJq9n8wyo7OqeKy3XxMhyys,14265
|
|
7
7
|
onnx_ir/_io.py,sha256=GWwA4XOZ-ZX1cgibgaYD0K0O5d9LX21ZwcBN02Wrh04,5205
|
|
@@ -16,13 +16,13 @@ onnx_ir/_version_utils.py,sha256=bZThuE7meVHFOY1DLsmss9WshVIp9iig7udGfDbVaK4,133
|
|
|
16
16
|
onnx_ir/convenience.py,sha256=0B1epuXZCSmY4FbW2vaYfR-t5ubxBZ1UruiytHs-zFw,917
|
|
17
17
|
onnx_ir/external_data.py,sha256=rXHtRU-9tjAt10Iervhr5lsI6Dtv-EhR7J4brxppImA,18079
|
|
18
18
|
onnx_ir/py.typed,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
|
19
|
-
onnx_ir/serde.py,sha256=
|
|
19
|
+
onnx_ir/serde.py,sha256=S0zCZnfePs1UV927HDEr3VnXuue_B5PD1dVPqwuwrak,80636
|
|
20
20
|
onnx_ir/tape.py,sha256=4FyfAHmVhQoMsfHMYnBwP2azi6UF6b6pj--ercObqZs,350
|
|
21
21
|
onnx_ir/tensor_adapters.py,sha256=YffUeZDZi8thxm-4nF2cL6cNSJSVmLm4A3IbEzwY8QQ,7233
|
|
22
22
|
onnx_ir/testing.py,sha256=WTrjf2joWizDWaYMJlV1KjZMQw7YmZ8NvuBTVn1uY6s,8803
|
|
23
23
|
onnx_ir/traversal.py,sha256=Wy4XphwuapAvm94-5iaz6G8LjIoMFpY7qfPfXzYViEE,4488
|
|
24
|
-
onnx_ir/_convenience/__init__.py,sha256=
|
|
25
|
-
onnx_ir/_convenience/_constructors.py,sha256=
|
|
24
|
+
onnx_ir/_convenience/__init__.py,sha256=SO7kc8RXVKEUODGh0q2Y7WgmbUsOjYSixmKFx_A0DAQ,19752
|
|
25
|
+
onnx_ir/_convenience/_constructors.py,sha256=HqCGtNPMzFFEerC7I5VEyMdBuIdOJDucn9UEdwuymcg,11519
|
|
26
26
|
onnx_ir/_thirdparty/asciichartpy.py,sha256=afQ0fsqko2uYRPAR4TZBrQxvCb4eN8lxZ2yDFbVQq_s,10533
|
|
27
27
|
onnx_ir/passes/__init__.py,sha256=M_Tcl_-qGSNPluFIvOoeDyh0qAwNayaYyXDS5UJUJPQ,764
|
|
28
28
|
onnx_ir/passes/_pass_infra.py,sha256=xIOw_zZIuOqD4Z_wZ4OvsqXfh2IZMoMlDp1xQ_MPQlc,9567
|
|
@@ -30,17 +30,17 @@ onnx_ir/passes/common/__init__.py,sha256=NYBrXvkq_CbWRwcZptSsF4u_-1zfN_BClLhVQY0
|
|
|
30
30
|
onnx_ir/passes/common/_c_api_utils.py,sha256=g6riA6xNGVWaO5YjVHZ0krrfslWHmRlryRkwB8X56cg,2907
|
|
31
31
|
onnx_ir/passes/common/clear_metadata_and_docstring.py,sha256=YwouLfsNFSaTuGd7uMOGjdvVwG9yHQTkSphUgDlM0ME,2365
|
|
32
32
|
onnx_ir/passes/common/common_subexpression_elimination.py,sha256=wZ1zEPdCshYB_ifP9fCAVfzQkesE6uhCfzCuL2qO5fA,7948
|
|
33
|
-
onnx_ir/passes/common/constant_manipulation.py,sha256=
|
|
33
|
+
onnx_ir/passes/common/constant_manipulation.py,sha256=Ja_2uO59ni8YX600iF3wvCmOk4EvM5crl7csYU1s7rQ,9391
|
|
34
34
|
onnx_ir/passes/common/identity_elimination.py,sha256=wN8g8uPGn6IIQ6Jf1lo6nGTXvpWyiSQtT_CfmtvZpwA,3664
|
|
35
35
|
onnx_ir/passes/common/initializer_deduplication.py,sha256=gKrXTMFAtCkMmiIm8zWzwPnwSbRdZxunJeAt_jFU-vY,7253
|
|
36
36
|
onnx_ir/passes/common/inliner.py,sha256=wBoO6yXt6F1AObQjYZHMQ0wn3YH681N4HQQVyaMAYd4,13702
|
|
37
|
-
onnx_ir/passes/common/naming.py,sha256=
|
|
37
|
+
onnx_ir/passes/common/naming.py,sha256=l_LrUiI3gAoSEVs8YeQ5kRNWp7aMOlBK-SfFUsKobZI,10687
|
|
38
38
|
onnx_ir/passes/common/onnx_checker.py,sha256=_sPmJ2ff9pDB1g9q7082BL6fyubomRaj6svE0cCyDew,1691
|
|
39
39
|
onnx_ir/passes/common/shape_inference.py,sha256=LVdvxjeKtcIEbPcb6mKisxoPJOOawzsm3tzk5j9xqeM,3992
|
|
40
40
|
onnx_ir/passes/common/topological_sort.py,sha256=Vcu1YhBdfRX4LROr0NScjB1Pwz2DjBFD0Z_GxqaxPF8,999
|
|
41
41
|
onnx_ir/passes/common/unused_removal.py,sha256=cBNqaqGnUVyCWxsD7hBzYk4qSglVPo3SmHAvkUo5-Oc,7613
|
|
42
|
-
onnx_ir-0.1.
|
|
43
|
-
onnx_ir-0.1.
|
|
44
|
-
onnx_ir-0.1.
|
|
45
|
-
onnx_ir-0.1.
|
|
46
|
-
onnx_ir-0.1.
|
|
42
|
+
onnx_ir-0.1.10.dist-info/licenses/LICENSE,sha256=z8d0m5b2O9McPEK1xHG_dWgUBT6EfBDz6wA0F7xSPTA,11358
|
|
43
|
+
onnx_ir-0.1.10.dist-info/METADATA,sha256=3ou4NcDwiEwn172tRdD57Tb7y7rCGUyfhFDqan7qM3s,3605
|
|
44
|
+
onnx_ir-0.1.10.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
45
|
+
onnx_ir-0.1.10.dist-info/top_level.txt,sha256=W5tROO93YjO0XRxIdjMy4wocp-5st5GiI2ukvW7UhDo,8
|
|
46
|
+
onnx_ir-0.1.10.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|