tico 0.1.0.dev250622__py3-none-any.whl → 0.1.0.dev250624__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.
tico/__init__.py CHANGED
@@ -21,7 +21,7 @@ from tico.config import CompileConfigV1, get_default_config
21
21
  from tico.utils.convert import convert, convert_from_exported_program, convert_from_pt2
22
22
 
23
23
  # THIS LINE IS AUTOMATICALLY GENERATED BY setup.py
24
- __version__ = "0.1.0.dev250622"
24
+ __version__ = "0.1.0.dev250624"
25
25
 
26
26
  MINIMUM_SUPPORTED_VERSION = "2.5.0"
27
27
  SECURE_TORCH_VERSION = "2.6.0"
@@ -21,9 +21,8 @@ import copy
21
21
  import torch
22
22
  from torch.export import ExportedProgram
23
23
 
24
- from tico.serialize.quant_param import QPARAM_KEY, QuantParam, to_qparam_dtype
24
+ from tico.serialize.quant_param import QPARAM_KEY, QuantParam
25
25
  from tico.utils import logging
26
- from tico.utils.graph import create_node
27
26
  from tico.utils.passes import PassBase, PassResult
28
27
  from tico.utils.trace_decorators import trace_graph_diff_on_pass
29
28
  from tico.utils.utils import get_quant_dtype
@@ -42,11 +41,33 @@ class FoldQuantOps(PassBase):
42
41
  To export quantized circle, this pass removes (Q - DQ) nodes and saves those quantization info
43
42
  to previous op's metadata.
44
43
 
