From b50403348926c53eba3e5d9fd68c07dee4c3ed74 Mon Sep 17 00:00:00 2001 From: Justin Chu Date: Tue, 29 Apr 2025 17:49:17 -0700 Subject: [PATCH 01/16] Display constant tensors for Value Display constant values and simplify the value repr string when fields are empty --- onnxscript/ir/_core.py | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/onnxscript/ir/_core.py b/onnxscript/ir/_core.py index 32073c5b91..69c52e18d0 100644 --- a/onnxscript/ir/_core.py +++ b/onnxscript/ir/_core.py @@ -1836,14 +1836,22 @@ def __init__( def __repr__(self) -> str: value_name = self.name if self.name else "anonymous:" + str(id(self)) + + type_text = f", type={self.type!r}" if self.type is not None else "" + shape_text = f", shape={self.shape!r}" if self.shape is not None else "" producer = self.producer() if producer is None: - producer_text = "None" + producer_text = "" elif producer.name is not None: - producer_text = producer.name + producer_text = f", producer='{producer.name}'" + else: + producer_text = f", producer=anonymous_node:{id(producer)}" + index_text = f", index={self.index()}" if self.index() is not None else "" + if self.const_value is not None: + const_value_text = f", const_value={self.const_value!r}" else: - producer_text = f"anonymous_node:{id(producer)}" - return f"{self.__class__.__name__}({value_name!r}, type={self.type!r}, shape={self.shape}, producer={producer_text}, index={self.index()})" + const_value_text = "" + return f"{self.__class__.__name__}(name={value_name!r}{type_text}{shape_text}{producer_text}{index_text}{const_value_text})" def __str__(self) -> str: value_name = self.name if self.name is not None else "anonymous:" + str(id(self)) From e5d59d8e43931ff2585641c5b645de85f8e45c21 Mon Sep 17 00:00:00 2001 From: Justin Chu Date: Tue, 29 Apr 2025 17:50:01 -0700 Subject: [PATCH 02/16] str --- onnxscript/ir/_core.py | 1 - 1 file changed, 1 deletion(-) diff --git a/onnxscript/ir/_core.py b/onnxscript/ir/_core.py index 69c52e18d0..895e13516b 100644 --- a/onnxscript/ir/_core.py +++ b/onnxscript/ir/_core.py @@ -1836,7 +1836,6 @@ def __init__( def __repr__(self) -> str: value_name = self.name if self.name else "anonymous:" + str(id(self)) - type_text = f", type={self.type!r}" if self.type is not None else "" shape_text = f", shape={self.shape!r}" if self.shape is not None else "" producer = self.producer() From b6c28df646b8b1a1d80211cdc1fc17560304e326 Mon Sep 17 00:00:00 2001 From: Justin Chu Date: Tue, 29 Apr 2025 18:01:12 -0700 Subject: [PATCH 03/16] Update str --- onnxscript/ir/_core.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/onnxscript/ir/_core.py b/onnxscript/ir/_core.py index 895e13516b..c2234c29cd 100644 --- a/onnxscript/ir/_core.py +++ b/onnxscript/ir/_core.py @@ -1856,10 +1856,14 @@ def __str__(self) -> str: value_name = self.name if self.name is not None else "anonymous:" + str(id(self)) shape_text = str(self.shape) if self.shape is not None else "?" type_text = str(self.type) if self.type is not None else "?" + if self.const_value is not None and self.const_value.size < 10: + const_value_text = f"{{{self.const_value}}}" + else: + const_value_text = "" # Quote the name because in reality the names can have invalid characters # that make them hard to read - return f"%{_quoted(value_name)}<{type_text},{shape_text}>" + return f"%{_quoted(value_name)}<{type_text},{shape_text}>{const_value_text}" def producer(self) -> Node | None: """The node that produces this value. From 144271ccbf1490b00dbff8885b16f13c458d88a2 Mon Sep 17 00:00:00 2001 From: Justin Chu Date: Tue, 29 Apr 2025 18:19:18 -0700 Subject: [PATCH 04/16] const_value_text --- onnxscript/ir/_core.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/onnxscript/ir/_core.py b/onnxscript/ir/_core.py index c2234c29cd..db2dc41df3 100644 --- a/onnxscript/ir/_core.py +++ b/onnxscript/ir/_core.py @@ -1847,7 +1847,11 @@ def __repr__(self) -> str: producer_text = f", producer=anonymous_node:{id(producer)}" index_text = f", index={self.index()}" if self.index() is not None else "" if self.const_value is not None: - const_value_text = f", const_value={self.const_value!r}" + # The the first line only + tensor_text = repr(self.const_value).replace('\n', ' ') + if len(tensor_text) > 100: + tensor_text = tensor_text[:100] + "...)" + const_value_text = f", const_value={tensor_text}" else: const_value_text = "" return f"{self.__class__.__name__}(name={value_name!r}{type_text}{shape_text}{producer_text}{index_text}{const_value_text})" @@ -1856,8 +1860,8 @@ def __str__(self) -> str: value_name = self.name if self.name is not None else "anonymous:" + str(id(self)) shape_text = str(self.shape) if self.shape is not None else "?" type_text = str(self.type) if self.type is not None else "?" - if self.const_value is not None and self.const_value.size < 10: - const_value_text = f"{{{self.const_value}}}" + if self.const_value is not None and self.const_value.size <= 10: + const_value_text = f"{{{self.const_value}}}".replace('\n', ' ') else: const_value_text = "" From 99cbf98e87a16bf6929b7b08087e76be39874ae2 Mon Sep 17 00:00:00 2001 From: Justin Chu Date: Tue, 29 Apr 2025 18:19:29 -0700 Subject: [PATCH 05/16] const_value_text --- onnxscript/ir/_core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/onnxscript/ir/_core.py b/onnxscript/ir/_core.py index db2dc41df3..0d0d9290f4 100644 --- a/onnxscript/ir/_core.py +++ b/onnxscript/ir/_core.py @@ -1848,7 +1848,7 @@ def __repr__(self) -> str: index_text = f", index={self.index()}" if self.index() is not None else "" if self.const_value is not None: # The the first line only - tensor_text = repr(self.const_value).replace('\n', ' ') + tensor_text = repr(self.const_value).replace("\n", " ") if len(tensor_text) > 100: tensor_text = tensor_text[:100] + "...)" const_value_text = f", const_value={tensor_text}" @@ -1861,7 +1861,7 @@ def __str__(self) -> str: shape_text = str(self.shape) if self.shape is not None else "?" type_text = str(self.type) if self.type is not None else "?" if self.const_value is not None and self.const_value.size <= 10: - const_value_text = f"{{{self.const_value}}}".replace('\n', ' ') + const_value_text = f"{{{self.const_value}}}".replace("\n", " ") else: const_value_text = "" From e30df97ac9a8443766e1dbed9a81b69470b173fb Mon Sep 17 00:00:00 2001 From: Justin Chu Date: Tue, 29 Apr 2025 18:20:27 -0700 Subject: [PATCH 06/16] ... --- onnxscript/ir/_core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onnxscript/ir/_core.py b/onnxscript/ir/_core.py index 0d0d9290f4..9b48562ca3 100644 --- a/onnxscript/ir/_core.py +++ b/onnxscript/ir/_core.py @@ -1863,7 +1863,7 @@ def __str__(self) -> str: if self.const_value is not None and self.const_value.size <= 10: const_value_text = f"{{{self.const_value}}}".replace("\n", " ") else: - const_value_text = "" + const_value_text = "{...}" # Quote the name because in reality the names can have invalid characters # that make them hard to read From c475f5cc4823a06867eb97a75ca0d910736b2b88 Mon Sep 17 00:00:00 2001 From: Justin Chu Date: Tue, 29 Apr 2025 18:22:09 -0700 Subject: [PATCH 07/16] take --- onnxscript/ir/_core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onnxscript/ir/_core.py b/onnxscript/ir/_core.py index 9b48562ca3..908a2858a5 100644 --- a/onnxscript/ir/_core.py +++ b/onnxscript/ir/_core.py @@ -1847,7 +1847,7 @@ def __repr__(self) -> str: producer_text = f", producer=anonymous_node:{id(producer)}" index_text = f", index={self.index()}" if self.index() is not None else "" if self.const_value is not None: - # The the first line only + # Take the first line only tensor_text = repr(self.const_value).replace("\n", " ") if len(tensor_text) > 100: tensor_text = tensor_text[:100] + "...)" From d59cad0ae4e940d15aea751bd8d18f9eb608b99f Mon Sep 17 00:00:00 2001 From: Justin Chu Date: Tue, 29 Apr 2025 22:20:18 -0700 Subject: [PATCH 08/16] Fix const_value_text --- onnxscript/ir/_core.py | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/onnxscript/ir/_core.py b/onnxscript/ir/_core.py index 908a2858a5..36d99f6df5 100644 --- a/onnxscript/ir/_core.py +++ b/onnxscript/ir/_core.py @@ -406,7 +406,9 @@ def __dlpack_device__(self) -> tuple[int, int]: return self.__array__().__dlpack_device__() def __repr__(self) -> str: - return f"{self._repr_base()}({self._raw!r}, name={self.name!r})" + tensor_lines = str(self._raw).split("\n") + tensor_text = " ".join(line.strip() for line in tensor_lines) + return f"{self._repr_base()}({tensor_text}, name={self.name!r})" @property def dtype(self) -> _enums.DataType: @@ -1848,7 +1850,7 @@ def __repr__(self) -> str: index_text = f", index={self.index()}" if self.index() is not None else "" if self.const_value is not None: # Take the first line only - tensor_text = repr(self.const_value).replace("\n", " ") + tensor_text = repr(self.const_value) if len(tensor_text) > 100: tensor_text = tensor_text[:100] + "...)" const_value_text = f", const_value={tensor_text}" @@ -1860,10 +1862,14 @@ def __str__(self) -> str: value_name = self.name if self.name is not None else "anonymous:" + str(id(self)) shape_text = str(self.shape) if self.shape is not None else "?" type_text = str(self.type) if self.type is not None else "?" - if self.const_value is not None and self.const_value.size <= 10: - const_value_text = f"{{{self.const_value}}}".replace("\n", " ") + if self.const_value is not None: + # Only display when the const value is small + if self.const_value.size <= 10: + const_value_text = f"{{{self.const_value}}}" + else: + const_value_text = "{...}" else: - const_value_text = "{...}" + const_value_text = "" # Quote the name because in reality the names can have invalid characters # that make them hard to read From 111d2bc31630d0a652b9ca3250764c2fb013b0f6 Mon Sep 17 00:00:00 2001 From: Justin Chu Date: Tue, 29 Apr 2025 22:30:43 -0700 Subject: [PATCH 09/16] Handle multiline --- onnxscript/ir/_core.py | 2 +- onnxscript/ir/serde.py | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/onnxscript/ir/_core.py b/onnxscript/ir/_core.py index 36d99f6df5..18edc17d43 100644 --- a/onnxscript/ir/_core.py +++ b/onnxscript/ir/_core.py @@ -406,7 +406,7 @@ def __dlpack_device__(self) -> tuple[int, int]: return self.__array__().__dlpack_device__() def __repr__(self) -> str: - tensor_lines = str(self._raw).split("\n") + tensor_lines = repr(self._raw).split("\n") tensor_text = " ".join(line.strip() for line in tensor_lines) return f"{self._repr_base()}({tensor_text}, name={self.name!r})" diff --git a/onnxscript/ir/serde.py b/onnxscript/ir/serde.py index 64703b2baa..98c06bcad2 100644 --- a/onnxscript/ir/serde.py +++ b/onnxscript/ir/serde.py @@ -278,9 +278,10 @@ def raw(self) -> onnx.TensorProto: return self._proto def __repr__(self) -> str: - # It is a little hard to display the content when there can be types - # unsupported by numpy - # Preferably we should display some content when the tensor is small + if self.size <= 10: + tensor_lines = repr(self.numpy()).split("\n") + tensor_text = " ".join(line.strip() for line in tensor_lines) + return f"{self._repr_base()}({tensor_text}, name={self.name!r})" return f"{self._repr_base()}(name={self.name!r})" def __array__(self, dtype: Any = None) -> np.ndarray: From cb95beb05645c5ad73620ce6f9794a3ba453a33f Mon Sep 17 00:00:00 2001 From: Justin Chu Date: Tue, 29 Apr 2025 22:36:00 -0700 Subject: [PATCH 10/16] repr --- onnxscript/ir/_core.py | 1 + 1 file changed, 1 insertion(+) diff --git a/onnxscript/ir/_core.py b/onnxscript/ir/_core.py index 18edc17d43..6add0b2a42 100644 --- a/onnxscript/ir/_core.py +++ b/onnxscript/ir/_core.py @@ -406,6 +406,7 @@ def __dlpack_device__(self) -> tuple[int, int]: return self.__array__().__dlpack_device__() def __repr__(self) -> str: + # Avoid multi-line repr tensor_lines = repr(self._raw).split("\n") tensor_text = " ".join(line.strip() for line in tensor_lines) return f"{self._repr_base()}({tensor_text}, name={self.name!r})" From 0e2f09bc93ee087744f058c3e5f924a79c8bfc4e Mon Sep 17 00:00:00 2001 From: Justin Chu Date: Wed, 30 Apr 2025 06:42:50 -0700 Subject: [PATCH 11/16] tensorproto display --- onnxscript/ir/_convenience/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onnxscript/ir/_convenience/__init__.py b/onnxscript/ir/_convenience/__init__.py index 0addc9da2f..e975ae2234 100644 --- a/onnxscript/ir/_convenience/__init__.py +++ b/onnxscript/ir/_convenience/__init__.py @@ -190,7 +190,7 @@ def convert_attributes( ... "type_protos": [ir.TensorType(ir.DataType.FLOAT), ir.TensorType(ir.DataType.FLOAT)], ... } >>> convert_attributes(attrs) - [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(array([1., 2., 3.]), name=None)), Attr('tensor_proto', TENSOR, TensorProtoTensor(name='proto')), Attr('graph', INTS, Graph( + [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(array([1., 2., 3.]), name=None)), TensorProtoTensor(array([1., 2., 3.], dtype=float32), name='proto')), Attr('graph', INTS, Graph( name='graph0', inputs=( From 6e8a79f5d9a845069e86b26d3200231bdb309081 Mon Sep 17 00:00:00 2001 From: Justin Chu Date: Wed, 30 Apr 2025 06:52:35 -0700 Subject: [PATCH 12/16] fix --- onnxscript/ir/_convenience/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/onnxscript/ir/_convenience/__init__.py b/onnxscript/ir/_convenience/__init__.py index b3aab0d822..47043d4687 100644 --- a/onnxscript/ir/_convenience/__init__.py +++ b/onnxscript/ir/_convenience/__init__.py @@ -212,7 +212,7 @@ def convert_attributes( ... "type_protos": [ir.TensorType(ir.DataType.FLOAT), ir.TensorType(ir.DataType.FLOAT)], ... } >>> convert_attributes(attrs) - [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(array([1., 2., 3.]), name=None)), TensorProtoTensor(array([1., 2., 3.], dtype=float32), name='proto')), Attr('graph', INTS, Graph( + [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(array([1., 2., 3.]), name=None)), Attr('tensor_proto', TENSOR, TensorProtoTensor(array([1., 2., 3.], dtype=float32), name='proto')), Attr('graph', INTS, Graph( name='graph0', inputs=( From 2d7e7c74772c4e29066f4d4304d2ddb126701b46 Mon Sep 17 00:00:00 2001 From: Justin Chu Date: Wed, 30 Apr 2025 10:43:32 -0700 Subject: [PATCH 13/16] tensor_text --- onnxscript/ir/_core.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/onnxscript/ir/_core.py b/onnxscript/ir/_core.py index 6add0b2a42..606cee2ecd 100644 --- a/onnxscript/ir/_core.py +++ b/onnxscript/ir/_core.py @@ -1850,10 +1850,11 @@ def __repr__(self) -> str: producer_text = f", producer=anonymous_node:{id(producer)}" index_text = f", index={self.index()}" if self.index() is not None else "" if self.const_value is not None: - # Take the first line only - tensor_text = repr(self.const_value) - if len(tensor_text) > 100: - tensor_text = tensor_text[:100] + "...)" + # Only display when the const value is small + if self.const_value.size <= 10: + tensor_text = f"{{{self.const_value}}}" + else: + tensor_text = "{...}" const_value_text = f", const_value={tensor_text}" else: const_value_text = "" From b69f3704c03100ad1214bc09015b5d1a5306cae3 Mon Sep 17 00:00:00 2001 From: Justin Chu Date: Wed, 30 Apr 2025 10:47:15 -0700 Subject: [PATCH 14/16] classname --- onnxscript/ir/_core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/onnxscript/ir/_core.py b/onnxscript/ir/_core.py index 606cee2ecd..34b3390f1c 100644 --- a/onnxscript/ir/_core.py +++ b/onnxscript/ir/_core.py @@ -1854,7 +1854,7 @@ def __repr__(self) -> str: if self.const_value.size <= 10: tensor_text = f"{{{self.const_value}}}" else: - tensor_text = "{...}" + tensor_text = f"{{{self.const_value.__class__.__name__}...}}" const_value_text = f", const_value={tensor_text}" else: const_value_text = "" @@ -1869,7 +1869,7 @@ def __str__(self) -> str: if self.const_value.size <= 10: const_value_text = f"{{{self.const_value}}}" else: - const_value_text = "{...}" + const_value_text = f"{{{self.const_value.__class__.__name__}...}}" else: const_value_text = "" From 6effccbce39ead27fbd54f3eb729e9b189164673 Mon Sep 17 00:00:00 2001 From: Justin Chu Date: Wed, 30 Apr 2025 10:50:11 -0700 Subject: [PATCH 15/16] ... --- onnxscript/ir/_core.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/onnxscript/ir/_core.py b/onnxscript/ir/_core.py index 34b3390f1c..3de48df677 100644 --- a/onnxscript/ir/_core.py +++ b/onnxscript/ir/_core.py @@ -1854,7 +1854,7 @@ def __repr__(self) -> str: if self.const_value.size <= 10: tensor_text = f"{{{self.const_value}}}" else: - tensor_text = f"{{{self.const_value.__class__.__name__}...}}" + tensor_text = f"{{{self.const_value.__class__.__name__}(...)}}" const_value_text = f", const_value={tensor_text}" else: const_value_text = "" @@ -1869,7 +1869,7 @@ def __str__(self) -> str: if self.const_value.size <= 10: const_value_text = f"{{{self.const_value}}}" else: - const_value_text = f"{{{self.const_value.__class__.__name__}...}}" + const_value_text = f"{{{self.const_value.__class__.__name__}(...)}}" else: const_value_text = "" From 1c6b77839299dca88a8ce232baae680d16eb768d Mon Sep 17 00:00:00 2001 From: Justin Chu Date: Wed, 30 Apr 2025 11:36:22 -0700 Subject: [PATCH 16/16] Show it on nodes --- onnxscript/ir/_core.py | 34 ++++++++++++++++------------------ 1 file changed, 16 insertions(+), 18 deletions(-) diff --git a/onnxscript/ir/_core.py b/onnxscript/ir/_core.py index 3de48df677..a99fd3de9a 100644 --- a/onnxscript/ir/_core.py +++ b/onnxscript/ir/_core.py @@ -1468,7 +1468,7 @@ def __str__(self) -> str: + ", ".join( [ ( - f"%{_quoted(x.name) if x.name else 'anonymous:' + str(id(x))}" + f"%{_quoted(x.name) if x.name else 'anonymous:' + str(id(x))}{x._constant_tensor_part()}" if x is not None else "None" ) @@ -1849,33 +1849,31 @@ def __repr__(self) -> str: else: producer_text = f", producer=anonymous_node:{id(producer)}" index_text = f", index={self.index()}" if self.index() is not None else "" - if self.const_value is not None: - # Only display when the const value is small - if self.const_value.size <= 10: - tensor_text = f"{{{self.const_value}}}" - else: - tensor_text = f"{{{self.const_value.__class__.__name__}(...)}}" - const_value_text = f", const_value={tensor_text}" - else: - const_value_text = "" + const_value_text = self._constant_tensor_part() + if const_value_text: + const_value_text = f", const_value={const_value_text}" return f"{self.__class__.__name__}(name={value_name!r}{type_text}{shape_text}{producer_text}{index_text}{const_value_text})" def __str__(self) -> str: value_name = self.name if self.name is not None else "anonymous:" + str(id(self)) shape_text = str(self.shape) if self.shape is not None else "?" type_text = str(self.type) if self.type is not None else "?" + + # Quote the name because in reality the names can have invalid characters + # that make them hard to read + return ( + f"%{_quoted(value_name)}<{type_text},{shape_text}>{self._constant_tensor_part()}" + ) + + def _constant_tensor_part(self) -> str: + """Display string for the constant tensor attached to str of Value.""" if self.const_value is not None: # Only display when the const value is small if self.const_value.size <= 10: - const_value_text = f"{{{self.const_value}}}" + return f"{{{self.const_value}}}" else: - const_value_text = f"{{{self.const_value.__class__.__name__}(...)}}" - else: - const_value_text = "" - - # Quote the name because in reality the names can have invalid characters - # that make them hard to read - return f"%{_quoted(value_name)}<{type_text},{shape_text}>{const_value_text}" + return f"{{{self.const_value.__class__.__name__}(...)}}" + return "" def producer(self) -> Node | None: """The node that produces this value.