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.
- {codegreen-0.2.2 → codegreen-0.3.0}/CMakeLists.txt +63 -53
- {codegreen-0.2.2/codegreen.egg-info → codegreen-0.3.0}/PKG-INFO +22 -11
- {codegreen-0.2.2 → codegreen-0.3.0}/README.md +20 -10
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/__init__.py +1 -1
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/cli/cli.py +221 -44
- {codegreen-0.2.2 → codegreen-0.3.0/codegreen.egg-info}/PKG-INFO +22 -11
- {codegreen-0.2.2 → codegreen-0.3.0}/pyproject.toml +2 -1
- {codegreen-0.2.2 → codegreen-0.3.0}/LICENSE +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/MANIFEST.in +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/__init__.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/__main__.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/compilers.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/config.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/harness.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/profilers.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/results.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/suites/__init__.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/suites/base.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/suites/benchmarksgame.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/suites/perfopt.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/validation/__init__.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/validation/analysis.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/validation/experiments.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/benchmark/validation/reporting.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/__init__.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/_ts_java.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/cfg/__init__.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/cfg/builder.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/cfg/callgraph.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/cfg/dataflow.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/cfg/energy_flow.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/cfg/features.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/cfg/pdg.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/cfg/types.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analysis/cfg/visualization.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analyzer/__init__.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/analyzer/plot.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/cli/__init__.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/cli/entrypoint.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/config.json +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/__init__.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/ast_processor.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/bridge_analyze.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/bridge_instrument.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/config.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/configs/TEMPLATE.json +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/configs/c.json +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/configs/cpp.json +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/configs/java.json +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/configs/javascript.json +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/configs/python.json +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/engine.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/language_configs.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/language_engine.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/language_runtimes/c/codegreen_runtime.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/language_runtimes/cpp/codegreen/runtime.hpp +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/language_runtimes/java/codegreen/runtime/CodeGreenRuntime.java +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/language_runtimes/java/codegreen/runtime/CodeGreenStandaloneRuntime.java +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/instrumentation/language_runtimes/python/codegreen_runtime.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/utils/__init__.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/utils/binary.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen/utils/platform.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen.egg-info/SOURCES.txt +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen.egg-info/dependency_links.txt +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen.egg-info/entry_points.txt +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen.egg-info/not-zip-safe +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen.egg-info/requires.txt +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/codegreen.egg-info/top_level.txt +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/requirements.txt +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/setup.cfg +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/setup.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/tests/test_instrumentation.py +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/binarytrees/2.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/helloworld/1.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/knucleotide/1.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/mandelbrot/1-ffi.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/mandelbrot/1-mffi.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/nbody/2.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/nbody/5.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/nbody/8-i.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/nsieve/1.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/spectral-norm/3.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/spectral-norm/4.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/spectral-norm/5-im.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/Programming-Language-Benchmarks/bench/algorithm/spectral-norm/6-im.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/aligned_indent.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/array.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/comment.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/compound_lit.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/cond.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/enum.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/expr.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/func.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/if_else.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/issue-1568.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/issue-2086.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/issue-4079.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/issue-4117.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/issue-4525.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/label.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/loop.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/no_braces.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/preproc_cond.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/preproc_func.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/string.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/struct.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/switch.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/ternary.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/indent/c/unfinished_comment.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/nvim-treesitter/tests/query/highlights/c/enums-as-constants.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/crates/cli/src/templates/PARSER_NAME.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/crates/cli/src/templates/py-binding.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/crates/generate/src/templates/alloc.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/crates/generate/src/templates/array.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/crates/highlight/include/tree_sitter/highlight.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/crates/tags/include/tree_sitter/tags.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/CMakeLists.txt +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/binding_web/lib/tree-sitter.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/include/tree_sitter/api.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/alloc.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/alloc.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/array.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/atomic.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/clock.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/error_costs.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/get_changed_ranges.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/get_changed_ranges.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/host.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/language.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/language.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/length.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/lexer.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/lexer.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/lib.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/node.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/parser.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/parser.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/point.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/portable/endian.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/query.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/reduce_action.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/reusable_node.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/stack.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/stack.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/subtree.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/subtree.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/tree.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/tree.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/tree_cursor.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/tree_cursor.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/ts_assert.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/unicode/ptypes.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/unicode/umachine.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/unicode/urename.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/unicode/utf.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/unicode/utf16.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/unicode/utf8.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/unicode.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/wasm/stdlib.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/wasm/wasm-stdlib.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/wasm_store.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/lib/src/wasm_store.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/depends_on_column/scanner.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/epsilon_external_extra_tokens/scanner.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/epsilon_external_tokens/scanner.c +0 -0
- {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
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/external_and_internal_tokens/scanner.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/external_extra_tokens/scanner.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/external_tokens/scanner.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/external_unicode_column_alignment/scanner.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/get_col_eof/scanner.c +0 -0
- {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
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/inverted_external_token/scanner.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter/test/fixtures/test_grammars/uses_current_column/scanner.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/CMakeLists.txt +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/bindings/c/tree_sitter/tree-sitter-c.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/bindings/python/tree_sitter_c/binding.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/bindings/swift/TreeSitterC/c.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/examples/cluster.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/examples/malloc.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/examples/parser.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/src/parser.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/src/tree_sitter/alloc.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/src/tree_sitter/array.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/src/tree_sitter/parser.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/test/highlight/keywords.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-c/test/highlight/names.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-cpp/CMakeLists.txt +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-cpp/bindings/c/tree-sitter-cpp.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-cpp/bindings/python/tree_sitter_cpp/binding.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-cpp/bindings/swift/TreeSitterCPP/cpp.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-cpp/examples/marker-index.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-cpp/src/parser.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-cpp/src/scanner.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-cpp/src/tree_sitter/alloc.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-cpp/src/tree_sitter/array.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-cpp/src/tree_sitter/parser.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-java/CMakeLists.txt +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-java/bindings/c/tree-sitter-java.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-java/bindings/python/tree_sitter_java/binding.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-java/bindings/swift/TreeSitterJava/java.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-java/src/parser.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-java/src/tree_sitter/alloc.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-java/src/tree_sitter/array.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-java/src/tree_sitter/parser.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-python/CMakeLists.txt +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-python/bindings/c/tree-sitter-python.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-python/bindings/python/tree_sitter_python/binding.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-python/bindings/swift/TreeSitterPython/python.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-python/src/parser.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-python/src/scanner.c +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-python/src/tree_sitter/alloc.h +0 -0
- {codegreen-0.2.2 → codegreen-0.3.0}/third_party/tree-sitter-python/src/tree_sitter/array.h +0 -0
- {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
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
add_dependencies(codegreen sync_instrumentation)
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
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
|
-
|
|
247
|
-
|
|
248
|
-
|
|
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
|
-
#
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
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.
|
|
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
|
-
|
|
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
|
-
#
|
|
460
|
+
# Linux: RAPL sensor access (one-time, requires sudo):
|
|
460
461
|
sudo ./install.sh # or: sudo codegreen init-sensors
|
|
461
|
-
|
|
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
|
-
-
|
|
469
|
-
-
|
|
470
|
-
-
|
|
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 `
|
|
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 (`
|
|
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**:
|
|
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
|
-
|
|
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
|
-
#
|
|
29
|
+
# Linux: RAPL sensor access (one-time, requires sudo):
|
|
30
30
|
sudo ./install.sh # or: sudo codegreen init-sensors
|
|
31
|
-
|
|
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
|
-
-
|
|
39
|
-
-
|
|
40
|
-
-
|
|
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 `
|
|
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 (`
|
|
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**:
|
|
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.
|
|
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":
|
|
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
|
|
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 {
|
|
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,
|
|
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
|
-
|
|
2296
|
-
|
|
2297
|
-
|
|
2298
|
-
|
|
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
|
-
|
|
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]
|
|
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
|
-
|
|
2708
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
2720
|
-
total_energy_j = 0.0
|
|
2901
|
+
total_energy_j = energy_backend.parse_energy(energy_file)
|
|
2721
2902
|
try:
|
|
2722
|
-
|
|
2723
|
-
|
|
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}
|