codegreen 0.2.2__tar.gz → 0.3.0__tar.gz

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 (214) hide show
  1. {codegreen-0.2.2 → codegreen-0.3.0}/CMakeLists.txt +63 -53
  2. {codegreen-0.2.2/codegreen.egg-info → codegreen-0.3.0}/PKG-INFO +22 -11
  3. {codegreen-0.2.2 → codegreen-0.3.0}/README.md +20 -10
  4. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/__init__.py +1 -1
  5. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/cli/cli.py +221 -44
  6. {codegreen-0.2.2 → codegreen-0.3.0/codegreen.egg-info}/PKG-INFO +22 -11
  7. {codegreen-0.2.2 → codegreen-0.3.0}/pyproject.toml +2 -1
  8. {codegreen-0.2.2 → codegreen-0.3.0}/LICENSE +0 -0
  9. {codegreen-0.2.2 → codegreen-0.3.0}/MANIFEST.in +0 -0
  10. {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/__init__.py +0 -0
  11. {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/__main__.py +0 -0
  12. {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/compilers.py +0 -0
  13. {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/config.py +0 -0
  14. {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/harness.py +0 -0
  15. {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/profilers.py +0 -0
  16. {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/results.py +0 -0
  17. {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/suites/__init__.py +0 -0
  18. {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/suites/base.py +0 -0
  19. {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/suites/benchmarksgame.py +0 -0
  20. {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/suites/perfopt.py +0 -0
  21. {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/validation/__init__.py +0 -0
  22. {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/validation/analysis.py +0 -0
  23. {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/validation/experiments.py +0 -0
  24. {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/validation/reporting.py +0 -0
  25. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/__init__.py +0 -0
  26. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/_ts_java.py +0 -0
  27. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/cfg/__init__.py +0 -0
  28. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/cfg/builder.py +0 -0
  29. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/cfg/callgraph.py +0 -0
  30. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/cfg/dataflow.py +0 -0
  31. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/cfg/energy_flow.py +0 -0
  32. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/cfg/features.py +0 -0
  33. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/cfg/pdg.py +0 -0
  34. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/cfg/types.py +0 -0
  35. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/cfg/visualization.py +0 -0
  36. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analyzer/__init__.py +0 -0
  37. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analyzer/plot.py +0 -0
  38. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/cli/__init__.py +0 -0
  39. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/cli/entrypoint.py +0 -0
  40. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/config.json +0 -0
  41. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/__init__.py +0 -0
  42. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/ast_processor.py +0 -0
  43. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/bridge_analyze.py +0 -0
  44. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/bridge_instrument.py +0 -0
  45. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/config.py +0 -0
  46. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/configs/TEMPLATE.json +0 -0
  47. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/configs/c.json +0 -0
  48. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/configs/cpp.json +0 -0
  49. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/configs/java.json +0 -0
  50. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/configs/javascript.json +0 -0
  51. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/configs/python.json +0 -0
  52. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/engine.py +0 -0
  53. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/language_configs.py +0 -0
  54. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/language_engine.py +0 -0
  55. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/language_runtimes/c/codegreen_runtime.h +0 -0
  56. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/language_runtimes/cpp/codegreen/runtime.hpp +0 -0
  57. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/language_runtimes/java/codegreen/runtime/CodeGreenRuntime.java +0 -0
  58. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/language_runtimes/java/codegreen/runtime/CodeGreenStandaloneRuntime.java +0 -0
  59. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/language_runtimes/python/codegreen_runtime.py +0 -0
  60. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/utils/__init__.py +0 -0
  61. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/utils/binary.py +0 -0
  62. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/utils/platform.py +0 -0
  63. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen.egg-info/SOURCES.txt +0 -0
  64. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen.egg-info/dependency_links.txt +0 -0
  65. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen.egg-info/entry_points.txt +0 -0
  66. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen.egg-info/not-zip-safe +0 -0
  67. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen.egg-info/requires.txt +0 -0
  68. {codegreen-0.2.2 → codegreen-0.3.0}/codegreen.egg-info/top_level.txt +0 -0
  69. {codegreen-0.2.2 → codegreen-0.3.0}/requirements.txt +0 -0
  70. {codegreen-0.2.2 → codegreen-0.3.0}/setup.cfg +0 -0
  71. {codegreen-0.2.2 → codegreen-0.3.0}/setup.py +0 -0
  72. {codegreen-0.2.2 → codegreen-0.3.0}/tests/test_instrumentation.py +0 -0
  73. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/binarytrees/2.c +0 -0
  74. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/helloworld/1.c +0 -0
  75. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/knucleotide/1.c +0 -0
  76. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/mandelbrot/1-ffi.c +0 -0
  77. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/mandelbrot/1-mffi.c +0 -0
  78. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/nbody/2.c +0 -0
  79. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/nbody/5.c +0 -0
  80. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/nbody/8-i.c +0 -0
  81. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/nsieve/1.c +0 -0
  82. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/spectral-norm/3.c +0 -0
  83. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/spectral-norm/4.c +0 -0
  84. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/spectral-norm/5-im.c +0 -0
  85. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/spectral-norm/6-im.c +0 -0
  86. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/aligned_indent.c +0 -0
  87. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/array.c +0 -0
  88. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/comment.c +0 -0
  89. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/compound_lit.c +0 -0
  90. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/cond.c +0 -0
  91. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/enum.c +0 -0
  92. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/expr.c +0 -0
  93. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/func.c +0 -0
  94. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/if_else.c +0 -0
  95. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/issue-1568.c +0 -0
  96. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/issue-2086.c +0 -0
  97. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/issue-4079.c +0 -0
  98. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/issue-4117.c +0 -0
  99. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/issue-4525.c +0 -0
  100. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/label.c +0 -0
  101. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/loop.c +0 -0
  102. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/no_braces.c +0 -0
  103. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/preproc_cond.c +0 -0
  104. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/preproc_func.c +0 -0
  105. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/string.c +0 -0
  106. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/struct.c +0 -0
  107. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/switch.c +0 -0
  108. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/ternary.c +0 -0
  109. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/unfinished_comment.c +0 -0
  110. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/query/highlights/c/enums-as-constants.c +0 -0
  111. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/crates/cli/src/templates/PARSER_NAME.h +0 -0
  112. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/crates/cli/src/templates/py-binding.c +0 -0
  113. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/crates/generate/src/templates/alloc.h +0 -0
  114. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/crates/generate/src/templates/array.h +0 -0
  115. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/crates/highlight/include/tree_sitter/highlight.h +0 -0
  116. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/crates/tags/include/tree_sitter/tags.h +0 -0
  117. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/CMakeLists.txt +0 -0
  118. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/binding_web/lib/tree-sitter.c +0 -0
  119. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/include/tree_sitter/api.h +0 -0
  120. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/alloc.c +0 -0
  121. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/alloc.h +0 -0
  122. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/array.h +0 -0
  123. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/atomic.h +0 -0
  124. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/clock.h +0 -0
  125. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/error_costs.h +0 -0
  126. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/get_changed_ranges.c +0 -0
  127. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/get_changed_ranges.h +0 -0
  128. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/host.h +0 -0
  129. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/language.c +0 -0
  130. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/language.h +0 -0
  131. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/length.h +0 -0
  132. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/lexer.c +0 -0
  133. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/lexer.h +0 -0
  134. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/lib.c +0 -0
  135. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/node.c +0 -0
  136. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/parser.c +0 -0
  137. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/parser.h +0 -0
  138. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/point.h +0 -0
  139. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/portable/endian.h +0 -0
  140. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/query.c +0 -0
  141. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/reduce_action.h +0 -0
  142. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/reusable_node.h +0 -0
  143. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/stack.c +0 -0
  144. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/stack.h +0 -0
  145. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/subtree.c +0 -0
  146. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/subtree.h +0 -0
  147. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/tree.c +0 -0
  148. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/tree.h +0 -0
  149. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/tree_cursor.c +0 -0
  150. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/tree_cursor.h +0 -0
  151. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/ts_assert.h +0 -0
  152. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/unicode/ptypes.h +0 -0
  153. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/unicode/umachine.h +0 -0
  154. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/unicode/urename.h +0 -0
  155. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/unicode/utf.h +0 -0
  156. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/unicode/utf16.h +0 -0
  157. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/unicode/utf8.h +0 -0
  158. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/unicode.h +0 -0
  159. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/wasm/stdlib.c +0 -0
  160. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/wasm/wasm-stdlib.h +0 -0
  161. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/wasm_store.c +0 -0
  162. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/wasm_store.h +0 -0
  163. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/depends_on_column/scanner.c +0 -0
  164. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/epsilon_external_extra_tokens/scanner.c +0 -0
  165. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/epsilon_external_tokens/scanner.c +0 -0
  166. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/external_and_internal_anonymous_tokens/scanner.c +0 -0
  167. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/external_and_internal_tokens/scanner.c +0 -0
  168. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/external_extra_tokens/scanner.c +0 -0
  169. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/external_tokens/scanner.c +0 -0
  170. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/external_unicode_column_alignment/scanner.c +0 -0
  171. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/get_col_eof/scanner.c +0 -0
  172. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/get_col_should_hang_not_crash/scanner.c +0 -0
  173. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/inverted_external_token/scanner.c +0 -0
  174. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/uses_current_column/scanner.c +0 -0
  175. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/CMakeLists.txt +0 -0
  176. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/bindings/c/tree_sitter/tree-sitter-c.h +0 -0
  177. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/bindings/python/tree_sitter_c/binding.c +0 -0
  178. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/bindings/swift/TreeSitterC/c.h +0 -0
  179. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/examples/cluster.c +0 -0
  180. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/examples/malloc.c +0 -0
  181. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/examples/parser.c +0 -0
  182. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/src/parser.c +0 -0
  183. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/src/tree_sitter/alloc.h +0 -0
  184. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/src/tree_sitter/array.h +0 -0
  185. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/src/tree_sitter/parser.h +0 -0
  186. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/test/highlight/keywords.c +0 -0
  187. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/test/highlight/names.c +0 -0
  188. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-cpp/CMakeLists.txt +0 -0
  189. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-cpp/bindings/c/tree-sitter-cpp.h +0 -0
  190. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-cpp/bindings/python/tree_sitter_cpp/binding.c +0 -0
  191. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-cpp/bindings/swift/TreeSitterCPP/cpp.h +0 -0
  192. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-cpp/examples/marker-index.h +0 -0
  193. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-cpp/src/parser.c +0 -0
  194. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-cpp/src/scanner.c +0 -0
  195. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-cpp/src/tree_sitter/alloc.h +0 -0
  196. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-cpp/src/tree_sitter/array.h +0 -0
  197. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-cpp/src/tree_sitter/parser.h +0 -0
  198. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-java/CMakeLists.txt +0 -0
  199. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-java/bindings/c/tree-sitter-java.h +0 -0
  200. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-java/bindings/python/tree_sitter_java/binding.c +0 -0
  201. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-java/bindings/swift/TreeSitterJava/java.h +0 -0
  202. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-java/src/parser.c +0 -0
  203. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-java/src/tree_sitter/alloc.h +0 -0
  204. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-java/src/tree_sitter/array.h +0 -0
  205. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-java/src/tree_sitter/parser.h +0 -0
  206. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-python/CMakeLists.txt +0 -0
  207. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-python/bindings/c/tree-sitter-python.h +0 -0
  208. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-python/bindings/python/tree_sitter_python/binding.c +0 -0
  209. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-python/bindings/swift/TreeSitterPython/python.h +0 -0
  210. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-python/src/parser.c +0 -0
  211. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-python/src/scanner.c +0 -0
  212. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-python/src/tree_sitter/alloc.h +0 -0
  213. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-python/src/tree_sitter/array.h +0 -0
  214. {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-python/src/tree_sitter/parser.h +0 -0
@@ -120,37 +120,33 @@ endif()
120
120
  # Instrumentation is now Python-based, no C++ build needed
121
121
  # add_subdirectory(codegreen/instrumentation)
122
122
 
123
- # Main executable
124
- add_executable(codegreen
125
- codegreen/measurement/main.cpp
126
- )
127
-
128
- # Ensure instrumentation files are synced before building main executable
129
- add_dependencies(codegreen sync_instrumentation)
130
-
131
- # Link all libraries
132
- target_link_libraries(codegreen PRIVATE
133
- codegreen-core
134
- codegreen-nemb
135
- ${JSONCPP_LIBRARIES}
136
- ${CURL_LIBRARIES}
137
- Threads::Threads
138
- )
139
-
140
- target_include_directories(codegreen PRIVATE
141
- ${CMAKE_SOURCE_DIR}/codegreen/measurement/include
142
- ${CMAKE_SOURCE_DIR}/codegreen/instrumentation/include
143
- ${JSONCPP_INCLUDE_DIRS}
144
- ${CURL_INCLUDE_DIRS}
145
- )
146
-
147
- # Compiler-specific options
148
- if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
149
- target_compile_options(codegreen PRIVATE
150
- -Wall -Wextra -Wno-unused-parameter
151
- $<$<CONFIG:Debug>:-g -O0>
152
- $<$<CONFIG:Release>:-O3 -DNDEBUG>
123
+ # Main executable (requires jsoncpp/curl/sqlite -- Linux only)
124
+ # On macOS, only codegreen-nemb is built; the Python CLI handles everything.
125
+ if(NOT APPLE)
126
+ add_executable(codegreen
127
+ codegreen/measurement/main.cpp
128
+ )
129
+ add_dependencies(codegreen sync_instrumentation)
130
+ target_link_libraries(codegreen PRIVATE
131
+ codegreen-core
132
+ codegreen-nemb
133
+ ${JSONCPP_LIBRARIES}
134
+ ${CURL_LIBRARIES}
135
+ Threads::Threads
153
136
  )
137
+ target_include_directories(codegreen PRIVATE
138
+ ${CMAKE_SOURCE_DIR}/codegreen/measurement/include
139
+ ${CMAKE_SOURCE_DIR}/codegreen/instrumentation/include
140
+ ${JSONCPP_INCLUDE_DIRS}
141
+ ${CURL_INCLUDE_DIRS}
142
+ )
143
+ if(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
144
+ target_compile_options(codegreen PRIVATE
145
+ -Wall -Wextra -Wno-unused-parameter
146
+ $<$<CONFIG:Debug>:-g -O0>
147
+ $<$<CONFIG:Release>:-O3 -DNDEBUG>
148
+ )
149
+ endif()
154
150
  endif()
155
151
 
156
152
  # Copy runtime modules to build directory with dependency tracking
@@ -242,30 +238,44 @@ if(EXISTS "${CMAKE_SOURCE_DIR}/config/codegreen.json")
242
238
  )
243
239
  endif()
244
240
 
245
- # Installation
246
- install(TARGETS codegreen
247
- RUNTIME DESTINATION bin
248
- COMPONENT runtime
249
- )
241
+ # Installation (binary only on Linux where codegreen-core is built)
242
+ if(NOT APPLE)
243
+ install(TARGETS codegreen
244
+ RUNTIME DESTINATION bin
245
+ COMPONENT runtime
246
+ )
247
+ endif()
250
248
 
251
- # Create development bin directory and copy binary for CLI integration
252
- add_custom_target(dev-install ALL
253
- DEPENDS codegreen
254
- COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_SOURCE_DIR}/bin
255
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/codegreen ${CMAKE_SOURCE_DIR}/bin/
256
- COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_SOURCE_DIR}/lib
257
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/lib/libcodegreen-nemb${CMAKE_SHARED_LIBRARY_SUFFIX} ${CMAKE_SOURCE_DIR}/lib/
258
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/lib/libcodegreen-core.a ${CMAKE_SOURCE_DIR}/lib/
259
- COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_SOURCE_DIR}/bin/python/instrumentation
260
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/codegreen/instrumentation/bridge_analyze.py ${CMAKE_SOURCE_DIR}/bin/python/instrumentation/
261
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/codegreen/instrumentation/bridge_instrument.py ${CMAKE_SOURCE_DIR}/bin/python/instrumentation/
262
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/codegreen/instrumentation/language_engine.py ${CMAKE_SOURCE_DIR}/bin/python/instrumentation/
263
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/codegreen/instrumentation/ast_processor.py ${CMAKE_SOURCE_DIR}/bin/python/instrumentation/
264
- COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/codegreen/instrumentation/language_configs.py ${CMAKE_SOURCE_DIR}/bin/python/instrumentation/
265
- COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/codegreen/instrumentation/language_runtimes ${CMAKE_SOURCE_DIR}/bin/python/instrumentation/language_runtimes
266
- COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/codegreen/instrumentation/configs ${CMAKE_SOURCE_DIR}/bin/python/instrumentation/configs
267
- COMMENT "Copying binary and instrumentation files to development bin directory for CLI integration"
268
- )
249
+ # Dev-install: copy NEMB library + instrumentation files for local development
250
+ if(APPLE)
251
+ add_custom_target(dev-install ALL
252
+ DEPENDS codegreen-nemb
253
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_SOURCE_DIR}/lib
254
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/lib/libcodegreen-nemb.dylib ${CMAKE_SOURCE_DIR}/lib/
255
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_SOURCE_DIR}/bin/python/instrumentation
256
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/codegreen/instrumentation/language_runtimes ${CMAKE_SOURCE_DIR}/bin/python/instrumentation/language_runtimes
257
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/codegreen/instrumentation/configs ${CMAKE_SOURCE_DIR}/bin/python/instrumentation/configs
258
+ COMMENT "Dev-install: NEMB dylib + instrumentation (macOS)"
259
+ )
260
+ else()
261
+ add_custom_target(dev-install ALL
262
+ DEPENDS codegreen
263
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_SOURCE_DIR}/bin
264
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}/codegreen ${CMAKE_SOURCE_DIR}/bin/
265
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_SOURCE_DIR}/lib
266
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/lib/libcodegreen-nemb.so ${CMAKE_SOURCE_DIR}/lib/
267
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_BINARY_DIR}/lib/libcodegreen-core.a ${CMAKE_SOURCE_DIR}/lib/
268
+ COMMAND ${CMAKE_COMMAND} -E make_directory ${CMAKE_SOURCE_DIR}/bin/python/instrumentation
269
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/codegreen/instrumentation/bridge_analyze.py ${CMAKE_SOURCE_DIR}/bin/python/instrumentation/
270
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/codegreen/instrumentation/bridge_instrument.py ${CMAKE_SOURCE_DIR}/bin/python/instrumentation/
271
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/codegreen/instrumentation/language_engine.py ${CMAKE_SOURCE_DIR}/bin/python/instrumentation/
272
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/codegreen/instrumentation/ast_processor.py ${CMAKE_SOURCE_DIR}/bin/python/instrumentation/
273
+ COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_SOURCE_DIR}/codegreen/instrumentation/language_configs.py ${CMAKE_SOURCE_DIR}/bin/python/instrumentation/
274
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/codegreen/instrumentation/language_runtimes ${CMAKE_SOURCE_DIR}/bin/python/instrumentation/language_runtimes
275
+ COMMAND ${CMAKE_COMMAND} -E copy_directory ${CMAKE_SOURCE_DIR}/codegreen/instrumentation/configs ${CMAKE_SOURCE_DIR}/bin/python/instrumentation/configs
276
+ COMMENT "Dev-install: binary + NEMB + instrumentation (Linux)"
277
+ )
278
+ endif()
269
279
 
270
280
  # Install runtime modules
271
281
  install(FILES ${CMAKE_SOURCE_DIR}/codegreen/instrumentation/language_runtimes/python/codegreen_runtime.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: codegreen
3
- Version: 0.2.2
3
+ Version: 0.3.0
4
4
  Summary: Energy-aware software development tool for measuring and optimizing code energy consumption
5
5
  Author-email: Saurabhsingh Rajput <saurabh@dal.ca>
6
6
  Maintainer-email: Saurabhsingh Rajput <saurabh@dal.ca>
@@ -399,6 +399,7 @@ Classifier: Programming Language :: Python :: 3.12
399
399
  Classifier: Programming Language :: Python :: 3.13
400
400
  Classifier: Programming Language :: C++
401
401
  Classifier: Operating System :: POSIX :: Linux
402
+ Classifier: Operating System :: MacOS :: MacOS X
402
403
  Classifier: Environment :: Console
403
404
  Requires-Python: >=3.8
404
405
  Description-Content-Type: text/markdown
@@ -447,7 +448,7 @@ CodeGreen is a comprehensive tool for fine-grained energy profiling and optimiza
447
448
  pip install codegreen
448
449
  ```
449
450
 
450
- Requires Linux with RAPL support. The wheel includes the pre-built C++ measurement backend.
451
+ Pre-built wheels available for Linux x86_64 and macOS ARM64 (Apple Silicon). Includes the native NEMB energy measurement backend.
451
452
 
452
453
  ### From source (recommended for development)
453
454
 
@@ -456,18 +457,28 @@ git clone https://github.com/SMART-Dal/codegreen.git
456
457
  cd codegreen
457
458
  ./install.sh
458
459
 
459
- # For RAPL sensor access (one-time, requires sudo):
460
+ # Linux: RAPL sensor access (one-time, requires sudo):
460
461
  sudo ./install.sh # or: sudo codegreen init-sensors
461
- # Then log out and back in for group permissions
462
+
463
+ # macOS: energy measurement requires sudo (IOReport access):
464
+ sudo codegreen run -- python script.py
462
465
  ```
463
466
 
467
+ ### Platform support
468
+
469
+ | Platform | pip install | Energy measurement | Backend |
470
+ |----------|------------|-------------------|---------|
471
+ | Linux x86_64 (Intel/AMD) | Pre-built wheel | Full | RAPL via NEMB |
472
+ | macOS ARM64 (Apple Silicon) | Pre-built wheel | Full | IOReport + kpc via NEMB |
473
+ | macOS Intel | From source | Full | IOReport via NEMB |
474
+ | Other | From source | Time-only | Fallback |
475
+
464
476
  ### Requirements
465
477
 
466
- - Linux (kernel 5.0+, Ubuntu 20.04+, Debian 11+, Fedora 35+, MacOS)
467
478
  - Python 3.9+
468
- - CMake 3.16+, g++ 9+ (for source builds only)
469
- - Intel or AMD CPU with RAPL support
470
- - `perf` (for `codegreen run` and benchmark validation)
479
+ - Linux: kernel 5.0+, Intel/AMD CPU with RAPL support
480
+ - macOS: Apple Silicon (M1-M5) or Intel, sudo for energy measurement
481
+ - Source builds: CMake 3.16+, C++17 compiler
471
482
 
472
483
  ## Usage
473
484
 
@@ -510,7 +521,7 @@ JSON (default for `--json`), CSV, Markdown table, and text summary. The JSON out
510
521
 
511
522
  ## Language support
512
523
 
513
- Adding a new language requires only a JSON config file in `src/instrumentation/configs/` plus the tree-sitter grammar. No Python code changes needed.
524
+ Adding a new language requires only a JSON config file in `codegreen/instrumentation/configs/` plus the tree-sitter grammar. No Python code changes needed.
514
525
 
515
526
  Currently supported: Python, C, C++, JavaScript, Java.
516
527
 
@@ -529,7 +540,7 @@ bash scripts/generate_comparison_artifacts.sh docs/benchmarks/
529
540
 
530
541
  ## Energy Flow Graph (EFG)
531
542
 
532
- CodeGreen includes an Energy Flow Graph module (`src/analysis/cfg/`) that builds energy-annotated control flow graphs from source code:
543
+ CodeGreen includes an Energy Flow Graph module (`codegreen/analysis/cfg/`) that builds energy-annotated control flow graphs from source code:
533
544
 
534
545
  ```python
535
546
  from codegreen.analysis.cfg.builder import build_per_method_cfgs
@@ -544,7 +555,7 @@ Features: Ball & Larus branch heuristics, SCC-based hot path computation, three-
544
555
 
545
556
  ## Architecture
546
557
 
547
- - **C++ NEMB backend**: RAPL energy reading with sub-microsecond timestamping, configurable polling interval
558
+ - **C++ NEMB backend**: platform-aware energy measurement (RAPL on Linux, IOReport on macOS), sub-microsecond timestamping, background polling with lock-free ring buffers
548
559
  - **Python instrumentation**: tree-sitter AST analysis, config-driven checkpoint insertion
549
560
  - **Energy Flow Graph**: CFG + energy annotation for path-dependent analysis
550
561
  - **Benchmark harness**: multi-suite support (benchmarksgame, PerfOpt), statistical analysis with t-distribution CI, IQR outlier detection, profiler comparison
@@ -17,7 +17,7 @@ CodeGreen is a comprehensive tool for fine-grained energy profiling and optimiza
17
17
  pip install codegreen
18
18
  ```
19
19
 
20
- Requires Linux with RAPL support. The wheel includes the pre-built C++ measurement backend.
20
+ Pre-built wheels available for Linux x86_64 and macOS ARM64 (Apple Silicon). Includes the native NEMB energy measurement backend.
21
21
 
22
22
  ### From source (recommended for development)
23
23
 
@@ -26,18 +26,28 @@ git clone https://github.com/SMART-Dal/codegreen.git
26
26
  cd codegreen
27
27
  ./install.sh
28
28
 
29
- # For RAPL sensor access (one-time, requires sudo):
29
+ # Linux: RAPL sensor access (one-time, requires sudo):
30
30
  sudo ./install.sh # or: sudo codegreen init-sensors
31
- # Then log out and back in for group permissions
31
+
32
+ # macOS: energy measurement requires sudo (IOReport access):
33
+ sudo codegreen run -- python script.py
32
34
  ```
33
35
 
36
+ ### Platform support
37
+
38
+ | Platform | pip install | Energy measurement | Backend |
39
+ |----------|------------|-------------------|---------|
40
+ | Linux x86_64 (Intel/AMD) | Pre-built wheel | Full | RAPL via NEMB |
41
+ | macOS ARM64 (Apple Silicon) | Pre-built wheel | Full | IOReport + kpc via NEMB |
42
+ | macOS Intel | From source | Full | IOReport via NEMB |
43
+ | Other | From source | Time-only | Fallback |
44
+
34
45
  ### Requirements
35
46
 
36
- - Linux (kernel 5.0+, Ubuntu 20.04+, Debian 11+, Fedora 35+, MacOS)
37
47
  - Python 3.9+
38
- - CMake 3.16+, g++ 9+ (for source builds only)
39
- - Intel or AMD CPU with RAPL support
40
- - `perf` (for `codegreen run` and benchmark validation)
48
+ - Linux: kernel 5.0+, Intel/AMD CPU with RAPL support
49
+ - macOS: Apple Silicon (M1-M5) or Intel, sudo for energy measurement
50
+ - Source builds: CMake 3.16+, C++17 compiler
41
51
 
42
52
  ## Usage
43
53
 
@@ -80,7 +90,7 @@ JSON (default for `--json`), CSV, Markdown table, and text summary. The JSON out
80
90
 
81
91
  ## Language support
82
92
 
83
- Adding a new language requires only a JSON config file in `src/instrumentation/configs/` plus the tree-sitter grammar. No Python code changes needed.
93
+ Adding a new language requires only a JSON config file in `codegreen/instrumentation/configs/` plus the tree-sitter grammar. No Python code changes needed.
84
94
 
85
95
  Currently supported: Python, C, C++, JavaScript, Java.
86
96
 
@@ -99,7 +109,7 @@ bash scripts/generate_comparison_artifacts.sh docs/benchmarks/
99
109
 
100
110
  ## Energy Flow Graph (EFG)
101
111
 
102
- CodeGreen includes an Energy Flow Graph module (`src/analysis/cfg/`) that builds energy-annotated control flow graphs from source code:
112
+ CodeGreen includes an Energy Flow Graph module (`codegreen/analysis/cfg/`) that builds energy-annotated control flow graphs from source code:
103
113
 
104
114
  ```python
105
115
  from codegreen.analysis.cfg.builder import build_per_method_cfgs
@@ -114,7 +124,7 @@ Features: Ball & Larus branch heuristics, SCC-based hot path computation, three-
114
124
 
115
125
  ## Architecture
116
126
 
117
- - **C++ NEMB backend**: RAPL energy reading with sub-microsecond timestamping, configurable polling interval
127
+ - **C++ NEMB backend**: platform-aware energy measurement (RAPL on Linux, IOReport on macOS), sub-microsecond timestamping, background polling with lock-free ring buffers
118
128
  - **Python instrumentation**: tree-sitter AST analysis, config-driven checkpoint insertion
119
129
  - **Energy Flow Graph**: CFG + energy annotation for path-dependent analysis
120
130
  - **Benchmark harness**: multi-suite support (benchmarksgame, PerfOpt), statistical analysis with t-distribution CI, IQR outlier detection, profiler comparison
@@ -5,7 +5,7 @@ A comprehensive energy measurement and code optimization tool for developers
5
5
  and researchers who need precise, fine-grained energy consumption analysis.
6
6
  """
7
7
 
8
- __version__ = "0.2.2"
8
+ __version__ = "0.3.0"
9
9
  __author__ = "Saurabhsingh Rajput"
10
10
  __email__ = "saurabh@dal.ca"
11
11
  __description__ = "Energy-aware software development tool"
@@ -35,6 +35,7 @@ except ImportError:
35
35
  import typer
36
36
  from rich.console import Console
37
37
  from rich.panel import Panel
38
+ from codegreen import __version__ as _VERSION
38
39
  from rich.text import Text
39
40
  from rich.table import Table
40
41
  from rich.progress import Progress, SpinnerColumn, TextColumn
@@ -531,7 +532,7 @@ def generate_optimized_config(
531
532
  "timestamp": datetime.now().isoformat(),
532
533
  "environment_type": environment_info["type"],
533
534
  "detected_sensors": list(sensor_info.keys()),
534
- "version": "0.1.0"
535
+ "version": _VERSION
535
536
  }
536
537
 
537
538
  # Environment-specific optimizations
@@ -699,7 +700,7 @@ def main(
699
700
  - [dim]codegreen config --show[/dim] - View/edit configuration
700
701
  """
701
702
  if version:
702
- console.print("[bold green]CodeGreen version 0.1.0[/bold green]")
703
+ console.print(f"[bold green]CodeGreen version {_VERSION}[/bold green]")
703
704
  raise typer.Exit()
704
705
 
705
706
  # If no command is provided and version is not requested, show help
@@ -1700,7 +1701,7 @@ def show_info(
1700
1701
  # Package information
1701
1702
  try:
1702
1703
  import codegreen
1703
- table.add_row("Version", "[ok]", f"CodeGreen {codegreen.__version__}")
1704
+ table.add_row("Version", "[ok]", f"CodeGreen {_VERSION}")
1704
1705
  except:
1705
1706
  table.add_row("Version", "-", "Unknown")
1706
1707
 
@@ -2272,49 +2273,40 @@ def run_command(
2272
2273
  - codegreen run --repeat 20 ./my_binary arg1 arg2
2273
2274
  - codegreen run --budget 10.0 python train.py
2274
2275
  """
2275
- import subprocess, time, re, tempfile, math
2276
+ import subprocess, time, math
2276
2277
  from benchmark.results import StatisticalAnalysis
2277
2278
 
2279
+ backend = _get_energy_backend()
2280
+ if not json_output:
2281
+ console.print(f"[dim]Energy backend: {backend.name}[/dim]")
2282
+
2278
2283
  for i in range(warmup):
2279
2284
  if not json_output:
2280
2285
  console.print(f"[dim]Warmup {i+1}/{warmup}[/dim]")
2281
2286
  subprocess.run(command, capture_output=True, timeout=300)
2282
2287
 
2283
- events = "power/energy-pkg/"
2284
- try:
2285
- r = subprocess.run(["perf", "list", "power"], capture_output=True, text=True, timeout=5)
2286
- if "energy-ram" in r.stdout:
2287
- events += ",power/energy-ram/"
2288
- except Exception:
2289
- pass
2290
-
2291
2288
  energies, times = [], []
2292
2289
  for i in range(repeat):
2293
2290
  if not json_output:
2294
2291
  console.print(f"[dim]Run {i+1}/{repeat}[/dim]")
2295
- with tempfile.NamedTemporaryFile(suffix='.txt', delete=False) as f:
2296
- perf_file = f.name
2297
- try:
2298
- full = ["perf", "stat", "-e", events, "-o", perf_file, "--"] + command
2299
- start = time.perf_counter()
2300
- subprocess.run(full, capture_output=True, text=True, timeout=300)
2301
- elapsed = time.perf_counter() - start
2302
- times.append(elapsed)
2303
- content = open(perf_file).read()
2304
- total = 0.0
2305
- for m in re.finditer(r'([\d.,]+)\s+Joules', content):
2306
- total += float(m.group(1).replace(',', ''))
2307
- if total > 0:
2308
- energies.append(total)
2309
- finally:
2310
- import os
2311
- os.unlink(perf_file)
2292
+ energy_j, elapsed = backend.measure(command)
2293
+ times.append(elapsed)
2294
+ if energy_j is not None and energy_j > 0:
2295
+ energies.append(energy_j)
2312
2296
 
2313
2297
  if not energies:
2298
+ msg = f"No energy data from {backend.name}"
2299
+ if isinstance(backend, _TimeOnlyBackend):
2300
+ msg += " (need perf on Linux or sudo powermetrics on macOS)"
2314
2301
  if json_output:
2315
- print(json.dumps({"success": False, "error": "No energy data (RAPL unavailable?)"}))
2302
+ t_mean = sum(times) / len(times) if times else 0
2303
+ print(json.dumps({"success": False, "error": msg,
2304
+ "time_seconds": {"mean": t_mean}}))
2316
2305
  else:
2317
- console.print("[red]No energy data collected. Is RAPL accessible?[/red]")
2306
+ console.print(f"[red]{msg}[/red]")
2307
+ if times:
2308
+ t_stats = StatisticalAnalysis.summarize(times)
2309
+ console.print(f"[bold]Time:[/bold] {t_stats.mean:.4f} s +/- {t_stats.std:.4f} s")
2318
2310
  raise typer.Exit(1)
2319
2311
 
2320
2312
  e_stats = StatisticalAnalysis.summarize(energies)
@@ -2342,6 +2334,197 @@ def run_command(
2342
2334
  console.print(f"[green]Within budget: {e_stats.mean:.4f}J <= {budget}J[/green]")
2343
2335
 
2344
2336
 
2337
+ class _EnergyBackend:
2338
+ """Base class for CLI energy measurement backends.
2339
+ Open/closed: add new hardware support by subclassing and appending to _ENERGY_BACKENDS.
2340
+ No file I/O during measurement -- all data via in-memory APIs or pipes."""
2341
+ name: str = "unknown"
2342
+ priority: int = 0 # higher = preferred
2343
+ def is_available(self) -> bool: return False
2344
+ def measure(self, command: list, timeout: int = 300) -> tuple:
2345
+ """Returns (energy_joules or None, elapsed_seconds)."""
2346
+ raise NotImplementedError
2347
+ def wrap_command(self, cmd_str: str, energy_file: str, checkpoint_file: str) -> str:
2348
+ """Wrap a shell command for energy + checkpoint capture (project mode)."""
2349
+ return f"bash -c '{cmd_str} 2>{checkpoint_file}'"
2350
+ def parse_energy(self, energy_file: str) -> float:
2351
+ """Parse energy from output file (project mode only). Returns joules or 0."""
2352
+ return 0.0
2353
+
2354
+
2355
+ class _NEMBBackend(_EnergyBackend):
2356
+ """In-process NEMB measurement via ctypes. Zero file I/O during measurement.
2357
+ Uses the same background polling + ring buffer architecture as fine-grained mode."""
2358
+ name = "NEMB (native energy measurement)"
2359
+ priority = 100
2360
+ _lib = None
2361
+
2362
+ def _load(self):
2363
+ if self._lib is not None:
2364
+ return self._lib
2365
+ import ctypes
2366
+ pkg_root = Path(__file__).resolve().parent.parent
2367
+ for name in ["libcodegreen-nemb.dylib", "libcodegreen-nemb.so"]:
2368
+ for d in [pkg_root / "lib", pkg_root.parent / "lib", pkg_root.parent / "build" / "lib"]:
2369
+ p = d / name
2370
+ if p.exists():
2371
+ try:
2372
+ self._lib = ctypes.CDLL(str(p))
2373
+ return self._lib
2374
+ except OSError:
2375
+ pass
2376
+ self._lib = False
2377
+ return False
2378
+
2379
+ def is_available(self) -> bool:
2380
+ lib = self._load()
2381
+ if not lib:
2382
+ return False
2383
+ import ctypes
2384
+ try:
2385
+ lib.nemb_initialize.restype = ctypes.c_int
2386
+ return lib.nemb_initialize() == 1
2387
+ except Exception:
2388
+ return False
2389
+
2390
+ def measure(self, command: list, timeout: int = 300) -> tuple:
2391
+ import ctypes, subprocess, time
2392
+ lib = self._load()
2393
+ lib.nemb_start_session.restype = ctypes.c_uint64
2394
+ lib.nemb_start_session.argtypes = [ctypes.c_char_p]
2395
+ lib.nemb_stop_session.restype = ctypes.c_int
2396
+ lib.nemb_stop_session.argtypes = [ctypes.c_uint64, ctypes.POINTER(ctypes.c_double), ctypes.POINTER(ctypes.c_double)]
2397
+
2398
+ sid = lib.nemb_start_session(b"run")
2399
+ start = time.perf_counter()
2400
+ subprocess.run(command, capture_output=True, timeout=timeout)
2401
+ elapsed = time.perf_counter() - start
2402
+ energy = ctypes.c_double(0)
2403
+ power = ctypes.c_double(0)
2404
+ ok = lib.nemb_stop_session(sid, ctypes.byref(energy), ctypes.byref(power))
2405
+ return (energy.value if ok and energy.value > 0 else None, elapsed)
2406
+
2407
+ def wrap_command(self, cmd_str: str, energy_file: str, checkpoint_file: str) -> str:
2408
+ # NEMB wraps via the codegreen binary which handles measurement internally
2409
+ binary = get_binary_path()
2410
+ if binary:
2411
+ return f"{binary} measure-workload --output {energy_file} -- bash -c '{cmd_str} 2>{checkpoint_file}'"
2412
+ return f"bash -c '{cmd_str} 2>{checkpoint_file}'"
2413
+
2414
+ def parse_energy(self, energy_file: str) -> float:
2415
+ try:
2416
+ d = json.loads(open(energy_file).read())
2417
+ return d.get("summary", {}).get("total_energy_j", 0.0)
2418
+ except Exception:
2419
+ return 0.0
2420
+
2421
+
2422
+ class _PerfBackend(_EnergyBackend):
2423
+ name = "perf (Linux RAPL)"
2424
+ priority = 50
2425
+ def is_available(self) -> bool:
2426
+ import shutil
2427
+ return sys.platform == "linux" and shutil.which("perf") is not None
2428
+ def _events(self) -> str:
2429
+ import subprocess
2430
+ events = "power/energy-pkg/"
2431
+ try:
2432
+ r = subprocess.run(["perf", "list", "power"], capture_output=True, text=True, timeout=5)
2433
+ if "energy-ram" in r.stdout:
2434
+ events += ",power/energy-ram/"
2435
+ except Exception:
2436
+ pass
2437
+ return events
2438
+ def measure(self, command: list, timeout: int = 300) -> tuple:
2439
+ import subprocess, time, tempfile, os
2440
+ with tempfile.NamedTemporaryFile(suffix='.txt', delete=False) as f:
2441
+ pf = f.name
2442
+ try:
2443
+ full = ["perf", "stat", "-e", self._events(), "-o", pf, "--"] + command
2444
+ start = time.perf_counter()
2445
+ subprocess.run(full, capture_output=True, text=True, timeout=timeout)
2446
+ elapsed = time.perf_counter() - start
2447
+ energy = self.parse_energy(pf)
2448
+ return (energy if energy > 0 else None, elapsed)
2449
+ finally:
2450
+ os.unlink(pf)
2451
+ def wrap_command(self, cmd_str: str, perf_file: str, checkpoint_file: str) -> str:
2452
+ return f"perf stat -e {self._events()} -o {perf_file} -- bash -c '{cmd_str} 2>{checkpoint_file}'"
2453
+ def parse_energy(self, perf_file: str) -> float:
2454
+ import re
2455
+ try:
2456
+ content = open(perf_file).read()
2457
+ total = 0.0
2458
+ for m in re.finditer(r'([\d.,]+)\s+Joules', content):
2459
+ total += float(m.group(1).replace(',', ''))
2460
+ return total
2461
+ except Exception:
2462
+ return 0.0
2463
+
2464
+
2465
+ class _PowermetricsBackend(_EnergyBackend):
2466
+ name = "powermetrics (macOS IOReport)"
2467
+ priority = 30
2468
+ def is_available(self) -> bool:
2469
+ import shutil
2470
+ return sys.platform == "darwin" and shutil.which("powermetrics") is not None
2471
+ def measure(self, command: list, timeout: int = 300) -> tuple:
2472
+ import subprocess, time, tempfile, os, re
2473
+ with tempfile.NamedTemporaryFile(suffix='.txt', delete=False) as f:
2474
+ pm_file = f.name
2475
+ try:
2476
+ proc = subprocess.Popen(
2477
+ ["sudo", "-n", "powermetrics", "--samplers", "cpu_power",
2478
+ "-i", "100", "-o", pm_file],
2479
+ stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
2480
+ time.sleep(0.2)
2481
+ start = time.perf_counter()
2482
+ subprocess.run(command, capture_output=True, timeout=timeout)
2483
+ elapsed = time.perf_counter() - start
2484
+ time.sleep(0.3)
2485
+ proc.terminate()
2486
+ try: proc.wait(timeout=5)
2487
+ except: proc.kill()
2488
+ mw_samples = []
2489
+ try:
2490
+ for line in open(pm_file):
2491
+ if "Combined Power" in line or "CPU Power" in line:
2492
+ import re as _re
2493
+ m = _re.search(r'(\d+)\s*mW', line)
2494
+ if m: mw_samples.append(int(m.group(1)))
2495
+ except Exception:
2496
+ pass
2497
+ if mw_samples:
2498
+ return ((sum(mw_samples) / len(mw_samples) / 1000.0) * elapsed, elapsed)
2499
+ return (None, elapsed)
2500
+ finally:
2501
+ os.unlink(pm_file)
2502
+ def wrap_command(self, cmd_str: str, perf_file: str, checkpoint_file: str) -> str:
2503
+ return f"bash -c '{cmd_str} 2>{checkpoint_file}'"
2504
+
2505
+
2506
+ class _TimeOnlyBackend(_EnergyBackend):
2507
+ name = "time-only (no energy)"
2508
+ def is_available(self) -> bool: return True
2509
+ def measure(self, command: list, timeout: int = 300) -> tuple:
2510
+ import subprocess, time
2511
+ start = time.perf_counter()
2512
+ subprocess.run(command, capture_output=True, timeout=timeout)
2513
+ return (None, time.perf_counter() - start)
2514
+
2515
+
2516
+ _ENERGY_BACKENDS = [_NEMBBackend(), _PerfBackend(), _PowermetricsBackend(), _TimeOnlyBackend()]
2517
+
2518
+ def _get_energy_backend() -> _EnergyBackend:
2519
+ """Auto-detect best available energy backend, sorted by priority.
2520
+ NEMB (100) > perf (50) > powermetrics (30) > time_only (0).
2521
+ Extensible: add new backends to _ENERGY_BACKENDS."""
2522
+ for b in sorted(_ENERGY_BACKENDS, key=lambda x: x.priority, reverse=True):
2523
+ if b.is_available():
2524
+ return b
2525
+ return _TimeOnlyBackend()
2526
+
2527
+
2345
2528
  def _load_language_config(language: str) -> dict:
2346
2529
  """Load language config JSON. Single source of truth for language-specific settings."""
2347
2530
  config_dir = Path(__file__).resolve().parent.parent / "instrumentation" / "configs"
@@ -2704,28 +2887,22 @@ def project_energy(
2704
2887
  if cores:
2705
2888
  full_cmd = f"taskset -c {cores} {full_cmd}"
2706
2889
 
2707
- # Run with perf stat for total energy + capture stderr for checkpoints
2708
- perf_file = tempfile.NamedTemporaryFile(suffix='.txt', delete=False).name
2890
+ energy_backend = _get_energy_backend()
2891
+ energy_file = tempfile.NamedTemporaryFile(suffix='.txt', delete=False).name
2709
2892
  checkpoint_file = tempfile.NamedTemporaryFile(suffix='.txt', delete=False).name
2710
2893
 
2711
- # Run: perf stat wrapping the command, stderr goes to checkpoint_file
2712
- perf_cmd = f"perf stat -e power/energy-pkg/ -o {perf_file} -- bash -c '{full_cmd} 2>{checkpoint_file}'"
2894
+ wrapped = energy_backend.wrap_command(full_cmd, energy_file, checkpoint_file)
2713
2895
  start_time = time.perf_counter()
2714
2896
  run_result = subprocess.run(
2715
- perf_cmd, shell=True, cwd=str(project_dir),
2897
+ wrapped, shell=True, cwd=str(project_dir),
2716
2898
  capture_output=True, text=True, timeout=3600)
2717
2899
  wall_time = time.perf_counter() - start_time
2718
2900
 
2719
- # Parse perf stat for total energy
2720
- total_energy_j = 0.0
2901
+ total_energy_j = energy_backend.parse_energy(energy_file)
2721
2902
  try:
2722
- perf_content = open(perf_file).read()
2723
- for m in re.finditer(r'([\d.,]+)\s+Joules', perf_content):
2724
- total_energy_j += float(m.group(1).replace(',', ''))
2725
- except Exception:
2903
+ os.unlink(energy_file)
2904
+ except OSError:
2726
2905
  pass
2727
- finally:
2728
- os.unlink(perf_file)
2729
2906
 
2730
2907
  # Parse checkpoints with per-thread call stacks for inclusive/exclusive
2731
2908
  func_data = {} # name -> {inclusive_uj, exclusive_uj, time_ns, calls}