mlonmcu 0.3.0.dev0__3-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 (376) hide show
  1. mlonmcu/__init__.py +26 -0
  2. mlonmcu/artifact.py +172 -0
  3. mlonmcu/cli/__init__.py +19 -0
  4. mlonmcu/cli/build.py +119 -0
  5. mlonmcu/cli/cleanup.py +75 -0
  6. mlonmcu/cli/common.py +227 -0
  7. mlonmcu/cli/compile.py +87 -0
  8. mlonmcu/cli/env.py +68 -0
  9. mlonmcu/cli/export.py +93 -0
  10. mlonmcu/cli/flow.py +67 -0
  11. mlonmcu/cli/helper/__init__.py +18 -0
  12. mlonmcu/cli/helper/filter.py +25 -0
  13. mlonmcu/cli/helper/parse.py +159 -0
  14. mlonmcu/cli/init.py +130 -0
  15. mlonmcu/cli/load.py +87 -0
  16. mlonmcu/cli/main.py +116 -0
  17. mlonmcu/cli/models.py +48 -0
  18. mlonmcu/cli/run.py +56 -0
  19. mlonmcu/cli/setup.py +136 -0
  20. mlonmcu/cli/tune.py +48 -0
  21. mlonmcu/config.py +219 -0
  22. mlonmcu/context/__init__.py +22 -0
  23. mlonmcu/context/context.py +545 -0
  24. mlonmcu/context/read_write_filelock.py +327 -0
  25. mlonmcu/environment/__init__.py +18 -0
  26. mlonmcu/environment/config.py +214 -0
  27. mlonmcu/environment/environment.py +501 -0
  28. mlonmcu/environment/init.py +191 -0
  29. mlonmcu/environment/list.py +81 -0
  30. mlonmcu/environment/loader.py +250 -0
  31. mlonmcu/environment/templates.py +69 -0
  32. mlonmcu/environment/writer.py +117 -0
  33. mlonmcu/feature/__init__.py +18 -0
  34. mlonmcu/feature/feature.py +230 -0
  35. mlonmcu/feature/features.py +1537 -0
  36. mlonmcu/feature/type.py +33 -0
  37. mlonmcu/flow/__init__.py +61 -0
  38. mlonmcu/flow/backend.py +234 -0
  39. mlonmcu/flow/framework.py +69 -0
  40. mlonmcu/flow/tflm/__init__.py +23 -0
  41. mlonmcu/flow/tflm/backend/__init__.py +23 -0
  42. mlonmcu/flow/tflm/backend/backend.py +47 -0
  43. mlonmcu/flow/tflm/backend/tflmc.py +129 -0
  44. mlonmcu/flow/tflm/backend/tflmi.py +385 -0
  45. mlonmcu/flow/tflm/framework.py +81 -0
  46. mlonmcu/flow/tvm/__init__.py +23 -0
  47. mlonmcu/flow/tvm/backend/__init__.py +26 -0
  48. mlonmcu/flow/tvm/backend/backend.py +282 -0
  49. mlonmcu/flow/tvm/backend/model_info.py +307 -0
  50. mlonmcu/flow/tvm/backend/python_utils.py +36 -0
  51. mlonmcu/flow/tvm/backend/tuner.py +41 -0
  52. mlonmcu/flow/tvm/backend/tvmaot.py +162 -0
  53. mlonmcu/flow/tvm/backend/tvmaotplus.py +51 -0
  54. mlonmcu/flow/tvm/backend/tvmc_utils.py +172 -0
  55. mlonmcu/flow/tvm/backend/tvmcg.py +102 -0
  56. mlonmcu/flow/tvm/backend/tvmllvm.py +106 -0
  57. mlonmcu/flow/tvm/backend/tvmrt.py +151 -0
  58. mlonmcu/flow/tvm/backend/wrapper.py +645 -0
  59. mlonmcu/flow/tvm/framework.py +96 -0
  60. mlonmcu/logging.py +79 -0
  61. mlonmcu/mlonmcu.py +19 -0
  62. mlonmcu/models/__init__.py +31 -0
  63. mlonmcu/models/convert_data.py +107 -0
  64. mlonmcu/models/frontend.py +571 -0
  65. mlonmcu/models/group.py +29 -0
  66. mlonmcu/models/lookup.py +345 -0
  67. mlonmcu/models/metadata.py +133 -0
  68. mlonmcu/models/model.py +104 -0
  69. mlonmcu/models/options.py +64 -0
  70. mlonmcu/models/utils.py +136 -0
  71. mlonmcu/platform/__init__.py +27 -0
  72. mlonmcu/platform/_platform.py +46 -0
  73. mlonmcu/platform/espidf/__init__.py +25 -0
  74. mlonmcu/platform/espidf/espidf.py +489 -0
  75. mlonmcu/platform/espidf/espidf_target.py +257 -0
  76. mlonmcu/platform/lookup.py +126 -0
  77. mlonmcu/platform/microtvm/__init__.py +25 -0
  78. mlonmcu/platform/microtvm/microtvm.py +580 -0
  79. mlonmcu/platform/microtvm/microtvm_arduino_target.py +68 -0
  80. mlonmcu/platform/microtvm/microtvm_backend.py +64 -0
  81. mlonmcu/platform/microtvm/microtvm_espidf_target.py +94 -0
  82. mlonmcu/platform/microtvm/microtvm_etissvp_target.py +98 -0
  83. mlonmcu/platform/microtvm/microtvm_host_target.py +46 -0
  84. mlonmcu/platform/microtvm/microtvm_spike_target.py +230 -0
  85. mlonmcu/platform/microtvm/microtvm_target.py +189 -0
  86. mlonmcu/platform/microtvm/microtvm_template_target.py +55 -0
  87. mlonmcu/platform/microtvm/microtvm_zephyr_target.py +91 -0
  88. mlonmcu/platform/mlif/__init__.py +25 -0
  89. mlonmcu/platform/mlif/mlif.py +300 -0
  90. mlonmcu/platform/mlif/mlif_target.py +86 -0
  91. mlonmcu/platform/platform.py +244 -0
  92. mlonmcu/platform/tvm/__init__.py +25 -0
  93. mlonmcu/platform/tvm/tvm.py +429 -0
  94. mlonmcu/platform/tvm/tvm_backend.py +57 -0
  95. mlonmcu/platform/tvm/tvm_target.py +165 -0
  96. mlonmcu/platform/zephyr/__init__.py +25 -0
  97. mlonmcu/platform/zephyr/zephyr.py +450 -0
  98. mlonmcu/platform/zephyr/zephyr_target.py +110 -0
  99. mlonmcu/plugins.py +26 -0
  100. mlonmcu/report.py +99 -0
  101. mlonmcu/session/__init__.py +18 -0
  102. mlonmcu/session/postprocess/__init__.py +43 -0
  103. mlonmcu/session/postprocess/postprocess.py +62 -0
  104. mlonmcu/session/postprocess/postprocesses.py +487 -0
  105. mlonmcu/session/run.py +1008 -0
  106. mlonmcu/session/session.py +373 -0
  107. mlonmcu/setup/__init__.py +18 -0
  108. mlonmcu/setup/cache.py +147 -0
  109. mlonmcu/setup/gen_requirements.py +619 -0
  110. mlonmcu/setup/setup.py +285 -0
  111. mlonmcu/setup/task.py +380 -0
  112. mlonmcu/setup/tasks/__init__.py +40 -0
  113. mlonmcu/setup/tasks/arm_gcc.py +58 -0
  114. mlonmcu/setup/tasks/cmsisnn.py +151 -0
  115. mlonmcu/setup/tasks/common.py +36 -0
  116. mlonmcu/setup/tasks/corstone300.py +64 -0
  117. mlonmcu/setup/tasks/espidf.py +87 -0
  118. mlonmcu/setup/tasks/etiss.py +147 -0
  119. mlonmcu/setup/tasks/llvm.py +67 -0
  120. mlonmcu/setup/tasks/mlif.py +49 -0
  121. mlonmcu/setup/tasks/muriscvnn.py +166 -0
  122. mlonmcu/setup/tasks/pulp.py +192 -0
  123. mlonmcu/setup/tasks/riscv_gcc.py +146 -0
  124. mlonmcu/setup/tasks/spike.py +190 -0
  125. mlonmcu/setup/tasks/tf.py +92 -0
  126. mlonmcu/setup/tasks/tflite.py +59 -0
  127. mlonmcu/setup/tasks/tflmc.py +141 -0
  128. mlonmcu/setup/tasks/tvm.py +172 -0
  129. mlonmcu/setup/tasks/utvmcg.py +96 -0
  130. mlonmcu/setup/tasks/zephyr.py +119 -0
  131. mlonmcu/setup/utils.py +374 -0
  132. mlonmcu/target/__init__.py +37 -0
  133. mlonmcu/target/_target.py +41 -0
  134. mlonmcu/target/arm/__init__.py +3 -0
  135. mlonmcu/target/arm/corstone300.py +235 -0
  136. mlonmcu/target/arm/util.py +109 -0
  137. mlonmcu/target/common.py +194 -0
  138. mlonmcu/target/elf.py +256 -0
  139. mlonmcu/target/host_x86.py +84 -0
  140. mlonmcu/target/metrics.py +75 -0
  141. mlonmcu/target/riscv/__init__.py +7 -0
  142. mlonmcu/target/riscv/etiss_pulpino.py +462 -0
  143. mlonmcu/target/riscv/gvsoc_pulp.py +215 -0
  144. mlonmcu/target/riscv/ovpsim.py +301 -0
  145. mlonmcu/target/riscv/riscv.py +185 -0
  146. mlonmcu/target/riscv/riscv_qemu.py +166 -0
  147. mlonmcu/target/riscv/spike.py +243 -0
  148. mlonmcu/target/riscv/util.py +134 -0
  149. mlonmcu/target/target.py +200 -0
  150. mlonmcu/utils.py +49 -0
  151. mlonmcu/version.py +21 -0
  152. mlonmcu-0.3.0.dev0.dist-info/LICENSE +202 -0
  153. mlonmcu-0.3.0.dev0.dist-info/METADATA +343 -0
  154. mlonmcu-0.3.0.dev0.dist-info/NOTICE +8 -0
  155. mlonmcu-0.3.0.dev0.dist-info/RECORD +376 -0
  156. mlonmcu-0.3.0.dev0.dist-info/WHEEL +5 -0
  157. mlonmcu-0.3.0.dev0.dist-info/entry_points.txt +3 -0
  158. mlonmcu-0.3.0.dev0.dist-info/top_level.txt +1 -0
  159. resources/frameworks/tvm/crt_config/README.md +7 -0
  160. resources/frameworks/tvm/crt_config/crt_config.h +53 -0
  161. resources/frameworks/tvm/tuning_records/riscv_cpu_v0.01.log.best +46 -0
  162. resources/patches/fix_esp32c3_march.patch +20 -0
  163. resources/patches/pulp_freertos_support.patch +55 -0
  164. resources/platforms/espidf/micro_speech_esp32devboard/CMakeLists.txt +29 -0
  165. resources/platforms/espidf/micro_speech_esp32devboard/README.md +70 -0
  166. resources/platforms/espidf/micro_speech_esp32devboard/components/mlif2/CMakeLists.txt +78 -0
  167. resources/platforms/espidf/micro_speech_esp32devboard/components/mlif2/Kconfig +76 -0
  168. resources/platforms/espidf/micro_speech_esp32devboard/components/mlif2/default_data.c +26 -0
  169. resources/platforms/espidf/micro_speech_esp32devboard/components/mlif2/default_model_support/process_input.c +35 -0
  170. resources/platforms/espidf/micro_speech_esp32devboard/components/mlif2/default_model_support/process_output.c +45 -0
  171. resources/platforms/espidf/micro_speech_esp32devboard/components/mlif2/include/exit.h +26 -0
  172. resources/platforms/espidf/micro_speech_esp32devboard/components/mlif2/include/ml_interface.h +70 -0
  173. resources/platforms/espidf/micro_speech_esp32devboard/components/mlif2/include/printing.h +31 -0
  174. resources/platforms/espidf/micro_speech_esp32devboard/components/mlif2/ml_interface.c +74 -0
  175. resources/platforms/espidf/micro_speech_esp32devboard/components/mlif2/ml_interface_tflm.cc +64 -0
  176. resources/platforms/espidf/micro_speech_esp32devboard/components/mlif2/ml_interface_tvm.c +53 -0
  177. resources/platforms/espidf/micro_speech_esp32devboard/components/tflite-lib/CMakeLists.txt +140 -0
  178. resources/platforms/espidf/micro_speech_esp32devboard/components/tflite-lib/Kconfig +8 -0
  179. resources/platforms/espidf/micro_speech_esp32devboard/components/tvm-lib/CMakeLists.txt +66 -0
  180. resources/platforms/espidf/micro_speech_esp32devboard/components/tvm-lib/Kconfig +7 -0
  181. resources/platforms/espidf/micro_speech_esp32devboard/example_test.py +38 -0
  182. resources/platforms/espidf/micro_speech_esp32devboard/info.txt +9 -0
  183. resources/platforms/espidf/micro_speech_esp32devboard/main/CMakeLists.txt +58 -0
  184. resources/platforms/espidf/micro_speech_esp32devboard/main/audio_provider.cc +193 -0
  185. resources/platforms/espidf/micro_speech_esp32devboard/main/audio_provider.h +49 -0
  186. resources/platforms/espidf/micro_speech_esp32devboard/main/command_responder.cc +53 -0
  187. resources/platforms/espidf/micro_speech_esp32devboard/main/command_responder.h +35 -0
  188. resources/platforms/espidf/micro_speech_esp32devboard/main/feature_provider.cc +132 -0
  189. resources/platforms/espidf/micro_speech_esp32devboard/main/feature_provider.cc.orig +145 -0
  190. resources/platforms/espidf/micro_speech_esp32devboard/main/feature_provider.h +55 -0
  191. resources/platforms/espidf/micro_speech_esp32devboard/main/kissfft/COPYING +11 -0
  192. resources/platforms/espidf/micro_speech_esp32devboard/main/kissfft/_kiss_fft_guts.h +168 -0
  193. resources/platforms/espidf/micro_speech_esp32devboard/main/kissfft/kiss_fft.c +408 -0
  194. resources/platforms/espidf/micro_speech_esp32devboard/main/kissfft/kiss_fft.h +124 -0
  195. resources/platforms/espidf/micro_speech_esp32devboard/main/kissfft/tools/kiss_fftr.c +159 -0
  196. resources/platforms/espidf/micro_speech_esp32devboard/main/kissfft/tools/kiss_fftr.h +46 -0
  197. resources/platforms/espidf/micro_speech_esp32devboard/main/main.cc +63 -0
  198. resources/platforms/espidf/micro_speech_esp32devboard/main/main_functions.cc +204 -0
  199. resources/platforms/espidf/micro_speech_esp32devboard/main/main_functions.h +37 -0
  200. resources/platforms/espidf/micro_speech_esp32devboard/main/micro_features_generator.cc +121 -0
  201. resources/platforms/espidf/micro_speech_esp32devboard/main/micro_features_generator.h +38 -0
  202. resources/platforms/espidf/micro_speech_esp32devboard/main/micro_model_settings.cc +23 -0
  203. resources/platforms/espidf/micro_speech_esp32devboard/main/micro_model_settings.h +43 -0
  204. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/bits.h +102 -0
  205. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/fft.cc +52 -0
  206. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/fft.h +50 -0
  207. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/fft_util.cc +69 -0
  208. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/fft_util.h +34 -0
  209. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/filterbank.c +134 -0
  210. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/filterbank.h +63 -0
  211. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/filterbank_util.c +220 -0
  212. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/filterbank_util.h +50 -0
  213. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/frontend.c +72 -0
  214. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/frontend.h +64 -0
  215. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/frontend_util.c +85 -0
  216. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/frontend_util.h +52 -0
  217. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/kiss_fft_common.h +48 -0
  218. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/kiss_fft_int16.cc +8 -0
  219. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/kiss_fft_int16.h +34 -0
  220. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/log_lut.c +30 -0
  221. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/log_lut.h +40 -0
  222. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/log_scale.c +83 -0
  223. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/log_scale.h +39 -0
  224. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/log_scale_util.c +27 -0
  225. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/log_scale_util.h +45 -0
  226. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/noise_reduction.c +51 -0
  227. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/noise_reduction.h +46 -0
  228. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/noise_reduction_util.c +45 -0
  229. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/noise_reduction_util.h +50 -0
  230. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/pcan_gain_control.c +56 -0
  231. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/pcan_gain_control.h +47 -0
  232. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/pcan_gain_control_util.c +92 -0
  233. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/pcan_gain_control_util.h +57 -0
  234. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/window.c +70 -0
  235. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/window.h +49 -0
  236. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/window_util.c +73 -0
  237. resources/platforms/espidf/micro_speech_esp32devboard/main/microfrontend/lib/window_util.h +45 -0
  238. resources/platforms/espidf/micro_speech_esp32devboard/main/pins.c +14 -0
  239. resources/platforms/espidf/micro_speech_esp32devboard/main/pins.h +30 -0
  240. resources/platforms/espidf/micro_speech_esp32devboard/main/recognize_commands.cc +150 -0
  241. resources/platforms/espidf/micro_speech_esp32devboard/main/recognize_commands.h +173 -0
  242. resources/platforms/espidf/micro_speech_esp32devboard/main/ringbuf.c +333 -0
  243. resources/platforms/espidf/micro_speech_esp32devboard/main/ringbuf.h +74 -0
  244. resources/platforms/espidf/micro_speech_esp32devboard/sdkconfig.defaults +36 -0
  245. resources/platforms/espidf/project/CMakeLists.txt +29 -0
  246. resources/platforms/espidf/project/README.md +70 -0
  247. resources/platforms/espidf/project/components/mlif/CMakeLists.txt +77 -0
  248. resources/platforms/espidf/project/components/mlif/Kconfig +76 -0
  249. resources/platforms/espidf/project/components/mlif/default_data.c +26 -0
  250. resources/platforms/espidf/project/components/mlif/default_model_support/process_input.c +35 -0
  251. resources/platforms/espidf/project/components/mlif/default_model_support/process_output.c +45 -0
  252. resources/platforms/espidf/project/components/mlif/include/exit.h +26 -0
  253. resources/platforms/espidf/project/components/mlif/include/ml_interface.h +60 -0
  254. resources/platforms/espidf/project/components/mlif/include/printing.h +31 -0
  255. resources/platforms/espidf/project/components/mlif/ml_interface.c +54 -0
  256. resources/platforms/espidf/project/components/mlif/ml_interface_tflm.cc +40 -0
  257. resources/platforms/espidf/project/components/mlif/ml_interface_tvm.c +40 -0
  258. resources/platforms/espidf/project/components/tflite-lib/CMakeLists.txt +142 -0
  259. resources/platforms/espidf/project/components/tflite-lib/Kconfig +8 -0
  260. resources/platforms/espidf/project/components/tvm-lib/CMakeLists.txt +66 -0
  261. resources/platforms/espidf/project/components/tvm-lib/Kconfig +7 -0
  262. resources/platforms/espidf/project/example_test.py +38 -0
  263. resources/platforms/espidf/project/main/CMakeLists.txt +25 -0
  264. resources/platforms/espidf/project/main/main.c +57 -0
  265. resources/platforms/espidf/project/sdkconfig.defaults +26 -0
  266. resources/platforms/zephyr/project/CMakeLists.txt +22 -0
  267. resources/platforms/zephyr/project/Kconfig +101 -0
  268. resources/platforms/zephyr/project/README.rst +33 -0
  269. resources/platforms/zephyr/project/cmake/AddAllSubdirs.cmake +21 -0
  270. resources/platforms/zephyr/project/cmake/ChooseTarget.cmake +22 -0
  271. resources/platforms/zephyr/project/cmake/LinkTFLite.cmake +223 -0
  272. resources/platforms/zephyr/project/cmake/LinkTVM.cmake +68 -0
  273. resources/platforms/zephyr/project/cmake/LookupClang.cmake +41 -0
  274. resources/platforms/zephyr/project/cmake/backends/tflmc.cmake +5 -0
  275. resources/platforms/zephyr/project/cmake/backends/tflmi.cmake +5 -0
  276. resources/platforms/zephyr/project/cmake/backends/tvmaot.cmake +10 -0
  277. resources/platforms/zephyr/project/cmake/backends/tvmaotplus.cmake +10 -0
  278. resources/platforms/zephyr/project/cmake/backends/tvmcg.cmake +10 -0
  279. resources/platforms/zephyr/project/cmake/backends/tvmllvm.cmake +8 -0
  280. resources/platforms/zephyr/project/cmake/backends/tvmrt.cmake +8 -0
  281. resources/platforms/zephyr/project/cmake/extras.cmake +9 -0
  282. resources/platforms/zephyr/project/cmake/features/auto_vectorize_gcc.cmake +65 -0
  283. resources/platforms/zephyr/project/cmake/features/auto_vectorize_llvm.cmake +20 -0
  284. resources/platforms/zephyr/project/cmake/features/cmsisnn.cmake +86 -0
  285. resources/platforms/zephyr/project/cmake/features/muriscvnn.cmake +87 -0
  286. resources/platforms/zephyr/project/cmake/frameworks/tflm.cmake +1 -0
  287. resources/platforms/zephyr/project/cmake/frameworks/tflm_mlif.cmake +8 -0
  288. resources/platforms/zephyr/project/cmake/frameworks/tvm.cmake +1 -0
  289. resources/platforms/zephyr/project/cmake/frameworks/tvm_mlif.cmake +37 -0
  290. resources/platforms/zephyr/project/lib/CMakeLists.txt +13 -0
  291. resources/platforms/zephyr/project/lib/drivers/fake_input.c +10 -0
  292. resources/platforms/zephyr/project/lib/drivers/fake_input.h +8 -0
  293. resources/platforms/zephyr/project/lib/ml_interface/CMakeLists.txt +31 -0
  294. resources/platforms/zephyr/project/lib/ml_interface/default_data.c +8 -0
  295. resources/platforms/zephyr/project/lib/ml_interface/default_model_support/CMakeLists.txt +2 -0
  296. resources/platforms/zephyr/project/lib/ml_interface/default_model_support/process_input.c +17 -0
  297. resources/platforms/zephyr/project/lib/ml_interface/default_model_support/process_output.c +27 -0
  298. resources/platforms/zephyr/project/lib/ml_interface/ml_interface.c +36 -0
  299. resources/platforms/zephyr/project/lib/ml_interface/ml_interface.h +47 -0
  300. resources/platforms/zephyr/project/lib/ml_interface/ml_interface_tflm.cc +22 -0
  301. resources/platforms/zephyr/project/lib/ml_interface/ml_interface_tvm.c +22 -0
  302. resources/platforms/zephyr/project/lib/support/CMakeLists.txt +2 -0
  303. resources/platforms/zephyr/project/lib/support/dummy.c +0 -0
  304. resources/platforms/zephyr/project/lib/support/exit.h +8 -0
  305. resources/platforms/zephyr/project/lib/support/printing.h +11 -0
  306. resources/platforms/zephyr/project/lib/support/quantize.h +23 -0
  307. resources/platforms/zephyr/project/lib/targets/corstone300.c +62 -0
  308. resources/platforms/zephyr/project/lib/targets/default.c +2 -0
  309. resources/platforms/zephyr/project/lib/targets/etiss_pulpino.c +112 -0
  310. resources/platforms/zephyr/project/lib/targets/generic_riscv.c +112 -0
  311. resources/platforms/zephyr/project/lib/targets/riscv_qemu.c +112 -0
  312. resources/platforms/zephyr/project/lib/targets/target.h +2 -0
  313. resources/platforms/zephyr/project/prj.conf +11 -0
  314. resources/platforms/zephyr/project/sample.yaml +19 -0
  315. resources/platforms/zephyr/project/src/main.c +71 -0
  316. resources/platforms/zephyr/project2/CMakeLists.txt +72 -0
  317. resources/platforms/zephyr/project2/Kconfig +101 -0
  318. resources/platforms/zephyr/project2/README.rst +33 -0
  319. resources/platforms/zephyr/project2/cmake/AddAllSubdirs.cmake +21 -0
  320. resources/platforms/zephyr/project2/cmake/ChooseTarget.cmake +22 -0
  321. resources/platforms/zephyr/project2/cmake/LinkTFLite.cmake +223 -0
  322. resources/platforms/zephyr/project2/cmake/LinkTVM.cmake +68 -0
  323. resources/platforms/zephyr/project2/cmake/LookupClang.cmake +41 -0
  324. resources/platforms/zephyr/project2/cmake/backends/tflmc.cmake +5 -0
  325. resources/platforms/zephyr/project2/cmake/backends/tflmi.cmake +5 -0
  326. resources/platforms/zephyr/project2/cmake/backends/tvmaot.cmake +10 -0
  327. resources/platforms/zephyr/project2/cmake/backends/tvmaotplus.cmake +10 -0
  328. resources/platforms/zephyr/project2/cmake/backends/tvmcg.cmake +10 -0
  329. resources/platforms/zephyr/project2/cmake/backends/tvmllvm.cmake +8 -0
  330. resources/platforms/zephyr/project2/cmake/backends/tvmrt.cmake +8 -0
  331. resources/platforms/zephyr/project2/cmake/extras.cmake +9 -0
  332. resources/platforms/zephyr/project2/cmake/features/auto_vectorize_gcc.cmake +65 -0
  333. resources/platforms/zephyr/project2/cmake/features/auto_vectorize_llvm.cmake +20 -0
  334. resources/platforms/zephyr/project2/cmake/features/cmsisnn.cmake +86 -0
  335. resources/platforms/zephyr/project2/cmake/features/muriscvnn.cmake +87 -0
  336. resources/platforms/zephyr/project2/cmake/frameworks/tflm.cmake +1 -0
  337. resources/platforms/zephyr/project2/cmake/frameworks/tflm_mlif.cmake +8 -0
  338. resources/platforms/zephyr/project2/cmake/frameworks/tvm.cmake +1 -0
  339. resources/platforms/zephyr/project2/cmake/frameworks/tvm_mlif.cmake +37 -0
  340. resources/platforms/zephyr/project2/default_data.c +8 -0
  341. resources/platforms/zephyr/project2/default_model_support/CMakeLists.txt +3 -0
  342. resources/platforms/zephyr/project2/default_model_support/process_input.c +17 -0
  343. resources/platforms/zephyr/project2/default_model_support/process_output.c +27 -0
  344. resources/platforms/zephyr/project2/lib/CMakeLists.txt +13 -0
  345. resources/platforms/zephyr/project2/lib/drivers/fake_input.c +10 -0
  346. resources/platforms/zephyr/project2/lib/drivers/fake_input.h +8 -0
  347. resources/platforms/zephyr/project2/lib/support/CMakeLists.txt +2 -0
  348. resources/platforms/zephyr/project2/lib/support/dummy.c +0 -0
  349. resources/platforms/zephyr/project2/lib/support/exit.h +8 -0
  350. resources/platforms/zephyr/project2/lib/support/printing.h +11 -0
  351. resources/platforms/zephyr/project2/lib/support/quantize.h +23 -0
  352. resources/platforms/zephyr/project2/lib/targets/corstone300.c +62 -0
  353. resources/platforms/zephyr/project2/lib/targets/default.c +2 -0
  354. resources/platforms/zephyr/project2/lib/targets/etiss_pulpino.c +112 -0
  355. resources/platforms/zephyr/project2/lib/targets/generic_riscv.c +112 -0
  356. resources/platforms/zephyr/project2/lib/targets/riscv_qemu.c +112 -0
  357. resources/platforms/zephyr/project2/lib/targets/target.h +2 -0
  358. resources/platforms/zephyr/project2/ml_interface.c +36 -0
  359. resources/platforms/zephyr/project2/ml_interface.h +47 -0
  360. resources/platforms/zephyr/project2/ml_interface_tflm.cc +22 -0
  361. resources/platforms/zephyr/project2/ml_interface_tvm.c +22 -0
  362. resources/platforms/zephyr/project2/prj.conf +13 -0
  363. resources/platforms/zephyr/project2/sample.yaml +19 -0
  364. resources/platforms/zephyr/project2/settings.json +6 -0
  365. resources/platforms/zephyr/project2/src/main.c +35 -0
  366. resources/pycharm/.run/README.md +73 -0
  367. resources/pycharm/.run/step1_ init env.run.xml +24 -0
  368. resources/pycharm/.run/step2_ setup.run.xml +25 -0
  369. resources/pycharm/.run/step3_ run resnet on pulpxpulpissimo.run.xml +25 -0
  370. resources/templates/default.yml.j2 +258 -0
  371. resources/templates/dev.yml.j2 +212 -0
  372. resources/templates/minimal.yml.j2 +234 -0
  373. resources/templates/phi.yml.j2 +282 -0
  374. resources/templates/pulp.yml.j2 +267 -0
  375. resources/templates/research.yml.j2 +237 -0
  376. resources/templates/tumeda.yml.j2 +239 -0