45
- [BEFORE]
46
- op (float) - Quantize - Dequantize - (float)
47
-
48
- [AFTER]
49
- op (float with meta[QPARAM_KEY])
44
+ ────────────────────────────────────────────────────────────────
45
+ BEFORE AFTER
46
+ ────────────────────────────────────────────────────────────────
47
+ op(float) ─ Q ─ DQ ─ … op(float, meta[QPARAM])
48
+
49
+ op ─ Q1 ─ DQ1 ─ Q2 ─ DQ2 op(meta[QPARAM]) ─ Q2
50
+ ▲ ▲
51
+ │ (Q1, DQ1 folded) │ (re-quantization kept)
52
+
53
+ op ─ Q ─┬─ DQ0 op(meta[QPARAM])
54
+ ├─ DQ1 (each DQ* folded, Q dropped when orphaned)
55
+ └─ DQ2
56
+ ────────────────────────────────────────────────────────────────
57
+
58
+ Algorithm
59
+ ---------
60
+ 1. Iterate over *all* Dequantize nodes.
61
+ 2. For each DQ, verify it is driven by a Quantize node `q` and that
62
+ `q` and `dq` share identical (scale, zero-point, dtype).
63
+ 3. a) If the producer op has **no** QPARAM, attach one, then replace
64
+ *this* DQ's usages with the producer op.
65
+ b) If the producer is already quantized with a different dtype,
66
+ this is a *re-quantization*: attach QPARAM to `q` and keep it,
67
+ but still remove the DQ.
68
+ 4. After all replacements, run `graph.eliminate_dead_code()`.
69
+ Any Quantize that became orphaned because *all* its DQs were folded
70
+ is deleted automatically.
50
71
  """
51
72
 
52
73
  def __init__(self):
@@ -81,15 +102,9 @@ class FoldQuantOps(PassBase):
81
102
  if q_args.dtype != dq_args.dtype:
82
103
  continue
83
104
 
84
- # Case 1. op is not quantized
85
- # - Quantize op
86
- # Case 2. op is quantized
87
- # 2.1. op_dtype == qdq_dtype
88
- # - Just skip (NOTE Need requantization?)
89
- # 2.2. op_dtype != qdq_dtype
90
- # - Insert Quantize operator
91
-
92
- # Case 1
105
+ # ───────────────────────────────────────────
106
+ # Case 1: op not yet quantized
107
+ # ───────────────────────────────────────────
93
108
  if QPARAM_KEY not in op.meta:
94
109
  qparam = QuantParam()
95
110
  qparam.scale = [q_args.scale]
@@ -100,21 +115,36 @@ class FoldQuantOps(PassBase):
100
115
  dq.replace_all_uses_with(op, propagate_meta=False)
101
116
 
102
117
  logger.debug(f"{q.name} and {dq.name} are folded to {op.name}.")
118
+ # ───────────────────────────────────────────
119
+ # Case 2: op already quantized
120
+ # 2.1 same dtype → nothing to do
121
+ # 2.2 diff dtype → leave Q in place
122
+ # ───────────────────────────────────────────
103
123
  else:
104
124
  op_qparam: QuantParam = op.meta[QPARAM_KEY]
105
125
  qdq_dtype = get_quant_dtype(q_args.quant_min, q_args.quant_max)
106
- # Case 2.2
126
+
107
127
  if op_qparam.dtype != qdq_dtype:
108
- # If op is already quantized with a dtype different from qdq, leave quantize
109
- qparam = QuantParam()
110
- qparam.scale = [q_args.scale]
111
- qparam.zero_point = [q_args.zero_p]
112
- qparam.dtype = qdq_dtype
113
- q.meta[QPARAM_KEY] = qparam
114
- assert len(q.users) == 1, "Fix me unless"
128
+ # Attach QPARAM to Q once
129
+ if QPARAM_KEY not in q.meta:
130
+ qparam = QuantParam()
131
+ qparam.scale = [q_args.scale]
132
+ qparam.zero_point = [q_args.zero_p]
133
+ qparam.dtype = qdq_dtype
134
+ q.meta[QPARAM_KEY] = qparam
135
+ assert len(q.users) == 1, "Fix me unless"
115
136
 
116
137
  dq.replace_all_uses_with(q, propagate_meta=False)
117
138
  logger.debug(f"{dq.name} is folded ({q.name} is left).")
139
+ else:
140
+ # Same dtype → the Quantize–Dequantize pair is redundant.
141
+ assert op_qparam.scale and op_qparam.scale[0] == q_args.scale
142
+ assert (
143
+ op_qparam.zero_point
144
+ and op_qparam.zero_point[0] == q_args.zero_p
145
+ )
146
+ dq.replace_all_uses_with(op, propagate_meta=False)
147
+ logger.debug(f"Removed redundant {dq.name}")
118
148
 
119
149
  graph.eliminate_dead_code()
120
150
  graph.lint()
@@ -117,6 +117,7 @@ class CastMixedTypeArgs(PassBase):
117
117
  lhs_val, rhs_val, type_promotion_kind=ops_to_promote[node.target]
118
118
  )[1]
119
119
  arg_to_promote = None
120
+ ori_type = None
120
121
  if lhs_val.dtype == type_to_promote:
121
122
  ori_type = rhs_val.dtype
122
123
  arg_to_promote = rhs
@@ -110,6 +110,8 @@ class ConvertConv1dToConv2d(PassBase):
110
110
  conv2d_op = torch.ops.aten.conv2d.default
111
111
  elif isinstance(padding, str):
112
112
  conv2d_op = torch.ops.aten.conv2d.padding
113
+ else:
114
+ raise RuntimeError("Invalid input")
113
115
 
114
116
  conv2d = create_node(
115
117
  graph,
@@ -86,6 +86,8 @@ class FuseRedundantReshapeToMean(PassBase):
86
86
  updated_args = node.args + (keep_dims,)
87
87
  elif len(mean_args) == 3:
88
88
  updated_args = node.args
89
+ else:
90
+ raise RuntimeError("Invalid input")
89
91
  node.args = updated_args
90
92
  node.meta["val"] = fused_val
91
93
  user_node.replace_all_uses_with(node, propagate_meta=False)
@@ -163,6 +163,7 @@ class LegalizePreDefinedLayoutOperators(PassBase):
163
163
  node.update_arg(node.args.index(weight), weight_permute)
164
164
 
165
165
  with graph.inserting_before(node):
166
+ legalized_op = None
166
167
  if groups == 1:
167
168
  if isinstance(padding, list):
168
169
  legalized_op = torch.ops.circle_custom.conv2d
@@ -175,6 +176,7 @@ class LegalizePreDefinedLayoutOperators(PassBase):
175
176
  legalized_op = torch.ops.circle_custom.depthwise_conv2d.padding
176
177
  else:
177
178
  assert groups == 1 or groups == input_shape[1] # Cannot reach here
179
+ assert legalized_op is not None
178
180
 
179
181
  circle_op = create_node(
180
182
  graph, legalized_op, args=node.args, kwargs=node.kwargs, origin=node
@@ -242,12 +242,16 @@ class RemoveRedundantReshapePattern3(PassBase):
242
242
  softmax = reshape_1_args.input
243
243
 
244
244
  # softmax
245
+ softmax_args = None
245
246
  if not is_target_node(softmax, ops.aten.softmax):
246
247
  continue
247
248
  if softmax.target == torch.ops.aten._softmax.default:
248
249
  softmax_args = SoftmaxArgs(*softmax.args, **softmax.kwargs) # type: ignore[arg-type, assignment]
249
250
  elif softmax.target == torch.ops.aten._safe_softmax.default:
250
251
  softmax_args = SafeSoftmaxArgs(*softmax.args, **softmax.kwargs) # type: ignore[arg-type, assignment]
252
+ else:
253
+ raise RuntimeError("Invalid input")
254
+ assert softmax_args is not None
251
255
  add, softmax_dim = (
252
256
  softmax_args.input,
253
257
  softmax_args.dim,
tico/pt2_to_circle.py CHANGED
@@ -14,6 +14,7 @@
14
14
 
15
15
  import argparse
16
16
  import os
17
+ from typing import Optional
17
18
 
18
19
  import torch
19
20
  import yaml
@@ -27,8 +28,10 @@ def convert(
27
28
  input: str,
28
29
  output: str,
29
30
  verbose: bool = False,
30
- config: CompileConfigBase = get_default_config(),
31
+ config: Optional[CompileConfigBase] = None,
31
32
  ):
33
+ if config is None:
34
+ config = get_default_config()
32
35
  # TODO Check input and output
33
36
 
34
37
  if verbose:
@@ -73,6 +76,7 @@ def main():
73
76
 
74
77
  args = parser.parse_args()
75
78
 
79
+ config = None
76
80
  if args.config:
77
81
  with open(args.config) as f:
78
82
  config_dict = yaml.safe_load(f)
@@ -102,6 +102,7 @@ class AnyVisitor(NodeVisitor):
102
102
  input_shape = list(extract_shape(input))
103
103
  output_shape = list(extract_shape(node))
104
104
 
105
+ dim_i32 = None
105
106
  if dim is None:
106
107
  dims = tuple(i for i in range(0, len(input_shape)))
107
108
  dim_i32 = tuple(
@@ -111,8 +112,12 @@ class AnyVisitor(NodeVisitor):
111
112
  dim_i32 = circle_legalize_dtype_to(dim, dtype=torch.int32)
112
113
  if isinstance(dim, tuple):
113
114
  dim_i32 = tuple(circle_legalize_dtype_to(d, dtype=torch.int32) for d in dim)
115
+ assert dim_i32 is not None
114
116
 
115
- inputs = [input, dim_i32]
117
+ inputs = [
118
+ input,
119
+ dim_i32,
120
+ ] # type: ignore[list-item]
116
121
  outputs = [node]
117
122
 
118
123
  dtype_torch = extract_torch_dtype(input)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: tico
3
- Version: 0.1.0.dev250622
3
+ Version: 0.1.0.dev250624
4
4
  Summary: Convert exported Torch module to circle
5
5
  Home-page: UNKNOWN
6
6
  License: UNKNOWN
@@ -1,5 +1,5 @@
1
- tico/__init__.py,sha256=U0yTg9CHkHxsRbkNANLYjrQ1kxP3vT3IjjtbLc8Bysk,1743
2
- tico/pt2_to_circle.py,sha256=PPmFNw20jw2Z2VyM3ln9pX__jTzBOAZiv0gT5a-p-Y8,2666
1
+ tico/__init__.py,sha256=XB8eztAKREkVE9vb9rfJU_Wx55LClZwOdTLgFv6whGU,1743
2
+ tico/pt2_to_circle.py,sha256=gu3MD4Iqc0zMZcCZ2IT8oGbyj21CTSbT3Rgd9s2B_9A,2767
3
3
  tico/config/__init__.py,sha256=xZzCXjZ84qE-CsBi-dfaL05bqpQ3stKKfTXhnrJRyVs,142
4
4
  tico/config/base.py,sha256=anwOiJFkUxUi7Cef573JgQcjk6S-FSi6O_TLjYASW-g,1244
5
5
  tico/config/factory.py,sha256=il0zqB6Lm5NX2LnG-TUhmiP9vVeZ_3TucJMorVZIodY,1324
@@ -50,7 +50,7 @@ tico/experimental/quantization/evaluation/executor/backend_executor.py,sha256=3k
50
50
  tico/experimental/quantization/evaluation/executor/circle_executor.py,sha256=eCCJ9wTwR0vUJ0oN7jxtQxZ9598GRw6P6KUxiuGsIIM,2685
51
51
  tico/experimental/quantization/evaluation/executor/triv24_executor.py,sha256=sUoXl6oOO2arAKaNjOBg7HiQja145_Jv6qgY7XtR7A8,5159
52
52
  tico/experimental/quantization/passes/__init__.py,sha256=IO6FP_xYbGy0dW0HL26GXD3ouxARaxCK7bz9dn4blPQ,26
53
- tico/experimental/quantization/passes/fold_quant_ops.py,sha256=cC5xuvqWqueKzLXUJi0pCk85vryImkhgnx-ee7G-tPI,4463
53
+ tico/experimental/quantization/passes/fold_quant_ops.py,sha256=iaBMyO49CwVkhebMz3rjkHWfWE2LhwH6fORe7n4S6XQ,7040
54
54
  tico/experimental/quantization/passes/insert_quantize_on_dtype_mismatch.py,sha256=AbNcI7rfIwHsQna_rFuwqFdOzFAU2lIB3sMK-vns8Dc,13072
55
55
  tico/experimental/quantization/passes/propagate_qparam_backward.py,sha256=TGtyW0Z2qOTgVIasBdGRgbwH31YYd6ek7OvLTmCV614,3118
56
56
  tico/experimental/quantization/passes/propagate_qparam_forward.py,sha256=RhUHGCR2RpBO5KYkQ7Z8U5u7HEwDq2wdKHLKAJCi-5c,5138
@@ -61,9 +61,9 @@ tico/interpreter/infer.py,sha256=vJ3b69ce9HrxNT0gFwbEhHpAyvVyuiunTgAeiqn5t64,435
61
61
  tico/interpreter/interpreter.py,sha256=tGbluCbrehTCqBu8mtGDNzby_ieJ2ry8_RH_eC0CQxk,3828
62
62
  tico/passes/__init__.py,sha256=IO6FP_xYbGy0dW0HL26GXD3ouxARaxCK7bz9dn4blPQ,26
63
63
  tico/passes/cast_aten_where_arg_type.py,sha256=ybtGj1L7_2zGyfb_G-_y1N1mRgKHVq6fBZc-9-fH9sA,7229
64
- tico/passes/cast_mixed_type_args.py,sha256=s1lAwYvJdYdkE11fK2n1faybPyA5CJtZkOkU46rhXXA,7590
64
+ tico/passes/cast_mixed_type_args.py,sha256=ArJpIPnQP1LPNaWIwee13Nbj749_awFKDO-pAYvdYvI,7618
65
65
  tico/passes/const_prop_pass.py,sha256=QOeR2u3fo9ZhWXRhfAUW1dTtuWgqgoqdDJoQ516UDbQ,11532
66
- tico/passes/convert_conv1d_to_conv2d.py,sha256=2AAs8q9BYuvMr0F1Mrua1rpGvwxOVIE10c798P5sFf8,5231
66
+ tico/passes/convert_conv1d_to_conv2d.py,sha256=7YljWJQBX5vBUMgGgRv8TvbJ9UpEL9hf4ZU3dNUhEZ8,5301
67
67
  tico/passes/convert_layout_op_to_reshape.py,sha256=sCAFjkmVtiKjvDQSAgnjNBHl3_hWXJZElGDXQiTH-7s,2963
68
68
  tico/passes/convert_repeat_to_expand_copy.py,sha256=JbtFTmWyfJS2SSd_higP1IEhQeh7wHdN5dmTbbiFVCs,3237
69
69
  tico/passes/convert_to_relu6.py,sha256=1BJpUwUb6Zli_1y3eyJQo7dg9B1xvZ7sYjMbvEQsFJM,6442
@@ -77,9 +77,9 @@ tico/passes/decompose_slice_scatter.py,sha256=xqMHKhW2595YoAeubKZ4jRhYW4TQ09EXPg
77
77
  tico/passes/extract_dtype_kwargs.py,sha256=ObpsaFlrTPYQw2hJ7UsC5CocyAtBkT_bMtzkMUqAyKc,4333
78
78
  tico/passes/fill_meta_val.py,sha256=Xbam6Aq90ZfWItZw1dgLIwH_q8RCiU5JodKNqkj-ink,1797
79
79
  tico/passes/fuse_leading_unsqueeze_reshape.py,sha256=88jwTP35yRyXOk9xdO6YW2OEfdKAws3KFRT16WQz0RI,4291
80
- tico/passes/fuse_redundant_reshape_to_mean.py,sha256=2SEZ0TfXsmUkuqUdNtS_mQzLd49su5TsQViCLMGL4f4,3691
80
+ tico/passes/fuse_redundant_reshape_to_mean.py,sha256=GhJS1ZKB6Ns4AhwcW3uUQ6q-0N-AzlD32B2EwusUJHg,3761
81
81
  tico/passes/legalize_causal_mask_value.py,sha256=xKdFwwMaSFCSQpSk8xISOAqFpZ1jIhgbBIqf7KTSGuk,4017
82
- tico/passes/legalize_predefined_layout_operators.py,sha256=oUwog9TGHT86MMy-T_ymTh5pQN0srSefiAA6CNiWVgA,15826
82
+ tico/passes/legalize_predefined_layout_operators.py,sha256=6jd_FmXX5rbBxqp3H5MQoCnL3vY3qoAdXaXkVdfXEjI,15902
83
83
  tico/passes/lower_pow2_to_mul.py,sha256=nfJXa9ZTZMiLg6ownSyvkM4KF2z9tZW34Q3CCWI_vmQ,2402
84
84
  tico/passes/lower_to_resize_nearest_neighbor.py,sha256=N6F56Of8Aiv-KIiYLHnh33WX72W60ZVQSBEYWHdYqNQ,9005
85
85
  tico/passes/lower_to_slice.py,sha256=0qAX3WzZdyMFDW4DiO9b5JFXd4rL1-0doBT6lJvaw_I,7260
@@ -89,7 +89,7 @@ tico/passes/remove_nop.py,sha256=Hf91p_EJAOC6DyWNthash0_UWtEcNc_M7znamQfYQ5Y,268
89
89
  tico/passes/remove_redundant_assert_nodes.py,sha256=IONd3xBy6I8tH6_Y1eN3_eCHH7WTC8soBgjXzOju9cQ,1612
90
90
  tico/passes/remove_redundant_expand.py,sha256=5SIqN7eIIcqF68tlrB31n1482jSBSBOgKb1wddLX6lw,2197
91
91
  tico/passes/remove_redundant_permute.py,sha256=98UsaZzFZdQzEEAR1pIzRisAf6hgfXLa88aayjalt3E,4292
92
- tico/passes/remove_redundant_reshape.py,sha256=inp5fMNXM675Rj29wmHn5xoPmOqbiDkgMmmsqguCeMk,16308
92
+ tico/passes/remove_redundant_reshape.py,sha256=ScLYTShXMXJBTzOByAEhX-qJe5pmu92pLsXv5mh7u5c,16454
93
93
  tico/passes/remove_redundant_slice.py,sha256=Iv7TbB39fktNb4eq0VdyZnwxL_VsKLJ90diMmaf3kZk,2087
94
94
  tico/passes/remove_redundant_to_copy.py,sha256=tKy4XKkO2l33fMxVPQ_iFkUeFvP15kbPvzPPhT_g0c8,3292
95
95
  tico/passes/restore_linear.py,sha256=xGJdNb-1CrkOKS9BnLbcblkZc6P2vVjKIi-7lRcs7Bk,4111
@@ -106,7 +106,7 @@ tico/serialize/operators/node_visitor.py,sha256=UYyCwXqSCeRyimThMShstHnt7vKM9tsu
106
106
  tico/serialize/operators/op_abs.py,sha256=Y-vy7rcqPT-qD3QS5R8zbApWWTPpjY6xuMMVnbIhYmQ,1827
107
107
  tico/serialize/operators/op_add.py,sha256=otm062DMHVAThWmOtSTZdPyP3P5-2cv5VL_UWBJeLms,2346
108
108
  tico/serialize/operators/op_alias_copy.py,sha256=Xu9OiILbGf8oddh8yTqovvLfgVs8XYV7Cg4n6CesWcg,2175
109
- tico/serialize/operators/op_any.py,sha256=QqAYby1WPd4l97vX-tBjAsOb_pVb1wPjj7SbWQNToCQ,5117
109
+ tico/serialize/operators/op_any.py,sha256=9oxP-8vS5R4oKX6KaePygzC4-jh8MVgbiS8Z5AWYOAw,5237
110
110
  tico/serialize/operators/op_arange_start_step.py,sha256=0T5lWwh3TfsFStmVv0v5qG03KENRDBmMix08RXQ4D-U,2132
111
111
  tico/serialize/operators/op_argmax.py,sha256=ARyGHlmWVmzwCct93V5x1-VyKqhxMOvV8GuM8yQWXdo,2290
112
112
  tico/serialize/operators/op_avg_pool2d.py,sha256=vc7WCakGXtGFPV1ix5EJmboH23tQ-cSI36ePY3PHKI4,7544
@@ -198,9 +198,9 @@ tico/utils/mx/__init__.py,sha256=IO6FP_xYbGy0dW0HL26GXD3ouxARaxCK7bz9dn4blPQ,26
198
198
  tico/utils/mx/elemwise_ops.py,sha256=V6glyAHsVR1joqpsgnNytatCD_ew92xNWZ19UFDoMTA,10281
199
199
  tico/utils/mx/formats.py,sha256=uzNWyu-1onUlwQfX5cZ6fZSUfHMRqorper7_T1k3jfk,3404
200
200
  tico/utils/mx/mx_ops.py,sha256=RcfUTYVi-wilGB2sC35OeARdwDqnixv7dG5iyZ-fQT8,8555
201
- tico-0.1.0.dev250622.dist-info/LICENSE,sha256=kp4JLII7bzRhPb0CPD5XTDZMh22BQ7h3k3B7t8TiSbw,12644
202
- tico-0.1.0.dev250622.dist-info/METADATA,sha256=PGKSmJTacXjjLvdGaeS4BtgUAEfmMcFQZnFxI5IpoR0,8846
203
- tico-0.1.0.dev250622.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
204
- tico-0.1.0.dev250622.dist-info/entry_points.txt,sha256=kBKYSS_IYrSXmUYevmmepqIVPScq5vF8ulQRu3I_Zf0,59
205
- tico-0.1.0.dev250622.dist-info/top_level.txt,sha256=oqs7UPoNSKZEwqsX8B-KAWdQwfAa7i60pbxW_Jk7P3w,5
206
- tico-0.1.0.dev250622.dist-info/RECORD,,
201
+ tico-0.1.0.dev250624.dist-info/LICENSE,sha256=kp4JLII7bzRhPb0CPD5XTDZMh22BQ7h3k3B7t8TiSbw,12644
202
+ tico-0.1.0.dev250624.dist-info/METADATA,sha256=wYEKWsf_DVC6nkCMwq4beejH_uGQrEQazoBsDJHlcAU,8846
203
+ tico-0.1.0.dev250624.dist-info/WHEEL,sha256=G16H4A3IeoQmnOrYV4ueZGKSjhipXx8zc8nu9FGlvMA,92
204
+ tico-0.1.0.dev250624.dist-info/entry_points.txt,sha256=kBKYSS_IYrSXmUYevmmepqIVPScq5vF8ulQRu3I_Zf0,59
205
+ tico-0.1.0.dev250624.dist-info/top_level.txt,sha256=oqs7UPoNSKZEwqsX8B-KAWdQwfAa7i60pbxW_Jk7P3w,5
206
+ tico-0.1.0.dev250624.dist-info/RECORD,,