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 +1 -1
- tico/experimental/quantization/passes/fold_quant_ops.py +54 -24
- tico/passes/cast_mixed_type_args.py +1 -0
- tico/passes/convert_conv1d_to_conv2d.py +2 -0
- tico/passes/fuse_redundant_reshape_to_mean.py +2 -0
- tico/passes/legalize_predefined_layout_operators.py +2 -0
- tico/passes/remove_redundant_reshape.py +4 -0
- tico/pt2_to_circle.py +5 -1
- tico/serialize/operators/op_any.py +6 -1
- {tico-0.1.0.dev250622.dist-info → tico-0.1.0.dev250624.dist-info}/METADATA +1 -1
- {tico-0.1.0.dev250622.dist-info → tico-0.1.0.dev250624.dist-info}/RECORD +15 -15
- {tico-0.1.0.dev250622.dist-info → tico-0.1.0.dev250624.dist-info}/LICENSE +0 -0
- {tico-0.1.0.dev250622.dist-info → tico-0.1.0.dev250624.dist-info}/WHEEL +0 -0
- {tico-0.1.0.dev250622.dist-info → tico-0.1.0.dev250624.dist-info}/entry_points.txt +0 -0
- {tico-0.1.0.dev250622.dist-info → tico-0.1.0.dev250624.dist-info}/top_level.txt +0 -0
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.
|
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
|
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
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
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
|
-
#
|
85
|
-
#
|
86
|
-
#
|
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
|
-
|
126
|
+
|
107
127
|
if op_qparam.dtype != qdq_dtype:
|
108
|
-
#
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
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 =
|
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 = [
|
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,5 +1,5 @@
|
|
1
|
-
tico/__init__.py,sha256=
|
2
|
-
tico/pt2_to_circle.py,sha256=
|
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=
|
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=
|
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=
|
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=
|
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=
|
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=
|
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=
|
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.
|
202
|
-
tico-0.1.0.
|
203
|
-
tico-0.1.0.
|
204
|
-
tico-0.1.0.
|
205
|
-
tico-0.1.0.
|
206
|
-
tico-0.1.0.
|
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,,
|
File without changes
|
File without changes
|
File without changes
|
File without changes
|