accelforge 0.0.1__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.
Files changed (258) hide show
  1. accelforge/__init__.py +21 -0
  2. accelforge/_accelerated_imports.py +16 -0
  3. accelforge/_deprecate/_simanneal/evalmapping.py +271 -0
  4. accelforge/_deprecate/_simanneal/mapspaceglobals.py +298 -0
  5. accelforge/_deprecate/_simanneal/simanneal.py +666 -0
  6. accelforge/_deprecate/_simanneal/tracking.py +105 -0
  7. accelforge/_deprecate/_simanneal/wrappers.py +218 -0
  8. accelforge/_deprecate/_simanneal2/__init__.py +7 -0
  9. accelforge/_deprecate/_simanneal2/simanneal.py +493 -0
  10. accelforge/_deprecate/_simanneal2/tracking.py +116 -0
  11. accelforge/_deprecate/compatibility_util.py +181 -0
  12. accelforge/_deprecate/layerdeduplication/__init__.py +2 -0
  13. accelforge/_deprecate/layerdeduplication/group_similar_einsums.py +160 -0
  14. accelforge/_deprecate/layerdeduplication/grouped_einsums.py +84 -0
  15. accelforge/_deprecate/mapping_filter_tags/__init__.py +2 -0
  16. accelforge/_deprecate/mapping_filter_tags/ffmt.py +212 -0
  17. accelforge/_deprecate/mapping_filter_tags/onesplit.py +24 -0
  18. accelforge/_deprecate/mapping_filter_tags/util.py +24 -0
  19. accelforge/_deprecate/tags.py +69 -0
  20. accelforge/_deprecate/viz/__init__.py +0 -0
  21. accelforge/_deprecate/viz/interactive.py +159 -0
  22. accelforge/_deprecate/viz/reservationtree.py +307 -0
  23. accelforge/_deprecate/viz/ski_slope.py +88 -0
  24. accelforge/_version.py +15 -0
  25. accelforge/examples.py +39 -0
  26. accelforge/frontend/__init__.py +10 -0
  27. accelforge/frontend/_binding.py +129 -0
  28. accelforge/frontend/_workload_isl/__init__.py +2 -0
  29. accelforge/frontend/_workload_isl/_isl.py +149 -0
  30. accelforge/frontend/_workload_isl/_symbolic.py +141 -0
  31. accelforge/frontend/arch copy.py +1544 -0
  32. accelforge/frontend/arch.py +1642 -0
  33. accelforge/frontend/config.py +63 -0
  34. accelforge/frontend/mapper/__init__.py +5 -0
  35. accelforge/frontend/mapper/ffm.py +126 -0
  36. accelforge/frontend/mapper/mapper.py +7 -0
  37. accelforge/frontend/mapper/metrics.py +30 -0
  38. accelforge/frontend/mapping/__init__.py +1 -0
  39. accelforge/frontend/mapping/mapping.py +1736 -0
  40. accelforge/frontend/model.py +14 -0
  41. accelforge/frontend/renames.py +150 -0
  42. accelforge/frontend/spec copy.py +230 -0
  43. accelforge/frontend/spec.py +301 -0
  44. accelforge/frontend/variables.py +12 -0
  45. accelforge/frontend/workload.py +952 -0
  46. accelforge/mapper/FFM/__init__.py +9 -0
  47. accelforge/mapper/FFM/_join_pmappings/__init__.py +0 -0
  48. accelforge/mapper/FFM/_join_pmappings/compatibility.py +653 -0
  49. accelforge/mapper/FFM/_join_pmappings/compress_pmappings.py +140 -0
  50. accelforge/mapper/FFM/_join_pmappings/join_pmappings.py +703 -0
  51. accelforge/mapper/FFM/_join_pmappings/pmapping_dataframe.py +901 -0
  52. accelforge/mapper/FFM/_join_pmappings/pmapping_group.py +337 -0
  53. accelforge/mapper/FFM/_make_pmappings/contraints/__init__.py +0 -0
  54. accelforge/mapper/FFM/_make_pmappings/contraints/constraints.py +360 -0
  55. accelforge/mapper/FFM/_make_pmappings/make_pmapping_templates/__init__.py +1 -0
  56. accelforge/mapper/FFM/_make_pmappings/make_pmapping_templates/make_loops.py +373 -0
  57. accelforge/mapper/FFM/_make_pmappings/make_pmapping_templates/make_pmapping_templates.py +463 -0
  58. accelforge/mapper/FFM/_make_pmappings/make_pmapping_templates/make_reservations.py +95 -0
  59. accelforge/mapper/FFM/_make_pmappings/make_pmapping_templates/make_storage_order.py +382 -0
  60. accelforge/mapper/FFM/_make_pmappings/make_pmapping_templates/make_storages.py +155 -0
  61. accelforge/mapper/FFM/_make_pmappings/make_pmappings.py +411 -0
  62. accelforge/mapper/FFM/_make_pmappings/make_pmappings_from_templates/__init__.py +1 -0
  63. accelforge/mapper/FFM/_make_pmappings/make_pmappings_from_templates/make_pmappings_from_templates.py +407 -0
  64. accelforge/mapper/FFM/_make_pmappings/make_pmappings_from_templates/make_tile_shapes.py +1681 -0
  65. accelforge/mapper/FFM/_make_pmappings/make_pmappings_from_templates/run_model.py +170 -0
  66. accelforge/mapper/FFM/_make_pmappings/make_pmappings_from_templates/symbol_relations.py +174 -0
  67. accelforge/mapper/FFM/_make_pmappings/pmapper_job.py +282 -0
  68. accelforge/mapper/FFM/_pareto_df/df_convention.py +273 -0
  69. accelforge/mapper/FFM/_pareto_df/pareto copy.py +836 -0
  70. accelforge/mapper/FFM/_pareto_df/pareto.py +508 -0
  71. accelforge/mapper/FFM/data.py +61 -0
  72. accelforge/mapper/FFM/main copy.py +236 -0
  73. accelforge/mapper/FFM/main.py +208 -0
  74. accelforge/mapper/FFM/mappings.py +510 -0
  75. accelforge/mapper/FFM/pmappings.py +310 -0
  76. accelforge/mapper/__init__.py +4 -0
  77. accelforge/mapper.py +0 -0
  78. accelforge/model/__init__.py +1 -0
  79. accelforge/model/_looptree/__init__.py +0 -0
  80. accelforge/model/_looptree/accesses.py +335 -0
  81. accelforge/model/_looptree/capacity/__init__.py +1 -0
  82. accelforge/model/_looptree/capacity/aggregators.py +36 -0
  83. accelforge/model/_looptree/capacity/capacity.py +47 -0
  84. accelforge/model/_looptree/energy.py +150 -0
  85. accelforge/model/_looptree/equivalent_ranks.py +29 -0
  86. accelforge/model/_looptree/latency/__init__.py +1 -0
  87. accelforge/model/_looptree/latency/latency.py +98 -0
  88. accelforge/model/_looptree/latency/memory.py +120 -0
  89. accelforge/model/_looptree/latency/processors.py +92 -0
  90. accelforge/model/_looptree/mapping_utilities.py +71 -0
  91. accelforge/model/_looptree/reuse/__init__.py +4 -0
  92. accelforge/model/_looptree/reuse/isl/__init__.py +1 -0
  93. accelforge/model/_looptree/reuse/isl/des.py +59 -0
  94. accelforge/model/_looptree/reuse/isl/isl_functions.py +374 -0
  95. accelforge/model/_looptree/reuse/isl/mapping_to_isl/__init__.py +4 -0
  96. accelforge/model/_looptree/reuse/isl/mapping_to_isl/analyze_mapping.py +297 -0
  97. accelforge/model/_looptree/reuse/isl/mapping_to_isl/skews_from_mapping.py +236 -0
  98. accelforge/model/_looptree/reuse/isl/mapping_to_isl/tiling.py +685 -0
  99. accelforge/model/_looptree/reuse/isl/mapping_to_isl/types.py +188 -0
  100. accelforge/model/_looptree/reuse/isl/spatial.py +260 -0
  101. accelforge/model/_looptree/reuse/isl/temporal.py +182 -0
  102. accelforge/model/_looptree/reuse/symbolic/__init__.py +1 -0
  103. accelforge/model/_looptree/reuse/symbolic/symbolic copy 2.py +1346 -0
  104. accelforge/model/_looptree/reuse/symbolic/symbolic copy.py +1408 -0
  105. accelforge/model/_looptree/reuse/symbolic/symbolic.py +1396 -0
  106. accelforge/model/_looptree/run.py +122 -0
  107. accelforge/model/_looptree/types.py +26 -0
  108. accelforge/model/_looptree/visualization/__init__.py +0 -0
  109. accelforge/model/_looptree/visualization/occupancy.py +11 -0
  110. accelforge/model/main.py +222 -0
  111. accelforge/plotting/__init__.py +2 -0
  112. accelforge/plotting/mappings.py +219 -0
  113. accelforge/plotting/specs.py +57 -0
  114. accelforge/util/__init__.py +4 -0
  115. accelforge/util/_base_analysis_types.py +24 -0
  116. accelforge/util/_basetypes.py +1089 -0
  117. accelforge/util/_frozenset.py +36 -0
  118. accelforge/util/_isl.py +29 -0
  119. accelforge/util/_itertools.py +14 -0
  120. accelforge/util/_mathfuncs.py +57 -0
  121. accelforge/util/_parse_expressions.py +339 -0
  122. accelforge/util/_picklecache.py +32 -0
  123. accelforge/util/_setexpressions.py +268 -0
  124. accelforge/util/_sympy/__init__.py +0 -0
  125. accelforge/util/_sympy/broadcast_max.py +18 -0
  126. accelforge/util/_visualization.py +112 -0
  127. accelforge/util/_yaml.py +579 -0
  128. accelforge/util/parallel.py +193 -0
  129. accelforge-0.0.1.dist-info/METADATA +64 -0
  130. accelforge-0.0.1.dist-info/RECORD +258 -0
  131. accelforge-0.0.1.dist-info/WHEEL +5 -0
  132. accelforge-0.0.1.dist-info/licenses/LICENSE +19 -0
  133. accelforge-0.0.1.dist-info/top_level.txt +5 -0
  134. docs/_build/html/_sources/fastfusion.frontend.mapper.rst.txt +37 -0
  135. docs/_build/html/_sources/fastfusion.frontend.rst.txt +70 -0
  136. docs/_build/html/_sources/fastfusion.frontend.workload.rst.txt +21 -0
  137. docs/_build/html/_sources/fastfusion.mapper.FFM.rst.txt +37 -0
  138. docs/_build/html/_sources/fastfusion.mapper.rst.txt +18 -0
  139. docs/_build/html/_sources/fastfusion.rst.txt +20 -0
  140. docs/_build/html/_sources/fastfusion.util.rst.txt +21 -0
  141. docs/_build/html/_sources/index.rst.txt +87 -0
  142. docs/_build/html/_sources/modules.rst.txt +7 -0
  143. docs/_build/html/_sources/notes/citation.rst.txt +45 -0
  144. docs/_build/html/_sources/notes/definitions.rst.txt +43 -0
  145. docs/_build/html/_sources/notes/faqs.rst.txt +39 -0
  146. docs/_build/html/_sources/notes/modeling/accelerator_energy_latency.rst.txt +72 -0
  147. docs/_build/html/_sources/notes/modeling/component_energy_area.rst.txt +96 -0
  148. docs/_build/html/_sources/notes/modeling/mapping.rst.txt +100 -0
  149. docs/_build/html/_sources/notes/modeling.rst.txt +33 -0
  150. docs/_build/html/_sources/notes/parsing/arithmetic_parsing.rst.txt +136 -0
  151. docs/_build/html/_sources/notes/parsing/setexpressions.rst.txt +63 -0
  152. docs/_build/html/_sources/notes/parsing/yaml_parsing.rst.txt +176 -0
  153. docs/_build/html/_sources/notes/quickstart_and_installation.rst.txt +9 -0
  154. docs/_build/html/_sources/notes/spec/architecture.rst.txt +133 -0
  155. docs/_build/html/_sources/notes/spec/mapping.rst.txt +12 -0
  156. docs/_build/html/_sources/notes/spec/workload.rst.txt +83 -0
  157. docs/_build/html/_sources/notes/spec.rst.txt +36 -0
  158. docs/source/_ext/include_attrs.py +213 -0
  159. docs/source/_ext/include_docstring.py +364 -0
  160. docs/source/_ext/include_functions.py +154 -0
  161. docs/source/_ext/include_notebook.py +131 -0
  162. docs/source/_ext/include_yaml.py +119 -0
  163. docs/source/_ext/inherited_attributes.py +222 -0
  164. docs/source/_ext/paths.py +4 -0
  165. docs/source/conf.py +79 -0
  166. examples/arches/compute_in_memory/_include.yaml +74 -0
  167. examples/arches/compute_in_memory/_include_functions.py +229 -0
  168. examples/arches/compute_in_memory/_load_spec.py +57 -0
  169. examples/arches/compute_in_memory/components/c2c_multiplier.py +181 -0
  170. examples/arches/compute_in_memory/components/dac_c2c_r2r.py +605 -0
  171. examples/arches/compute_in_memory/components/misc.py +195 -0
  172. examples/arches/compute_in_memory/components/util/bit_functions.py +51 -0
  173. examples/arches/compute_in_memory/components/zero_comparator.py +92 -0
  174. examples/arches/compute_in_memory/isaac.yaml +233 -0
  175. examples/arches/compute_in_memory/memory_cells/ecram_demo.yaml +63 -0
  176. examples/arches/compute_in_memory/memory_cells/rram_example.yaml +63 -0
  177. examples/arches/compute_in_memory/memory_cells/rram_isaac_isca_2016.yaml +64 -0
  178. examples/arches/compute_in_memory/memory_cells/rram_neurosim_default.yaml +63 -0
  179. examples/arches/compute_in_memory/memory_cells/rram_raella_isca_2023.yaml +70 -0
  180. examples/arches/compute_in_memory/memory_cells/rram_wan_nature_2022.yaml +63 -0
  181. examples/arches/compute_in_memory/memory_cells/sram_colonnade_jssc_2021.yaml +63 -0
  182. examples/arches/compute_in_memory/memory_cells/sram_example.yaml +63 -0
  183. examples/arches/compute_in_memory/memory_cells/sram_jia_jssc_2020.yaml +63 -0
  184. examples/arches/compute_in_memory/memory_cells/sram_sinangil_jssc_2021.yaml +63 -0
  185. examples/arches/compute_in_memory/memory_cells/sram_wang_vlsi_2022.yaml +63 -0
  186. examples/arches/compute_in_memory/wang_vlsi_2022.yaml +289 -0
  187. examples/arches/eyeriss.yaml +68 -0
  188. examples/arches/fanout_variations/at_glb.yaml +31 -0
  189. examples/arches/fanout_variations/at_glb_with_fanout_node.yaml +34 -0
  190. examples/arches/fanout_variations/at_mac.yaml +31 -0
  191. examples/arches/fanout_variations/at_mac_with_constraints.yaml +38 -0
  192. examples/arches/fanout_variations/at_mac_with_fanout_node.yaml +34 -0
  193. examples/arches/nvdla.yaml +47 -0
  194. examples/arches/simple.yaml +28 -0
  195. examples/arches/tpu_v4i.yaml +67 -0
  196. examples/mappings/unfused_matmuls_to_simple.yaml +33 -0
  197. examples/misc/component_annotated.yaml +33 -0
  198. examples/workloads/gpt3_6.7B.yaml +124 -0
  199. examples/workloads/matmuls.yaml +20 -0
  200. examples/workloads/mobilenet_28.yaml +81 -0
  201. examples/workloads/mobilenet_various_separate.yaml +106 -0
  202. examples/workloads/three_matmuls_annotated.yaml +59 -0
  203. notebooks/.ipynb_checkpoints/fastfusion_arch_study_michael-checkpoint.ipynb +359 -0
  204. notebooks/compute_in_memory/_scripts.py +339 -0
  205. notebooks/compute_in_memory/isaac.guide.ipynb +270 -0
  206. notebooks/compute_in_memory/wang_vlsi_2022.ipynb +602 -0
  207. notebooks/paths.py +4 -0
  208. notebooks/tutorials/.ipynb_checkpoints/1_FFM-checkpoint.ipynb +3110 -0
  209. notebooks/tutorials/FFM.ipynb +3498 -0
  210. notebooks/tutorials/_include.py +48 -0
  211. notebooks/tutorials/component_energy_area.ipynb +363 -0
  212. tests/Q_mapping.yaml +38 -0
  213. tests/__init__.py +0 -0
  214. tests/conv.mapping.yaml +27 -0
  215. tests/conv.workload.yaml +13 -0
  216. tests/conv_sym.mapping.yaml +43 -0
  217. tests/copy.mapping.yaml +35 -0
  218. tests/copy.workload.yaml +15 -0
  219. tests/distribuffers/__init__.py +0 -0
  220. tests/distribuffers/multicast/test_cases.yaml +482 -0
  221. tests/distribuffers/spec/binding/valid_bindings.yaml +97 -0
  222. tests/distribuffers/spec/distributed.yaml +100 -0
  223. tests/distribuffers/spec/logical_arch.yaml +32 -0
  224. tests/distribuffers/spec/physical_arch.yaml +69 -0
  225. tests/distribuffers/test_binding.py +48 -0
  226. tests/frontend/__init__.py +0 -0
  227. tests/frontend/test_mapping_viz.py +52 -0
  228. tests/mapper/__init__.py +0 -0
  229. tests/mapper/configs/conv1d/conv1d.mapping.yaml +31 -0
  230. tests/mapper/configs/conv1d/conv1d.workload.yaml +11 -0
  231. tests/mapper/configs/two_conv1d/two_conv1d.expected.yaml +38 -0
  232. tests/mapper/configs/two_conv1d/two_conv1d.mapping.yaml +54 -0
  233. tests/mapper/configs/two_conv1d/two_conv1d.workload.yaml +19 -0
  234. tests/mapper/test_mapping_to_isl.py +90 -0
  235. tests/mapper/test_spatial_reuse_analysis.py +67 -0
  236. tests/mapper/test_temporal_reuse_analysis.py +56 -0
  237. tests/mapper/util.py +58 -0
  238. tests/matmul.mapping.yaml +29 -0
  239. tests/matmul.workload.yaml +12 -0
  240. tests/matmul_spatial.mapping.yaml +44 -0
  241. tests/mha.renames.yaml +65 -0
  242. tests/mha.workload.yaml +67 -0
  243. tests/mha.yaml +59 -0
  244. tests/mha_full.workload.yaml +67 -0
  245. tests/mobilenet.workload.yaml +35 -0
  246. tests/mobilenet_long.workload.yaml +64 -0
  247. tests/pmappingcache.py +24 -0
  248. tests/processing_stage.arch.yaml +40 -0
  249. tests/snowcat.arch.yaml +36 -0
  250. tests/test_ffm_join_pmappings.py +106 -0
  251. tests/test_ffm_make_pmappings.py +82 -0
  252. tests/test_ffm_make_tile_shapes.py +49 -0
  253. tests/test_mapper.py +100 -0
  254. tests/test_model.py +37 -0
  255. tests/test_plotting.py +72 -0
  256. tests/test_processing_stage.py +46 -0
  257. tests/test_symbolic_model.py +248 -0
  258. tests/test_workload.py +141 -0
