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,49 @@
1
+ import unittest
2
+ from pathlib import Path
3
+
4
+ import time
5
+
6
+ from accelforge.frontend.spec import Spec, Mapping
7
+ from accelforge.mapper.FFM._make_pmappings.contraints.constraints import (
8
+ MappingConstraints,
9
+ )
10
+ from accelforge.mapper.FFM._make_pmappings.pmapper_job import Job
11
+ from accelforge.mapper.FFM._make_pmappings.make_pmappings import make_tile_shapes
12
+ from accelforge.frontend.mapper.metrics import Metrics
13
+ from accelforge.frontend import arch
14
+
15
+
16
+ class TestTileShapeExploration(unittest.TestCase):
17
+ def test_pmapping(self):
18
+ PARENT_DIR = Path(__file__).parent
19
+ spec = Spec.from_yaml(
20
+ PARENT_DIR / "conv.workload.yaml", PARENT_DIR / "four_level.arch.yaml"
21
+ )
22
+ spec = spec.calculate_component_area_energy_latency_leak(area=False)
23
+
24
+ mapping = Mapping.from_yaml(PARENT_DIR / "conv_sym.mapping.yaml")
25
+
26
+ flattened_arch = spec._get_flattened_architecture()
27
+ memories_track_all = [
28
+ m.name for m in flattened_arch if isinstance(m, arch.Memory)
29
+ ]
30
+ memories_track_pmappings_only = []
31
+
32
+ job = Job(
33
+ mapping=mapping,
34
+ constraints=MappingConstraints(),
35
+ spec=spec,
36
+ metrics=Metrics.LATENCY,
37
+ job_id=0,
38
+ rank_variable_bounds={},
39
+ memories_track_all=memories_track_all,
40
+ memories_track_pmappings_only=memories_track_pmappings_only,
41
+ )
42
+
43
+ result, _ = make_tile_shapes(job)
44
+ data, n_total_pmappings = result
45
+ self.assertTrue("Total_latency" in data.columns)
46
+
47
+
48
+ if __name__ == "__main__":
49
+ unittest.main()
tests/test_mapper.py ADDED
@@ -0,0 +1,100 @@
1
+ import unittest
2
+ from pathlib import Path
3
+
4
+ from accelforge.frontend.spec import Spec
5
+ from accelforge.mapper import Metrics
6
+ from accelforge.mapper.FFM.main import map_workload_to_arch
7
+
8
+
9
+ EXAMPLES_DIR = Path(__file__).parent.parent / "examples"
10
+
11
+ M_SHAPE = 64
12
+ KN_SHAPE = 64
13
+
14
+
15
+ class ActionChecker(unittest.TestCase):
16
+ def _check_memory_actions_exist(self, spec, memory_names, result):
17
+ for einsum_name in spec.workload.einsum_names:
18
+ for memory_name in memory_names:
19
+ for memory_action in ["read", "write"]:
20
+ self.assertTrue(
21
+ f"{einsum_name}<SEP>action<SEP>{memory_name}<SEP>{memory_action}" in result.data.columns,
22
+ f"{einsum_name}<SEP>action<SEP>{memory_name}<SEP>{memory_action} "
23
+ f"not found in {result.data.columns}"
24
+ )
25
+
26
+
27
+ class TestMapper(ActionChecker, unittest.TestCase):
28
+ def test_one_matmul(self):
29
+ spec = Spec.from_yaml(
30
+ EXAMPLES_DIR / "arches" / "simple.yaml",
31
+ EXAMPLES_DIR / "workloads" / "matmuls.yaml",
32
+ jinja_parse_data={"N_EINSUMS": 1, "M": 64, "KN": 64},
33
+ )
34
+
35
+ result = map_workload_to_arch(spec)
36
+ self._check_memory_actions_exist(spec, ["MainMemory", "GlobalBuffer"], result)
37
+
38
+ def test_two_matmuls(self):
39
+ spec = Spec.from_yaml(
40
+ EXAMPLES_DIR / "arches" / "simple.yaml",
41
+ EXAMPLES_DIR / "workloads" / "matmuls.yaml",
42
+ jinja_parse_data={"N_EINSUMS": 2, "M": 64, "KN": 64},
43
+ )
44
+
45
+ result = map_workload_to_arch(spec)
46
+ self._check_memory_actions_exist(spec, ["MainMemory", "GlobalBuffer"], result)
47
+
48
+
49
+ class TestFanout(ActionChecker):
50
+ FANOUT = 4
51
+ """Need to sync this with YAMLs somehow."""
52
+
53
+ def _run_with_arch(self, arch_fname: str, n_einsums=1):
54
+ spec = Spec.from_yaml(
55
+ EXAMPLES_DIR / "arches" / "fanout_variations" / arch_fname,
56
+ EXAMPLES_DIR / "workloads" / "matmuls.yaml",
57
+ jinja_parse_data={"N_EINSUMS": n_einsums, "M": 64, "KN": 64},
58
+ )
59
+ spec.mapper.ffm.metrics = Metrics.LATENCY
60
+
61
+ result = map_workload_to_arch(spec)
62
+ self._check_memory_actions_exist(spec, ["MainMemory", "GlobalBuffer"], result)
63
+ self.assertEqual(
64
+ result.data["Matmul0<SEP>Total<SEP>latency"].iloc[0],
65
+ M_SHAPE*KN_SHAPE**2/self.FANOUT
66
+ )
67
+ return result
68
+
69
+
70
+ class TestMapperFanoutOneMatmul(TestFanout):
71
+ def test_at_mac(self):
72
+ self._run_with_arch("at_mac.yaml")
73
+
74
+ def test_at_glb(self):
75
+ self._run_with_arch("at_glb.yaml")
76
+
77
+ def test_at_mac_with_fanout_node(self):
78
+ self._run_with_arch("at_mac_with_fanout_node.yaml")
79
+
80
+ def test_at_glb_with_fanout_node(self):
81
+ self._run_with_arch("at_glb_with_fanout_node.yaml")
82
+
83
+
84
+ class TestMapperFanoutTwoMatmuls(TestFanout):
85
+ def test_at_mac(self):
86
+ self._run_with_arch("at_mac.yaml", n_einsums=2)
87
+
88
+ def test_at_glb(self):
89
+ self._run_with_arch("at_glb.yaml", n_einsums=2)
90
+
91
+ def test_at_mac_with_fanout_node(self):
92
+ self._run_with_arch("at_mac_with_fanout_node.yaml", n_einsums=2)
93
+
94
+ def test_at_glb_with_fanout_node(self):
95
+ self._run_with_arch("at_glb_with_fanout_node.yaml", n_einsums=2)
96
+
97
+
98
+ class TestMapperFanoutConstraints(TestFanout):
99
+ def test_at_mac_constraints(self):
100
+ self._run_with_arch("at_mac_with_constraints.yaml")
tests/test_model.py ADDED
@@ -0,0 +1,37 @@
1
+ import unittest
2
+ from pathlib import Path
3
+
4
+ from accelforge.frontend.spec import Spec
5
+ from accelforge.model.main import evaluate_mapping
6
+ from accelforge.util.parallel import set_n_parallel_jobs
7
+
8
+ set_n_parallel_jobs(1)
9
+
10
+
11
+ EXAMPLES_DIR = Path(__file__).parent.parent / "examples"
12
+
13
+
14
+ class TestModel(unittest.TestCase):
15
+ def test_one_matmul(self):
16
+ spec = Spec.from_yaml(
17
+ EXAMPLES_DIR / "arches" / "simple.yaml",
18
+ EXAMPLES_DIR / "workloads" / "matmuls.yaml",
19
+ EXAMPLES_DIR / "mappings" / "unfused_matmuls_to_simple.yaml",
20
+ jinja_parse_data={"N_EINSUMS": 1, "M": 64, "KN": 64},
21
+ )
22
+
23
+ result = evaluate_mapping(spec)
24
+
25
+ def test_two_matmuls(self):
26
+ spec = Spec.from_yaml(
27
+ EXAMPLES_DIR / "arches" / "simple.yaml",
28
+ EXAMPLES_DIR / "workloads" / "matmuls.yaml",
29
+ EXAMPLES_DIR / "mappings" / "unfused_matmuls_to_simple.yaml",
30
+ jinja_parse_data={"N_EINSUMS": 2, "M": 64, "KN": 64},
31
+ )
32
+
33
+ result = evaluate_mapping(spec)
34
+
35
+
36
+ if __name__ == "__main__":
37
+ unittest.main()
tests/test_plotting.py ADDED
@@ -0,0 +1,72 @@
1
+ import unittest
2
+ from pathlib import Path
3
+
4
+ from accelforge.frontend.spec import Spec
5
+ from accelforge.model.main import evaluate_mapping
6
+ from accelforge.util.parallel import set_n_parallel_jobs
7
+ from accelforge.plotting.mappings import plot_energy_comparison, plot_energy_breakdown, plot_action_breakdown
8
+
9
+ set_n_parallel_jobs(1)
10
+
11
+
12
+ EXAMPLES_DIR = Path(__file__).parent.parent / "examples"
13
+
14
+
15
+ class TestEnergyPlotting(unittest.TestCase):
16
+ def test_comparison(self):
17
+ spec = Spec.from_yaml(
18
+ EXAMPLES_DIR / "arches" / "simple.yaml",
19
+ EXAMPLES_DIR / "workloads" / "matmuls.yaml",
20
+ EXAMPLES_DIR / "mappings" / "unfused_matmuls_to_simple.yaml",
21
+ jinja_parse_data={"N_EINSUMS": 2, "M": 64, "KN": 64},
22
+ )
23
+
24
+ result = evaluate_mapping(spec)
25
+
26
+ fig, ax = plot_energy_comparison([result])
27
+ fig.tight_layout()
28
+ fig.savefig("total.png", dpi=400, bbox_inches="tight")
29
+
30
+ def test_breakdown(self):
31
+ spec = Spec.from_yaml(
32
+ EXAMPLES_DIR / "arches" / "simple.yaml",
33
+ EXAMPLES_DIR / "workloads" / "matmuls.yaml",
34
+ EXAMPLES_DIR / "mappings" / "unfused_matmuls_to_simple.yaml",
35
+ jinja_parse_data={"N_EINSUMS": 2, "M": 64, "KN": 64},
36
+ )
37
+
38
+ result = evaluate_mapping(spec)
39
+
40
+ fig, axes = plot_energy_breakdown([result, result], ["einsum", "component"])
41
+ fig.tight_layout()
42
+ fig.savefig("fig.png", dpi=400, bbox_inches="tight")
43
+
44
+ def test_breakdown_stacked(self):
45
+ spec = Spec.from_yaml(
46
+ EXAMPLES_DIR / "arches" / "simple.yaml",
47
+ EXAMPLES_DIR / "workloads" / "matmuls.yaml",
48
+ EXAMPLES_DIR / "mappings" / "unfused_matmuls_to_simple.yaml",
49
+ jinja_parse_data={"N_EINSUMS": 2, "M": 64, "KN": 64},
50
+ )
51
+
52
+ result = evaluate_mapping(spec)
53
+
54
+ fig, axes = plot_energy_breakdown([result, result], ["einsum", "component"], ["action"])
55
+ fig.tight_layout()
56
+ fig.savefig("fig.png", dpi=400, bbox_inches="tight")
57
+
58
+
59
+ class TestActionPlotting(unittest.TestCase):
60
+ def test_breakdown(self):
61
+ spec = Spec.from_yaml(
62
+ EXAMPLES_DIR / "arches" / "simple.yaml",
63
+ EXAMPLES_DIR / "workloads" / "matmuls.yaml",
64
+ EXAMPLES_DIR / "mappings" / "unfused_matmuls_to_simple.yaml",
65
+ jinja_parse_data={"N_EINSUMS": 2, "M": 64, "KN": 64},
66
+ )
67
+
68
+ result = evaluate_mapping(spec)
69
+
70
+ fig, axes = plot_action_breakdown([result, result], ["einsum", "component"])
71
+ fig.tight_layout()
72
+ fig.savefig("fig.png", dpi=400, bbox_inches="tight")
@@ -0,0 +1,46 @@
1
+ from math import isclose
2
+ import unittest
3
+ from pathlib import Path
4
+
5
+ from accelforge.frontend import Spec
6
+ from accelforge.frontend.arch import Arch
7
+ from accelforge.frontend.mapping import Mapping
8
+ from accelforge.frontend.workload import Workload
9
+
10
+ from accelforge.frontend.mapper.metrics import Metrics
11
+ from accelforge.model._looptree.accesses import (
12
+ isl_buffer_accesses_from_buffet_actions,
13
+ Accesses,
14
+ )
15
+ from accelforge.model._looptree.energy import gather_actions
16
+ from accelforge.model._looptree.latency import get_latency
17
+ from accelforge.model._looptree.types import Buffet
18
+ from accelforge.model._looptree.reuse.symbolic import (
19
+ BuffetStats,
20
+ analyze_reuse_and_add_reservations_to_mapping,
21
+ Compute,
22
+ )
23
+ from accelforge.mapper.FFM import make_pmappings, join_pmappings
24
+
25
+
26
+ PARENT_DIR = Path(__file__).parent
27
+
28
+
29
+ class TestProcessingStage(unittest.TestCase):
30
+ def test_processing_stage(self):
31
+ spec = Spec.from_yaml(
32
+ [
33
+ Path(__file__).parent / "processing_stage.arch.yaml",
34
+ Path(__file__).parent / "matmul.workload.yaml",
35
+ ]
36
+ )
37
+ spec.mapper.ffm.metrics = Metrics.ENERGY
38
+ pmappings = make_pmappings(spec)
39
+ mappings = join_pmappings(spec, pmappings)
40
+
41
+ energy = mappings.data.iloc[0]["Total_energy"]
42
+ self.assertAlmostEqual(energy, 100 * (128 * 64 * 2 + 128 * 128))
43
+
44
+
45
+ if __name__ == "__main__":
46
+ unittest.main()
@@ -0,0 +1,248 @@
1
+ from math import isclose
2
+ import unittest
3
+ from pathlib import Path
4
+
5
+ from accelforge.frontend import Spec
6
+ from accelforge.frontend.mapping import Mapping
7
+ from accelforge.frontend.workload import Workload
8
+
9
+ from accelforge.mapper.FFM._make_pmappings.pmapper_job import Job
10
+ from accelforge.model._looptree.accesses import (
11
+ isl_buffer_accesses_from_buffet_actions,
12
+ Accesses,
13
+ )
14
+ from accelforge.model._looptree.energy import gather_actions
15
+ from accelforge.model._looptree.latency import get_latency
16
+ from accelforge.model._looptree.types import Buffet
17
+ from accelforge.model._looptree.reuse.symbolic import (
18
+ BuffetStats,
19
+ analyze_reuse_and_add_reservations_to_mapping,
20
+ Compute,
21
+ )
22
+
23
+
24
+ PARENT_DIR = Path(__file__).parent
25
+
26
+
27
+ def make_job(mapping: Mapping, workload: Workload) -> Job:
28
+ return Job(
29
+ spec=None,
30
+ mapping=mapping,
31
+ workload=workload,
32
+ )
33
+
34
+
35
+ class TestSymbolicModel(unittest.TestCase):
36
+ def test_q_mapping(self):
37
+ mapping = Mapping.from_yaml(Path(__file__).parent / "Q_mapping.yaml")
38
+ workload = Workload.from_yaml(Path(__file__).parent / "mha.yaml")
39
+
40
+ result = analyze_reuse_and_add_reservations_to_mapping(
41
+ make_job(mapping, workload)
42
+ )
43
+
44
+ self.assertAlmostEqual(
45
+ result.compute_stats[Compute("Q", "MAC")].total_ops, 64.0
46
+ )
47
+ self.assertAlmostEqual(
48
+ result.compute_stats[Compute("Q", "MAC")].max_per_unit_ops, 16.0
49
+ )
50
+
51
+ def test_conv_mapping(self):
52
+ mapping = Mapping.from_yaml(Path(__file__).parent / "conv.mapping.yaml")
53
+ workload = Workload.from_yaml(Path(__file__).parent / "conv.workload.yaml")
54
+
55
+ result = analyze_reuse_and_add_reservations_to_mapping(
56
+ make_job(mapping, workload)
57
+ )
58
+
59
+ self.assertAlmostEqual(
60
+ result.compute_stats[Compute("conv", "MAC")].total_ops, 120.0
61
+ )
62
+ self.assertAlmostEqual(
63
+ result.compute_stats[Compute("conv", "MAC")].max_per_unit_ops, 10.0
64
+ )
65
+
66
+ def test_matmul_mapping(self):
67
+ mapping = Mapping.from_yaml(Path(__file__).parent / "matmul.mapping.yaml")
68
+ workload = Workload.from_yaml(Path(__file__).parent / "matmul.workload.yaml")
69
+
70
+ result = analyze_reuse_and_add_reservations_to_mapping(
71
+ make_job(mapping, workload)
72
+ )
73
+
74
+ REF_OCCUPANCY = {"W0": 1, "T0": 128, "T1": 128 * 128}
75
+ for tensor, ref_occupancy in REF_OCCUPANCY.items():
76
+ self.assertAlmostEqual(
77
+ result.buffet_stats[
78
+ Buffet(tensor, "Matmul1", "LocalBuffer")
79
+ ].max_occupancy,
80
+ ref_occupancy,
81
+ )
82
+
83
+ def test_matmul_spatial(self):
84
+ mapping = Mapping.from_yaml(PARENT_DIR / "matmul_spatial.mapping.yaml")
85
+ workload = Workload.from_yaml(PARENT_DIR / "matmul.workload.yaml")
86
+
87
+ result = analyze_reuse_and_add_reservations_to_mapping(
88
+ make_job(mapping, workload)
89
+ )
90
+ self.assertAlmostEqual(
91
+ result.fanout,
92
+ {
93
+ ("LocalBuffer", "Matmul1"): {0: 128.0, 1: 4.0},
94
+ ("MainMemory", "Matmul1"): {},
95
+ },
96
+ )
97
+
98
+ def test_copy_mapping(self):
99
+ mapping = Mapping.from_yaml(PARENT_DIR / "copy.mapping.yaml")
100
+ workload = Workload.from_yaml(PARENT_DIR / "copy.workload.yaml")
101
+
102
+ result = analyze_reuse_and_add_reservations_to_mapping(
103
+ make_job(mapping, workload)
104
+ )
105
+
106
+ self.assertAlmostEqual(
107
+ result.compute_stats[Compute("copy", "MAC")].total_ops, 0
108
+ )
109
+ self.assertAlmostEqual(
110
+ result.compute_stats[Compute("copy", "MAC")].max_per_unit_ops, 0
111
+ )
112
+
113
+ for tensor in ["O1", "O2", "O3", "O4"]:
114
+ for memory in [
115
+ "MainMemory",
116
+ "GlobalBuffer",
117
+ "LocalBuffer",
118
+ "Register",
119
+ "MAC",
120
+ ]:
121
+ buffet = Buffet(level=memory, tensor=tensor, einsum="copy")
122
+ if buffet not in result.buffet_stats:
123
+ continue
124
+ stats = result.buffet_stats[buffet]
125
+ self.assertAlmostEqual(stats.net_total_read_actions(), 0)
126
+ self.assertAlmostEqual(stats.net_max_per_unit_read_actions(), 0)
127
+ self.assertAlmostEqual(stats.net_total_write_actions(), 0)
128
+ self.assertAlmostEqual(stats.net_max_per_unit_write_actions(), 0)
129
+ self.assertAlmostEqual(stats.max_occupancy, 0)
130
+
131
+ buffet = Buffet(level="GlobalBuffer", tensor="I", einsum="copy")
132
+ stats = result.buffet_stats.get(buffet, BuffetStats())
133
+ self.assertAlmostEqual(stats.net_total_read_actions(), 0)
134
+ self.assertAlmostEqual(stats.net_max_per_unit_read_actions(), 0)
135
+ self.assertAlmostEqual(stats.net_total_write_actions(), 0)
136
+ self.assertAlmostEqual(stats.net_max_per_unit_write_actions(), 0)
137
+ self.assertAlmostEqual(stats.max_occupancy, 0)
138
+
139
+ stats = result.buffet_stats[
140
+ Buffet(level="LocalBuffer", tensor="I", einsum="copy")
141
+ ]
142
+ self.assertAlmostEqual(stats.net_total_read_actions(), 16)
143
+ self.assertAlmostEqual(stats.net_max_per_unit_read_actions(), 16)
144
+ self.assertAlmostEqual(stats.net_total_write_actions(), 0)
145
+ self.assertAlmostEqual(stats.net_max_per_unit_write_actions(), 0)
146
+ self.assertAlmostEqual(stats.max_occupancy, 2)
147
+
148
+ stats = result.buffet_stats[Buffet(level="Register", tensor="I", einsum="copy")]
149
+ self.assertAlmostEqual(stats.net_total_read_actions(), 0)
150
+ self.assertAlmostEqual(stats.net_max_per_unit_read_actions(), 0)
151
+ self.assertAlmostEqual(stats.net_total_write_actions(), 8)
152
+ self.assertAlmostEqual(stats.net_max_per_unit_write_actions(), 8)
153
+ self.assertAlmostEqual(stats.max_occupancy, 1)
154
+
155
+ stats = result.buffet_stats[
156
+ Buffet(level="MainMemory", tensor="I", einsum="copy")
157
+ ]
158
+ self.assertAlmostEqual(stats.net_total_read_actions(), 8)
159
+ self.assertAlmostEqual(stats.net_max_per_unit_read_actions(), 8)
160
+ self.assertAlmostEqual(stats.net_total_write_actions(), 8)
161
+ self.assertAlmostEqual(stats.net_max_per_unit_write_actions(), 8)
162
+ self.assertAlmostEqual(stats.max_occupancy, 8)
163
+
164
+ stats = result.buffet_stats[Buffet(level="Disk", tensor="I", einsum="copy")]
165
+ self.assertAlmostEqual(stats.net_total_read_actions(), 0)
166
+ self.assertAlmostEqual(stats.net_max_per_unit_read_actions(), 0)
167
+ self.assertAlmostEqual(stats.net_total_write_actions(), 8)
168
+ self.assertAlmostEqual(stats.net_max_per_unit_write_actions(), 8)
169
+ self.assertAlmostEqual(stats.max_occupancy, 8)
170
+
171
+
172
+ class TestSymbolicAccesses(unittest.TestCase):
173
+ def test_q_mapping(self):
174
+ mapping = Mapping.from_yaml(Path(__file__).parent / "Q_mapping.yaml")
175
+ workload = Workload.from_yaml(Path(__file__).parent / "mha.yaml")
176
+
177
+ result = analyze_reuse_and_add_reservations_to_mapping(
178
+ make_job(mapping, workload)
179
+ )
180
+
181
+ # main_memory_I_accesses = accesses.get_accesses('MainMemory', 'I', 'Q')
182
+ stats = result.buffet_stats[Buffet(level="MainMemory", tensor="I", einsum="Q")]
183
+ self.assertAlmostEqual(stats.net_total_read_actions(), 64.0)
184
+ self.assertAlmostEqual(stats.net_max_per_unit_read_actions(), 64.0)
185
+ self.assertAlmostEqual(stats.net_total_write_actions(), 0.0)
186
+ self.assertAlmostEqual(stats.net_max_per_unit_write_actions(), 0.0)
187
+
188
+ stats = result.buffet_stats[Buffet(level="LocalBuffer", tensor="I", einsum="Q")]
189
+ self.assertAlmostEqual(stats.net_total_read_actions(), 64.0)
190
+ self.assertAlmostEqual(stats.net_max_per_unit_read_actions(), 16.0)
191
+ self.assertAlmostEqual(stats.net_total_write_actions(), 64.0)
192
+ self.assertAlmostEqual(stats.net_max_per_unit_write_actions(), 16.0)
193
+
194
+ stats = result.buffet_stats[Buffet(level="MainMemory", tensor="Q", einsum="Q")]
195
+ self.assertAlmostEqual(stats.net_total_read_actions(), 0)
196
+ self.assertAlmostEqual(stats.net_max_per_unit_read_actions(), 0)
197
+ self.assertAlmostEqual(stats.net_total_write_actions(), 16.0)
198
+ self.assertAlmostEqual(stats.net_max_per_unit_write_actions(), 16.0)
199
+
200
+ stats = result.buffet_stats[Buffet(level="LocalBuffer", tensor="Q", einsum="Q")]
201
+ self.assertAlmostEqual(stats.net_total_read_actions(), 64.0)
202
+ self.assertAlmostEqual(stats.net_max_per_unit_read_actions(), 16.0)
203
+ self.assertAlmostEqual(stats.net_total_write_actions(), 64.0)
204
+ self.assertAlmostEqual(stats.net_max_per_unit_write_actions(), 16.0)
205
+
206
+
207
+ class TestSymbolicActions(unittest.TestCase):
208
+ def test_q_mapping(self):
209
+ mapping = Mapping.from_yaml(Path(__file__).parent / "Q_mapping.yaml")
210
+ workload = Workload.from_yaml(Path(__file__).parent / "mha.yaml")
211
+
212
+ result = analyze_reuse_and_add_reservations_to_mapping(
213
+ make_job(mapping, workload)
214
+ )
215
+ actions = gather_actions(result, None, use_name=True)
216
+
217
+ self.assertAlmostEqual(actions[("LocalBuffer", "read")].total, 128.0)
218
+ self.assertAlmostEqual(actions[("LocalBuffer", "read")].max_per_unit, 32.0)
219
+ self.assertAlmostEqual(actions[("LocalBuffer", "write")].total, 128.0)
220
+ self.assertAlmostEqual(actions[("LocalBuffer", "write")].max_per_unit, 32.0)
221
+
222
+ self.assertAlmostEqual(actions[("MAC", "compute")].total, 64.0)
223
+ self.assertAlmostEqual(actions[("MAC", "compute")].max_per_unit, 16.0)
224
+
225
+
226
+ class TestSymbolicLatency(unittest.TestCase):
227
+ def test_q_mapping(self):
228
+ spec = Spec.from_yaml(
229
+ [
230
+ # Path(__file__).parent / 'Q_mapping.yaml',
231
+ Path(__file__).parent / "mha.yaml",
232
+ Path(__file__).parent / "four_level.arch.yaml",
233
+ ]
234
+ )
235
+ workload = spec.workload
236
+ architecture = spec._get_flattened_architecture()
237
+ mapping = Mapping.from_yaml(Path(__file__).parent / "Q_mapping.yaml")
238
+
239
+ result = analyze_reuse_and_add_reservations_to_mapping(
240
+ make_job(mapping, workload)
241
+ )
242
+ overall_latency, _, _ = get_latency(result, mapping, workload, architecture)
243
+
244
+ self.assertAlmostEqual(overall_latency, 16.0)
245
+
246
+
247
+ if __name__ == "__main__":
248
+ unittest.main()