@@ -0,0 +1,373 @@
1
+ #
2
+ # Copyright (c) 2022 TUM Department of Electrical and Computer Engineering.
3
+ #
4
+ # This file is part of MLonMCU.
5
+ # See https://github.com/tum-ei-eda/mlonmcu.git for further info.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+ """Definition of a MLonMCU Run which represents a set of benchmarks in a session."""
20
+ import os
21
+ import shutil
22
+ import tempfile
23
+ import multiprocessing
24
+ from datetime import datetime
25
+ from enum import Enum
26
+ from pathlib import Path
27
+ import concurrent.futures
28
+
29
+ from tqdm import tqdm
30
+
31
+ from mlonmcu.session.run import Run
32
+ from mlonmcu.logging import get_logger
33
+ from mlonmcu.report import Report
34
+ from mlonmcu.config import filter_config
35
+
36
+ from .postprocess.postprocess import SessionPostprocess
37
+ from .run import RunStage
38
+
39
+ logger = get_logger() # TODO: rename to get_mlonmcu_logger
40
+
41
+
42
+ class SessionStatus(Enum): # TODO: remove?
43
+ """Status type for a session."""
44
+
45
+ CREATED = 0
46
+ OPEN = 1
47
+ CLOSED = 2
48
+ ERROR = 3
49
+
50
+
51
+ class Session:
52
+ """A session which wraps around multiple runs in a context."""
53
+
54
+ DEFAULTS = {
55
+ "report_fmt": "csv",
56
+ }
57
+
58
+ def __init__(self, label="", idx=None, archived=False, dir=None, config=None):
59
+ self.timestamp = datetime.now().strftime("%Y%m%dT%H%M%S")
60
+ self.label = (
61
+ label if len(label) > 0 else ("unnamed" + "_" + self.timestamp)
62
+ ) # TODO: decide if named sessions should also get a timestamp?
63
+ self.idx = idx
64
+ self.config = config if config else {}
65
+ self.config = filter_config(self.config, "session", self.DEFAULTS, [], [])
66
+ self.status = SessionStatus.CREATED
67
+ self.opened_at = None
68
+ self.closed_at = None
69
+ self.runs = []
70
+ self.report = None
71
+ self.next_run_idx = 0
72
+ self.archived = archived
73
+ if dir is None:
74
+ assert not self.archived
75
+ self.tempdir = tempfile.TemporaryDirectory()
76
+ self.dir = Path(self.tempdir.name)
77
+ else:
78
+ self.tempdir = None
79
+ self.dir = dir
80
+ if not self.dir.is_dir():
81
+ self.dir.mkdir(parents=True)
82
+ self.runs_dir = self.dir / "runs"
83
+ if not os.path.exists(self.runs_dir):
84
+ os.mkdir(self.runs_dir)
85
+ if not self.archived:
86
+ self.open()
87
+
88
+ @property
89
+ def prefix(self):
90
+ """get prefix property."""
91
+ return f"[session-{self.idx}] " if self.idx else ""
92
+
93
+ @property
94
+ def report_fmt(self):
95
+ """get report_fmt property."""
96
+ return str(self.config["report_fmt"])
97
+
98
+ def create_run(self, *args, **kwargs):
99
+ """Factory method to create a run and add it to this session."""
100
+ idx = len(self.runs)
101
+ logger.debug("Creating a new run with id %s", idx)
102
+ run = Run(*args, idx=idx, session=self, **kwargs)
103
+ self.runs.append(run)
104
+ # TODO: move this to a helper function
105
+ run_link = run.dir.parent / "latest" # TODO: Create relative symlink using os.path.relpath for portability
106
+ if os.path.islink(run_link):
107
+ os.unlink(run_link)
108
+ os.symlink(run.dir, run_link)
109
+ return run
110
+
111
+ # def update_run(self): # TODO TODO
112
+ # pass
113
+
114
+ def get_reports(self):
115
+ """Returns a full report which includes all runs in this session."""
116
+ if self.report:
117
+ return self.report
118
+
119
+ reports = [run.get_report() for run in self.runs]
120
+ merged = Report()
121
+ merged.add(reports)
122
+ return merged
123
+
124
+ def enumerate_runs(self):
125
+ """Update run indices."""
126
+ # Find start index
127
+ max_idx = -1
128
+ for run in self.runs:
129
+ if run.archived:
130
+ max_idx = max(max_idx, run.idx)
131
+ run_idx = max_idx + 1
132
+ for run in self.runs:
133
+ if not run.archived:
134
+ run.idx = run_idx
135
+ run.init_directory()
136
+ run_idx += 1
137
+ self.next_run_idx = run_idx
138
+
139
+ def request_run_idx(self):
140
+ """Return next free run index."""
141
+ ret = self.next_run_idx
142
+ self.next_run_idx += 1
143
+ # TODO: find a better approach for this
144
+ return ret
145
+
146
+ def process_runs(
147
+ self,
148
+ until=RunStage.DONE,
149
+ per_stage=False,
150
+ print_report=False,
151
+ num_workers=1,
152
+ progress=False,
153
+ export=False,
154
+ context=None,
155
+ ):
156
+ """Process a runs in this session until a given stage."""
157
+
158
+ # TODO: Add configurable callbacks for stage/run complete
159
+
160
+ self.enumerate_runs()
161
+ self.report = None
162
+ assert num_workers > 0, "num_workers can not be < 1"
163
+ workers = []
164
+ # results = []
165
+ workers = []
166
+ pbar = None # Outer progress bar
167
+ pbar2 = None # Inner progress bar
168
+ num_runs = len(self.runs)
169
+ num_failures = 0
170
+ stage_failures = {}
171
+ worker_run_idx = []
172
+
173
+ def _init_progress(total, msg="Processing..."):
174
+ """Helper function to initialize a progress bar for the session."""
175
+ return tqdm(
176
+ total=total,
177
+ desc=msg,
178
+ ncols=100,
179
+ bar_format="{l_bar}{bar}| {n_fmt}/{total_fmt} [{elapsed}s]",
180
+ leave=None,
181
+ )
182
+
183
+ def _update_progress(pbar, count=1):
184
+ """Helper function to update the progress bar for the session."""
185
+ pbar.update(count)
186
+
187
+ def _close_progress(pbar):
188
+ """Helper function to close the session progressbar, if available."""
189
+ if pbar:
190
+ pbar.close()
191
+
192
+ def _process(pbar, run, until, skip):
193
+ """Helper function to invoke the run."""
194
+ run.process(until=until, skip=skip, export=export)
195
+ if progress:
196
+ _update_progress(pbar)
197
+
198
+ def _join_workers(workers):
199
+ """Helper function to collect all worker threads."""
200
+ nonlocal num_failures
201
+ results = []
202
+ for i, w in enumerate(workers):
203
+ try:
204
+ results.append(w.result())
205
+ except Exception as e:
206
+ logger.exception(e)
207
+ logger.error("An exception was thrown by a worker during simulation")
208
+ run_index = worker_run_idx[i]
209
+ run = self.runs[run_index]
210
+ if run.failing:
211
+ num_failures += 1
212
+ failed_stage = RunStage(run.next_stage).name
213
+ if failed_stage in stage_failures:
214
+ stage_failures[failed_stage].append(run_index)
215
+ else:
216
+ stage_failures[failed_stage] = [run_index]
217
+ if progress:
218
+ _close_progress(pbar)
219
+ return results
220
+
221
+ def _used_stages(runs, until):
222
+ """Determines the stages which are used by at least one run."""
223
+ used = []
224
+ for stage_index in list(range(RunStage.LOAD, until + 1)) + [RunStage.POSTPROCESS]:
225
+ stage = RunStage(stage_index)
226
+ if any(run.has_stage(stage) for run in runs):
227
+ used.append(stage)
228
+ return used
229
+
230
+ used_stages = _used_stages(self.runs, until)
231
+ skipped_stages = [stage for stage in RunStage if stage not in used_stages]
232
+
233
+ with concurrent.futures.ThreadPoolExecutor(num_workers) as executor:
234
+ if per_stage:
235
+ if progress:
236
+ pbar2 = _init_progress(len(used_stages), msg="Processing stages")
237
+ for stage in used_stages:
238
+ run_stage = RunStage(stage).name
239
+ if progress:
240
+ pbar = _init_progress(len(self.runs), msg=f"Processing stage {run_stage}")
241
+ else:
242
+ logger.info("%s Processing stage %s", self.prefix, run_stage)
243
+ for i, run in enumerate(self.runs):
244
+ if i == 0:
245
+ total_threads = min(len(self.runs), num_workers)
246
+ cpu_count = multiprocessing.cpu_count()
247
+ if (stage == RunStage.COMPILE) and run.compile_platform:
248
+ total_threads *= run.compile_platform.num_threads
249
+ if total_threads > 2 * cpu_count:
250
+ if pbar2:
251
+ print()
252
+ logger.warning(
253
+ "The chosen configuration leads to a maximum of %d threads being"
254
+ + " processed which heavily exceeds the available CPU resources (%d)."
255
+ + " It is recommended to lower the value of 'mlif.num_threads'!",
256
+ total_threads,
257
+ cpu_count,
258
+ )
259
+ if run.failing:
260
+ logger.warning("Skiping stage '%s' for failed run", run_stage)
261
+ else:
262
+ worker_run_idx.append(i)
263
+ workers.append(executor.submit(_process, pbar, run, until=stage, skip=skipped_stages))
264
+ _join_workers(workers)
265
+ workers = []
266
+ worker_run_idx = []
267
+ if progress:
268
+ _update_progress(pbar2)
269
+ if progress:
270
+ _close_progress(pbar2)
271
+ else:
272
+ if progress:
273
+ pbar = _init_progress(len(self.runs), msg="Processing all runs")
274
+ else:
275
+ logger.info(self.prefix + "Processing all stages")
276
+ for i, run in enumerate(self.runs):
277
+ if i == 0:
278
+ total_threads = min(len(self.runs), num_workers)
279
+ cpu_count = multiprocessing.cpu_count()
280
+ if (until >= RunStage.COMPILE) and run.compile_platform.name == "mlif":
281
+ total_threads *= (
282
+ run.compile_platform.num_threads
283
+ ) # TODO: This should also be used for non-mlif platforms
284
+ if total_threads > 2 * cpu_count:
285
+ if pbar2:
286
+ print()
287
+ logger.warning(
288
+ "The chosen configuration leads to a maximum of %d being processed which"
289
+ + " heavily exceeds the available CPU resources (%d)."
290
+ + " It is recommended to lower the value of 'mlif.num_threads'!",
291
+ total_threads,
292
+ cpu_count,
293
+ )
294
+ worker_run_idx.append(i)
295
+ workers.append(executor.submit(_process, pbar, run, until=until, skip=skipped_stages))
296
+ _join_workers(workers)
297
+ if num_failures == 0:
298
+ logger.info("All runs completed successfuly!")
299
+ elif num_failures == num_runs:
300
+ logger.error("All runs have failed to complete!")
301
+ else:
302
+ num_success = num_runs - num_failures
303
+ logger.warning("%d out or %d runs completed successfully!", num_success, num_runs)
304
+ summary = "\n".join(
305
+ [
306
+ f"\t{stage}: \t{len(failed)} failed run(s): " + " ".join([str(idx) for idx in failed])
307
+ for stage, failed in stage_failures.items()
308
+ if len(failed) > 0
309
+ ]
310
+ )
311
+ logger.info("Summary:\n%s", summary)
312
+
313
+ report = self.get_reports()
314
+ logger.info("Postprocessing session report")
315
+ # Warning: currently we only support one instance of the same type of postprocess,
316
+ # also it will be applied to all rows!
317
+ session_postprocesses = []
318
+ for run in self.runs:
319
+ for postprocess in run.postprocesses:
320
+ if isinstance(postprocess, SessionPostprocess):
321
+ if postprocess.name not in [p.name for p in session_postprocesses]:
322
+ session_postprocesses.append(postprocess)
323
+ for postprocess in session_postprocesses:
324
+ artifacts = postprocess.post_session(report)
325
+ if artifacts is not None:
326
+ for artifact in artifacts:
327
+ # Postprocess has an artifact: write to disk!
328
+ logger.debug("Writting postprocess artifact to disk: %s", artifact.name)
329
+ artifact.export(self.dir)
330
+ report_file = Path(self.dir) / f"report.{self.report_fmt}"
331
+ report.export(report_file)
332
+ results_dir = context.environment.paths["results"].path
333
+ results_file = results_dir / f"{self.label}.{self.report_fmt}"
334
+ report.export(results_file)
335
+ logger.info(self.prefix + "Done processing runs")
336
+ self.report = report
337
+ if print_report:
338
+ logger.info("Report:\n%s", str(report.df))
339
+
340
+ return num_failures == 0
341
+
342
+ def discard(self):
343
+ """Discard a run and remove its directory."""
344
+ self.close()
345
+ if self.dir.is_dir():
346
+ logger.debug("Cleaning up discarded session")
347
+ shutil.rmtree(self.dir)
348
+
349
+ def __repr__(self):
350
+ return f"Session(idx={self.idx},status={self.status},runs={self.runs})"
351
+
352
+ @property
353
+ def active(self):
354
+ """Get active property."""
355
+ return self.status == SessionStatus.OPEN
356
+
357
+ def open(self):
358
+ """Open this run."""
359
+ self.status = SessionStatus.OPEN
360
+ self.opened_at = datetime.now()
361
+
362
+ def close(self, err=None):
363
+ """Close this run."""
364
+ if err:
365
+ self.status = SessionStatus.ERROR
366
+ else:
367
+ self.status = SessionStatus.CLOSED
368
+ self.closed_at = datetime.now()
369
+ if self.tempdir:
370
+ self.tempdir.cleanup()
371
+
372
+
373
+ # TODO: implement close()? and use closing contextlib? for tempdir
@@ -0,0 +1,18 @@
1
+ #
2
+ # Copyright (c) 2022 TUM Department of Electrical and Computer Engineering.
3
+ #
4
+ # This file is part of MLonMCU.
5
+ # See https://github.com/tum-ei-eda/mlonmcu.git for further info.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
mlonmcu/setup/cache.py ADDED
@@ -0,0 +1,147 @@
1
+ #
2
+ # Copyright (c) 2022 TUM Department of Electrical and Computer Engineering.
3
+ #
4
+ # This file is part of MLonMCU.
5
+ # See https://github.com/tum-ei-eda/mlonmcu.git for further info.
6
+ #
7
+ # Licensed under the Apache License, Version 2.0 (the "License");
8
+ # you may not use this file except in compliance with the License.
9
+ # You may obtain a copy of the License at
10
+ #
11
+ # http://www.apache.org/licenses/LICENSE-2.0
12
+ #
13
+ # Unless required by applicable law or agreed to in writing, software
14
+ # distributed under the License is distributed on an "AS IS" BASIS,
15
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
+ # See the License for the specific language governing permissions and
17
+ # limitations under the License.
18
+ #
19
+ """Definition of Taks Cache"""
20
+
21
+ import os
22
+ import configparser
23
+ from typing import Any
24
+
25
+
26
+ def convert_key(name):
27
+ if not isinstance(name, tuple):
28
+ name = (name, frozenset())
29
+ else:
30
+ assert len(name) == 2
31
+ if not isinstance(name[1], frozenset):
32
+ name = (name[0], frozenset(name[1]))
33
+ return name
34
+
35
+
36
+ class TaskCache:
37
+ """Task cache used to store dependency paths for the current and furture sessions.
38
+
39
+ This can be interpreted as a "modded" dictionary which takes a key + some flags.
40
+ """
41
+
42
+ def __init__(self):
43
+ self._vars = {}
44
+
45
+ def __repr__(self):
46
+ return str(self._vars)
47
+
48
+ def __setitem__(self, name, value):
49
+ name = convert_key(name)
50
+ self._vars[name[0]] = value # Holds latest value
51
+ self._vars[name] = value
52
+
53
+ def __getitem__(self, name):
54
+ name = convert_key(name)
55
+ return self._vars[name]
56
+
57
+ def __len__(self):
58
+ return len(self._vars)
59
+
60
+ def __contains__(self, name):
61
+ name = convert_key(name)
62
+ return name in self._vars.keys()
63
+
64
+ def find_best_match(self, name: str, flags=[]) -> Any:
65
+ """Utility whih tries to resolve the cache entry with the beste match.
66
+
67
+ Parameters
68
+ ----------
69
+ name : str
70
+ The cache-key.
71
+ flags : list
72
+ Optional flags used for the lookup.
73
+ """
74
+ # print("find_best_match", name, flags)
75
+ keys = self._vars.keys()
76
+ # print("keys", keys)
77
+ matches = []
78
+ counts = []
79
+ for key in keys:
80
+ if not isinstance(key, tuple):
81
+ continue
82
+ assert len(key) == 2
83
+ name_, flags_ = key[0], key[1]
84
+ if name == name_:
85
+ count = 0
86
+ for flag in flags_:
87
+ if flag not in flags:
88
+ count = -1 # incompatible
89
+ break
90
+ count = count + 1
91
+ if count >= 0:
92
+ matches.append(flags_)
93
+ counts.append(count)
94
+ if len(counts) == 0:
95
+ raise RuntimeError("Unable to find a match in the cache")
96
+ m = max(counts)
97
+ assert counts.count(m) == 1, f"For the given set of flags, there are multiple cache matches for the name {name}"
98
+ idx = counts.index(m)
99
+ flag = matches[idx]
100
+ ret = self._vars[name, flag]
101
+ return ret
102
+
103
+ def read_from_file(self, filename, reset=True):
104
+ if reset:
105
+ self._vars = {}
106
+ if not os.path.isfile(filename):
107
+ raise RuntimeError(f"File not found: {filename}")
108
+ cfg = configparser.ConfigParser()
109
+ cfg.read(filename)
110
+ sections = cfg.sections()
111
+ for section in sections:
112
+ if section == "default":
113
+ flags = set()
114
+ else:
115
+ flags = {flag for flag in section.split(",")}
116
+ content = dict(cfg[section].items())
117
+ for name, value in content.items():
118
+ self[name, flags] = value
119
+
120
+ def write_to_file(self, filename):
121
+ # d = self._vars
122
+
123
+ out = {} # This will be a dict of dicts
124
+ for key in self._vars:
125
+ # print(key, type(key))
126
+ if isinstance(key, str):
127
+ continue
128
+ name, flags = key[0], key[1]
129
+ value = self._vars[key]
130
+ if len(flags) == 0:
131
+ section_name = "default"
132
+ else:
133
+ section_name = ",".join(sorted(flags))
134
+ if section_name in out:
135
+ out[section_name][name] = value
136
+ else:
137
+ out[section_name] = {name: value}
138
+
139
+ with open(filename, "w") as cachefile:
140
+ cfg = configparser.ConfigParser()
141
+ if "default" in out: # Default section should be first
142
+ cfg["default"] = out["default"]
143
+ for x in out:
144
+ if x == "default":
145
+ continue
146
+ cfg[x] = out[x]
147
+ cfg.write(cachefile)