diff --git a/results/trip_count/milp.csv b/results/trip_count/milp.csv new file mode 100644 index 00000000..c5024570 --- /dev/null +++ b/results/trip_count/milp.csv @@ -0,0 +1,14 @@ +benchmark,capacitor,status,basic_blocks,edges,abstract_cfg_blocks,abstract_cfg_edges,region_boundaries,compilation_time_ms,peak_rss_kb,profiling_time_ms,execution_time_us,runtime_region_boundary_calls,runtime_debug_store_mem_calls,runtime_debug_restore_mem_calls,candidate_globals,milp_allocation_mode,milp_variables,milp_constraints,milp_presolved_variables,milp_presolved_constraints,optimal_solution,distributed_checkpoints_inserted,vm_placed_globals,vm_placed_global_names,milp_solve_time_ms,result,run_attempts +activity_recognition-10uF,10uF,ok,16,22,8,9,4,45,40640,439,34048.7,13,0,0,9,regional,533,1986,147,323,yes,6,8,lfsr_state:4;__local_main.features.i.sroa.0:4;__local_main.features.i.sroa.4:4;__local_main.features.i4.sroa.0:4;__local_main.features.i4.sroa.4:4;__local_main.stats.sroa.0.i:8;__local_main.features.i13.sroa.0:4;__local_main.features.i13.sroa.5:4,26,64,1 +aes-10uF,10uF,ok,26,35,9,10,4,208,48624,559,104854.28,20,0,0,3,regional,2475,10033,61,133,yes,49,0,,26,107,1 +bitcount-10uF,10uF,ok,64,95,52,75,22,400,77056,488,6178386.14,80096,0,0,2,regional,8126,35533,1885,5944,yes,49,0,,230,52382,1 +chacha20-10uF,10uF,ok,11,15,4,4,2,26,37632,536,50559.28,8,0,0,3,regional,495,1907,23,46,yes,30,0,,4,79,1 +crc-10uF,10uF,ok,9,12,6,6,3,10,35936,423,29828.77,5,0,0,2,regional,117,414,18,37,yes,0,1,__local_main.result:6,3,20431,1 +cuckoo_filter-10uF,10uF,ok,23,33,15,20,4,203,47840,536,72434.9,2052,0,0,3,regional,1009,4162,344,951,yes,12,0,,166,4048,1 +dijkstra-10uF,10uF,ok,17,24,11,15,7,138,44768,429,1126514.82,3787,0,0,5,regional,1229,4972,223,550,yes,48,1,__local_main.nodes.i:5,99,33447,1 +poly1305-10uF,10uF,ok,7,9,4,4,2,19,36880,472,478591.92,86,0,0,3,regional,559,2135,31,68,yes,0,0,,4,68,1 +qsort-10uF,10uF,ok,17,24,12,15,5,18,37776,421,1091951.53,643,0,0,2,regional,324,1264,36,75,yes,7,0,,6,27023,1 +rsa-10uF,10uF,ok,144,209,86,119,43,4652,146896,658,74903.7,324,0,0,8,regional,21292,91133,3214,9905,yes,59,3,g_product:54;__local_main.qn_arr.i:11;__local_main.qn_arr.i34:8,4182,32,1 +sensor_fusion-10uF,10uF,ok,177,268,4,4,2,18,38944,419,25604.81,17,0,0,2,regional,431,1696,17,34,yes,0,1,g_output:4,5,613,1 +sha256-10uF,10uF,ok,38,54,14,18,6,164,58848,399,94440.73,18,0,0,6,regional,4083,16818,307,830,yes,79,0,,89,131,1 +stringsearch-10uF,10uF,ok,41,58,31,43,12,545,61632,556,82545.06,2270,0,0,4,regional,2200,9143,1070,3127,yes,21,3,__local_main.total_found:7;len:7;findme:7,473,20,1 diff --git a/results/trip_count/milp_debug.csv b/results/trip_count/milp_debug.csv new file mode 100644 index 00000000..4f567f34 --- /dev/null +++ b/results/trip_count/milp_debug.csv @@ -0,0 +1,14 @@ +benchmark,capacitor,status,basic_blocks,edges,abstract_cfg_blocks,abstract_cfg_edges,region_boundaries,compilation_time_ms,peak_rss_kb,profiling_time_ms,execution_time_us,runtime_region_boundary_calls,runtime_debug_store_mem_calls,runtime_debug_restore_mem_calls,candidate_globals,milp_allocation_mode,milp_variables,milp_constraints,milp_presolved_variables,milp_presolved_constraints,optimal_solution,distributed_checkpoints_inserted,vm_placed_globals,vm_placed_global_names,milp_solve_time_ms,result,run_attempts +activity_recognition-10uF,10uF,ok,16,22,8,9,4,38,40624,381,34054.13,13,0,0,9,regional,533,1986,147,323,yes,6,8,lfsr_state:4;__local_main.features.i.sroa.0:4;__local_main.features.i.sroa.4:4;__local_main.features.i4.sroa.0:4;__local_main.features.i4.sroa.4:4;__local_main.stats.sroa.0.i:8;__local_main.features.i13.sroa.0:4;__local_main.features.i13.sroa.5:4,23,64,1 +aes-10uF,10uF,ok,26,35,9,10,4,210,46384,393,104872.82,20,0,0,3,regional,2475,10033,61,133,yes,49,0,,25,107,1 +bitcount-10uF,10uF,ok,64,95,52,75,22,370,75344,412,6179187.38,80096,0,0,2,regional,8126,35533,1885,5944,yes,49,0,,202,52382,1 +chacha20-10uF,10uF,ok,11,15,4,4,2,20,37760,395,50568.56,8,0,0,3,regional,495,1907,23,46,yes,30,0,,3,79,1 +crc-10uF,10uF,ok,9,12,6,6,3,10,35888,404,29834.06,5,0,0,2,regional,117,414,18,37,yes,0,1,__local_main.result:6,2,20431,1 +cuckoo_filter-10uF,10uF,ok,23,33,15,20,4,202,47184,414,72446.45,2052,0,0,3,regional,1009,4162,344,951,yes,12,0,,166,4048,1 +dijkstra-10uF,10uF,ok,17,24,11,15,7,139,45344,405,1126739.77,3787,0,0,5,regional,1229,4972,223,550,yes,48,1,__local_main.nodes.i:5,100,33447,1 +poly1305-10uF,10uF,ok,7,9,4,4,2,14,36752,374,478678.17,86,0,0,3,regional,559,2135,31,68,yes,0,0,,3,68,1 +qsort-10uF,10uF,ok,17,24,12,15,5,18,38208,398,1092206.94,643,0,0,2,regional,324,1264,36,75,yes,7,0,,6,27023,1 +rsa-10uF,10uF,ok,144,209,86,119,43,4645,146048,407,74921.11,324,0,0,8,regional,21292,91133,3214,9905,yes,59,3,g_product:54;__local_main.qn_arr.i:11;__local_main.qn_arr.i34:8,4174,32,1 +sensor_fusion-10uF,10uF,ok,177,268,4,4,2,18,38928,418,25607.51,17,0,0,2,regional,431,1696,17,34,yes,0,1,g_output:4,5,613,1 +sha256-10uF,10uF,ok,38,54,14,18,6,166,55520,409,94456.81,18,0,0,6,regional,4083,16818,307,830,yes,79,0,,85,131,1 +stringsearch-10uF,10uF,ok,41,58,31,43,12,543,62832,409,82554.74,2270,0,0,4,regional,2200,9143,1070,3127,yes,21,3,__local_main.total_found:7;len:7;findme:7,473,20,1 diff --git a/scripts/ckpt/bench/all.py b/scripts/ckpt/bench/all.py index d0dcc87c..643eb6ce 100644 --- a/scripts/ckpt/bench/all.py +++ b/scripts/ckpt/bench/all.py @@ -133,6 +133,7 @@ def _run_step( energy_config=opts.energy_config, cpu_freq=opts.cpu_freq, coarse_allocation=opts.coarse_allocation, + tripcount_annotations=True, milp_gap=opts.milp_gap, pass_log_level=opts.pass_log_level, accumulate_keys_file=None, diff --git a/scripts/ckpt/bench/milp.py b/scripts/ckpt/bench/milp.py index 1047d536..47d26996 100644 --- a/scripts/ckpt/bench/milp.py +++ b/scripts/ckpt/bench/milp.py @@ -130,6 +130,7 @@ def run_milp_benchmarks( energy_config: Path | None, cpu_freq: int, coarse_allocation: bool, + tripcount_annotations: bool, milp_gap: float, pass_log_level: str, accumulate_keys_file: Path | None, @@ -202,6 +203,7 @@ def compile_fn(bench_path: Path, cap: CapacitorConfig) -> CompileResult: milp_gap=milp_gap, milp_log_file="", coarse_allocation=coarse_allocation, + tripcount_annotations=tripcount_annotations, save_temps=False, ) diff --git a/scripts/ckpt/cli.py b/scripts/ckpt/cli.py index e948a121..b55aa5dd 100644 --- a/scripts/ckpt/cli.py +++ b/scripts/ckpt/cli.py @@ -154,6 +154,11 @@ def _cap_callback( is_flag=True, help="Use one MILP placement variable per eligible value instead of per-region placement.", ) +_no_tripcount_flag = click.option( + "--no-tripcount", + is_flag=True, + help="Ignore __loop_tripcount annotations; loops with unknown bounds are chunked.", +) _milp_gap_option = click.option( "--milp-gap", type=float, @@ -420,6 +425,7 @@ def _handle_accumulate_keys(result, accumulate_keys: str | None) -> None: "--milp-log-file", type=click.Path(), default="", help="Gurobi log file path." ) @_coarse_allocation_flag +@_no_tripcount_flag @_accumulate_keys_option @click.pass_context def compile_milp_cmd( @@ -442,6 +448,7 @@ def compile_milp_cmd( milp_gap: float, milp_log_file: str, coarse_allocation: bool, + no_tripcount: bool, accumulate_keys: str | None, csv_path: str | None, ) -> None: @@ -498,6 +505,7 @@ def compile_milp_cmd( milp_gap=milp_gap, milp_log_file=milp_log_file, coarse_allocation=coarse_allocation, + tripcount_annotations=not no_tripcount, save_temps=save_temps, ), ) @@ -979,6 +987,7 @@ def bench() -> None: @_energy_override_option @_cpu_freq_option("16") @_coarse_allocation_flag +@_no_tripcount_flag @_milp_gap_option @_accumulate_keys_option @_saleae_timeout_option @@ -994,6 +1003,7 @@ def bench_milp_cmd( energy_config: str | None, cpu_freq: str, coarse_allocation: bool, + no_tripcount: bool, milp_gap: float, accumulate_keys: str | None, timeout: float, @@ -1014,6 +1024,7 @@ def bench_milp_cmd( energy_config=_path_or_none(energy_config), cpu_freq=_mhz_to_hz(cpu_freq), coarse_allocation=coarse_allocation, + tripcount_annotations=not no_tripcount, milp_gap=milp_gap, pass_log_level=ctx.obj["pass_log_level"], accumulate_keys_file=_path_or_none(accumulate_keys), @@ -1597,6 +1608,7 @@ def verify_rockclimb_cmd( @_estimator_mode_option @_cpu_freq_option("16") @_coarse_allocation_flag +@_no_tripcount_flag @_saleae_timeout_option @click.pass_context def verify_milp_cmd( @@ -1608,6 +1620,7 @@ def verify_milp_cmd( estimator_mode: str, cpu_freq: str, coarse_allocation: bool, + no_tripcount: bool, timeout: float, ) -> None: """Verify semantic correctness of MILP checkpoint insertion.""" @@ -1625,6 +1638,7 @@ def verify_milp_cmd( estimator_mode=estimator_mode, cpu_freq=_mhz_to_hz(cpu_freq), coarse_allocation=coarse_allocation, + tripcount_annotations=not no_tripcount, pass_log_level=ctx.obj["pass_log_level"], ) if not all_ok(results): diff --git a/scripts/ckpt/compile/chunked.py b/scripts/ckpt/compile/chunked.py index 745d90fd..7b3ffc3f 100644 --- a/scripts/ckpt/compile/chunked.py +++ b/scripts/ckpt/compile/chunked.py @@ -89,6 +89,7 @@ def compile_chunked( cpu_freq=opts.cpu_freq, extra_includes=opts.extra_includes, extra_defines=opts.extra_defines, + tripcount_annotations=True, ) # Middle-end optimization diff --git a/scripts/ckpt/compile/common.py b/scripts/ckpt/compile/common.py index bd752338..1347775f 100644 --- a/scripts/ckpt/compile/common.py +++ b/scripts/ckpt/compile/common.py @@ -122,12 +122,17 @@ def compile_annotated_ir( cpu_freq: int, extra_includes: list[str], extra_defines: list[str], + tripcount_annotations: bool, ) -> Path: """Shared phase 1 of the instrumented pipelines: C -> raw IR -> tripcounts. No LLVM pass has run on the returned IR, so the ``__loop_tripcount`` markers still sit inside their source loops for exact trip-count annotation. Returns the annotated IR path (tmp/tripcount.ll). + + With ``tripcount_annotations=False`` the annotation pass is skipped and + the raw IR is returned; the no-op marker calls are inlined away by the + middle-end optimization, so the passes see no trip-count metadata. """ input_ll = tmp / "input.ll" includes = list(extra_includes) @@ -144,6 +149,9 @@ def compile_annotated_ir( extra_defines=[f"F_CPU={cpu_freq}", *extra_defines], ) + if not tripcount_annotations: + return input_ll + tripcount_ll = tmp / "tripcount.ll" annotate_tripcounts(tc, env, input_ll, tripcount_ll) return tripcount_ll diff --git a/scripts/ckpt/compile/milp.py b/scripts/ckpt/compile/milp.py index 5197f8b2..6680fa1c 100644 --- a/scripts/ckpt/compile/milp.py +++ b/scripts/ckpt/compile/milp.py @@ -49,6 +49,7 @@ class MilpCompileOptions: milp_log_file: str coarse_allocation: bool save_temps: bool + tripcount_annotations: bool extra_includes: list[str] = field(default_factory=list) extra_defines: list[str] = field(default_factory=list) @@ -105,6 +106,7 @@ def compile_milp( cpu_freq=opts.cpu_freq, extra_includes=opts.extra_includes, extra_defines=opts.extra_defines, + tripcount_annotations=opts.tripcount_annotations, ) # Middle-end optimization diff --git a/scripts/ckpt/compile/rockclimb.py b/scripts/ckpt/compile/rockclimb.py index 0996cd8e..835d74c8 100644 --- a/scripts/ckpt/compile/rockclimb.py +++ b/scripts/ckpt/compile/rockclimb.py @@ -100,6 +100,7 @@ def compile_rockclimb( cpu_freq=opts.cpu_freq, extra_includes=[], extra_defines=opts.extra_defines, + tripcount_annotations=True, ) # Step 1c: Middle-end optimization (the second half of what a plain diff --git a/scripts/ckpt/compile/schematic.py b/scripts/ckpt/compile/schematic.py index 3fc994c7..a6c376cf 100644 --- a/scripts/ckpt/compile/schematic.py +++ b/scripts/ckpt/compile/schematic.py @@ -110,6 +110,7 @@ def compile_schematic( cpu_freq=opts.cpu_freq, extra_includes=opts.extra_includes, extra_defines=opts.extra_defines, + tripcount_annotations=True, ) # Middle-end optimization diff --git a/scripts/ckpt/intermittent/runner.py b/scripts/ckpt/intermittent/runner.py index 2c9209a7..e523429a 100644 --- a/scripts/ckpt/intermittent/runner.py +++ b/scripts/ckpt/intermittent/runner.py @@ -184,6 +184,7 @@ def compile_fn(bench_path: Path, cap: CapacitorConfig) -> CompileResult: milp_gap=0.0, milp_log_file="", coarse_allocation=False, + tripcount_annotations=True, save_temps=False, extra_defines=list(_SHRINK_DEFINES), ) diff --git a/scripts/ckpt/verify/all.py b/scripts/ckpt/verify/all.py index cd005ef0..c143b2c0 100644 --- a/scripts/ckpt/verify/all.py +++ b/scripts/ckpt/verify/all.py @@ -37,6 +37,7 @@ def verify_all( energy_config=energy_config, estimator_mode=estimator_mode, coarse_allocation=False, + tripcount_annotations=True, pass_log_level=pass_log_level, ), rockclimb_spec( diff --git a/scripts/ckpt/verify/milp.py b/scripts/ckpt/verify/milp.py index 327fc605..f9bd5d43 100644 --- a/scripts/ckpt/verify/milp.py +++ b/scripts/ckpt/verify/milp.py @@ -22,6 +22,7 @@ def milp_spec( energy_config: Path | None, estimator_mode: str, coarse_allocation: bool, + tripcount_annotations: bool, pass_log_level: str, ) -> AlgorithmSpec: """Build the MILP verification spec.""" @@ -60,6 +61,7 @@ def compile_instrumented( milp_gap=0.0, milp_log_file="", coarse_allocation=coarse_allocation, + tripcount_annotations=tripcount_annotations, save_temps=False, extra_defines=extra_defines, ), @@ -88,6 +90,7 @@ def verify_milp( cpu_freq: int, capture_timeout_seconds: float, coarse_allocation: bool, + tripcount_annotations: bool, pass_log_level: str, ) -> list[BenchResult]: """Verify semantic correctness of MILP checkpoint insertion.""" @@ -96,6 +99,7 @@ def verify_milp( energy_config=energy_config, estimator_mode=estimator_mode, coarse_allocation=coarse_allocation, + tripcount_annotations=tripcount_annotations, pass_log_level=pass_log_level, ) return verify_algorithms(