@@ -0,0 +1,273 @@
1
+ import functools
2
+ import re
3
+
4
+ from accelforge.util._frozenset import fzs
5
+ from accelforge.frontend.workload import Rank
6
+ from accelforge.util._base_analysis_types import ActionKey, VerboseActionKey
7
+
8
+
9
+ MAPPING_COLUMN = "mapping"
10
+ COMPRESSED_INDEX = "compressed_index"
11
+ TILE_SHAPE_PREFIX = "tile_shape"
12
+
13
+ DICT_COLUMNS = set([MAPPING_COLUMN])
14
+ RESERVED_COLUMNS = DICT_COLUMNS
15
+
16
+ _resource_name_nloops_reg = re.compile(r"RESOURCE_(.+?)(?:_LEFT)?_LEVEL_(-?\d+)")
17
+
18
+ _resource_name_tensor_reg = re.compile(r"RESOURCE_(.+?)_LEVEL_(.+?)")
19
+
20
+
21
+ def dict_cached(func):
22
+ cache = {}
23
+
24
+ @functools.wraps(func)
25
+ def wrapper(*args, **kwargs):
26
+ key = (args, fzs(kwargs.items()))
27
+ if key not in cache:
28
+ cache[key] = func(*args, **kwargs)
29
+ return cache[key]
30
+
31
+ return wrapper
32
+
33
+
34
+ def partition_col(col, prefix, expected_len=None) -> list[str] | None:
35
+ col = col.split("<SEP>")
36
+ if col[0] != prefix:
37
+ return None
38
+ if expected_len is not None and len(col) != expected_len:
39
+ raise ValueError(
40
+ f'Expected {expected_len} parts in "{col}" with prefix "{prefix}" '
41
+ f"but got {len(col)}"
42
+ )
43
+ return col[1:]
44
+
45
+
46
+ @dict_cached
47
+ def action2col(action: ActionKey | VerboseActionKey) -> str:
48
+ if isinstance(action, VerboseActionKey):
49
+ return f"action<SEP>{action.level}<SEP>{action.tensor}<SEP>{action.action}"
50
+ elif isinstance(action, ActionKey):
51
+ return f"action<SEP>{action.level}<SEP>{action.action}"
52
+
53
+
54
+ @dict_cached
55
+ def col2action(colname: str) -> ActionKey | VerboseActionKey:
56
+ separated_names = colname.split("<SEP>")
57
+ if len(separated_names) == 4:
58
+ assert separated_names[0] == "action"
59
+ return ActionKey(separated_names[1], separated_names[2])
60
+ elif len(separated_names) == 5:
61
+ assert separated_names[1] == "action"
62
+ return VerboseActionKey(
63
+ separated_names[2],
64
+ separated_names[4],
65
+ separated_names[3],
66
+ separated_names[0],
67
+ )
68
+ else:
69
+ raise ValueError(f"bad column name: {colname}")
70
+
71
+
72
+ @dict_cached
73
+ def energy2col(action: ActionKey | VerboseActionKey) -> str:
74
+ if isinstance(action, VerboseActionKey):
75
+ return f"energy<SEP>{action.level}<SEP>{action.tensor}<SEP>{action.action}"
76
+ elif isinstance(action, ActionKey):
77
+ return f"energy<SEP>{action.level}<SEP>{action.action}"
78
+
79
+
80
+ @dict_cached
81
+ def col2energy(colname: str) -> ActionKey | VerboseActionKey:
82
+ separated_names = colname.split("<SEP>")
83
+ if len(separated_names) == 4:
84
+ assert separated_names[1] == "energy", colname
85
+ return ActionKey(separated_names[2], separated_names[3])
86
+ elif len(separated_names) == 5:
87
+ assert separated_names[1] == "energy"
88
+ return VerboseActionKey(
89
+ separated_names[2],
90
+ separated_names[4],
91
+ separated_names[3],
92
+ separated_names[0],
93
+ )
94
+ else:
95
+ raise ValueError(f"bad column name: {colname}")
96
+
97
+
98
+ @dict_cached
99
+ def col2nameloop(x: str) -> tuple[str, int] | None:
100
+ """Format: reservation name level left"""
101
+ x = partition_col(x, "reservation", 4)
102
+ if x is None:
103
+ return None
104
+ return x[0], int(x[1])
105
+
106
+
107
+ @dict_cached
108
+ def nameloop2col(name: str, nloops: int, left: bool = False) -> str:
109
+ """Format: reservation name level left"""
110
+ return f"reservation<SEP>{name}<SEP>{nloops}<SEP>" + ("left" if left else "right")
111
+
112
+
113
+ @dict_cached
114
+ def stride2col(rank_name: Rank, nloops: int) -> str:
115
+ """Format: stride rank_name nloops"""
116
+ return f"stride<SEP>{rank_name}<SEP>{nloops}"
117
+
118
+
119
+ @dict_cached
120
+ def col2stride(col: str) -> tuple[Rank, int] | None:
121
+ """Format: stride rank_name nloops"""
122
+ x = partition_col(col, "stride", 3)
123
+ return x[0], int(x[1])
124
+
125
+
126
+ @dict_cached
127
+ def initial2col(rank_name: Rank, nloops: int) -> str:
128
+ """Format: initial rank_name nloops"""
129
+ return f"initial<SEP>{rank_name}<SEP>{nloops}"
130
+
131
+
132
+ @dict_cached
133
+ def col2initial(col: str) -> tuple[Rank, int] | None:
134
+ """Format: initial rank_name nloops"""
135
+ x = partition_col(col, "initial", 3)
136
+ return x[0], int(x[1])
137
+
138
+
139
+ @dict_cached
140
+ def iterations2col(nloops: int) -> str:
141
+ """Format: n_iterations nloops"""
142
+ return f"n_iterations<SEP>{nloops}"
143
+
144
+
145
+ @dict_cached
146
+ def col2iterations(col: str) -> int | None:
147
+ """Format: n_iterations nloops"""
148
+ x = partition_col(col, "n_iterations", 2)
149
+ return x[0]
150
+
151
+
152
+ @dict_cached
153
+ def firstlatency2col(name: str, nloops: int) -> str:
154
+ """Format: first latency name level"""
155
+ return f"first_latency<SEP>{name}<SEP>{nloops}"
156
+
157
+
158
+ @dict_cached
159
+ def tensor2col(tensor: str) -> str:
160
+ """Format: tensor tensor_name"""
161
+ return f"tensor<SEP>{tensor}"
162
+
163
+
164
+ @dict_cached
165
+ def col2nametensor(col: str) -> str | None:
166
+ """Format: tensor tensor_name"""
167
+ x = partition_col(col, "tensor", 2)
168
+ if x is None:
169
+ return None
170
+ return x[1]
171
+
172
+
173
+ @dict_cached
174
+ def is_tensor_col(c: str) -> bool:
175
+ return c.startswith("tensor<SEP>")
176
+
177
+
178
+ @dict_cached
179
+ def col2nameloopleft(x: str) -> tuple[str, int, bool] | None:
180
+ """Format: reservation name level left"""
181
+ x = partition_col(x, "reservation", 4)
182
+ if x is None:
183
+ return None
184
+ return x[0], x[1], x[2] == "left"
185
+
186
+
187
+ def is_reservation_col(x: str) -> bool:
188
+ return col2nameloop(x) is not None
189
+
190
+
191
+ @dict_cached
192
+ def is_left_col(x: str) -> bool:
193
+ """Format: reservation name level left"""
194
+ x = partition_col(x, "reservation", 4)
195
+ if x is None:
196
+ return False
197
+ return x[2] == "left"
198
+
199
+
200
+ def make_fused_loop_col(s: str) -> str:
201
+ return f"fused_loop<SEP>{s}"
202
+
203
+
204
+ def is_fused_loop_col(c: str) -> bool:
205
+ return c.startswith("fused_loop<SEP>")
206
+
207
+
208
+ def is_n_iterations_col(c: str) -> bool:
209
+ return c.startswith("fused_loop<SEP>n_iterations")
210
+
211
+
212
+ def add_to_col(df, target, source):
213
+ if target in df:
214
+ target_type = df[target].dtype
215
+ source_type = df[source].dtype
216
+ if target_type != source_type:
217
+ df[target] = df[target].astype("float64")
218
+ df[source] = df[source].astype("float64")
219
+ df.loc[:, target] = df[target] + df[source] if target in df else df[source]
220
+
221
+
222
+ def max_to_col(df, target, source):
223
+ df.loc[:, target] = df[[target, source]].max(axis=1) if target in df else df[source]
224
+
225
+
226
+ def is_objective_col(c):
227
+ return partition_col(c, "Total") is not None
228
+
229
+
230
+ def col_used_in_pareto(c):
231
+ return col2nameloop(c) is not None or is_objective_col(c)
232
+
233
+
234
+ # Pipeline:
235
+ # - Need to share temporal loops up to the spatial loop index
236
+ # Resources:
237
+ # - Energy
238
+ # - PE usage
239
+ # - Buf usage
240
+ # - Buf accesses (for BW calculation later)
241
+
242
+ # - Options:
243
+ # - Non-pipelined: Sum resources above shared loops, max below.
244
+ # - Pipelined: Sum resources above shared loops, max below. Sum
245
+ # PE usage. Latency is pipeline latency summed.
246
+ #
247
+ # * Can't bake into compatiblity unless we have a notion of left vs.
248
+ # right pipelined.
249
+
250
+ # PIPELINE CHANGES REQUIRED:
251
+ # - Latency above above loop index (first tile), below (all subsequent tiles)
252
+ # - Compatibility includes information for how may be fused:
253
+ # - Pipelined: Max below latencies,
254
+ # - Non-pipelined:
255
+ # Shared resources:
256
+ # -
257
+ # SEQUENTIAL:
258
+ # - In parallel: Fetch all above-shared-loop resources for all operations
259
+ # - Sequentially: Fetch any below-shared-loop resources for all operations
260
+ # PIPELINE:
261
+ # - In parallel: Fetch all above-shared-loop resources for all operations
262
+ # - Sequentially: Fetch any below-shared-loop resources for the first iteration of all operations
263
+ # - In parallel: Fetch all below-shared-loop resources for all operations in all subsequent iterations
264
+
265
+
266
+ # Above index 0: Freed when Einsum fully terminates
267
+ # Above index 1: Freed after each iteration of the outermost loop
268
+
269
+ # -1 -> global resource
270
+ # 0 -> einsum only
271
+
272
+ # Shared index -1: Sum -1 resources, max everyone below
273
+ # Shared index 0: Sum 0 resources, max everyone below