import tempfile import time import pickle import pandas as pd from imc_utils.pps_e36311a import PPS_E36311A from imc_utils.smu_b2902a import SMU_B2902A from imc_utils.build_config.cortex_m33 import BuildConfigM33 from imc_utils.build_config.test_env import TestEnv from imc_utils.serial_watch import SerialWatcher WORKSPACE_ROOT = "/home/ybkim/workspace/imc/imc_freertos_app_m33" NVM_RESET_BIN = f"{WORKSPACE_ROOT}/imc/utils/nvm_reset.elf" OPENOCD_SCRIPT = f"{WORKSPACE_ROOT}/imc_freertos_app_m33.cfg" use_smu = False def get_build_config(benchmark, config_name): config = get_default_build_config() config.bench_name = benchmark bench_repeat_count = config.bench_repeat_count_small[benchmark] config.bench_repeat_count = bench_repeat_count if config_name == "pass_count": config.use_checkpoint_pass_counter = True # config.checkpoint_pass_count = config.pass_count_10ms[benchmark] # config.checkpoint_pass_count = config.pass_count_400ms[benchmark] # config.checkpoint_pass_count = config.pass_count_167ms[benchmark] config.checkpoint_pass_count = config.pass_count_154ms[benchmark] if config_name == "adaptive": config.use_checkpoint_voltage_check = True config.split_loop = True config.enable_adaptive_loop_pass_count = True config.max_loop_ids = 15 config.loop_opt_debug = False if config_name == "unroll": config.use_checkpoint_voltage_check = True config.custom_unroll = True return config def main(): pps = PPS_E36311A() if use_smu: volt = 3.3 smu = SMU_B2902A(voltage=3.3) config = get_default_build_config() benchmarks = [ "vBasicMath", "vCrc", "vFFT", "vSha", "vStringSearch", "vMatMul", "vConv2d", "vAes", ] benchmarks = [ # "vCrc", # "vSha", "vBasicMath", # "vMatMul" ] configs = ["pass_count", "adaptive", "unroll"] # configs = ["adaptive"] total_iterations = 20 target_current_limit = 0.015 for benchmark in benchmarks: for config_name in configs: all_records = [] config = get_build_config(benchmark, config_name) if use_smu: smu.set_current_limit(0.1) smu.power_on() else: pps.set_voltage(3.3, 1) pps.set_current(0.1, 1) pps.output_on(1) env = TestEnv(WORKSPACE_ROOT, NVM_RESET_BIN, OPENOCD_SCRIPT) with tempfile.TemporaryDirectory() as build_dir: binary = env.build_binary(config, build_dir) env.clear_nvm_and_load_binary(binary, resume=False) if use_smu: smu.set_current_limit(target_current_limit) else: pps.set_current(target_current_limit, 1) time.sleep(1) env.resume_board(terminate=True) watcher = SerialWatcher(benchmark, total_iterations) records = watcher.run() for record in records: record.update( { # "loop_pass_count": loop_pass_count, } ) all_records.append(record) df = pd.DataFrame(all_records) columns = ["bench_name", "time_taken", "recovery", "stats", "is_correct"] print(df[columns]) save_records(benchmark, config_name, df) if use_smu: smu.power_off() else: pps.output_off(1) def get_default_build_config(): config = BuildConfigM33() config.insert_compiler_checkpoints = True config.enable_extension = True config.use_checkpoint_pass_counter = False config.use_checkpoint_voltage_check = False config.bench_infinite_loop = True config.print_recovery_message = True config.split_loop = False config.enable_static_loop_pass_count = False config.enable_adaptive_loop_pass_count = False config.print_stats = True config.custom_unroll = False config.loop_opt_debug = False return config def save_records(bench_name, config_name, df): with open(f"output/{config_name}/{bench_name}.pickle", "wb") as f: pickle.dump(df, f) if __name__ == "__main__": main()