validation.py 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. import tempfile
  2. import time
  3. import pandas as pd
  4. import pickle
  5. from imc_utils.pps_e36311a import PPS_E36311A
  6. from imc_utils.build_config.cortex_m33 import BuildConfigM33
  7. from imc_utils.build_config.test_env import TestEnv
  8. import imc_utils.serial_device
  9. WORKSPACE_ROOT = "/home/ybkim/workspace/imc/imc_freertos_app_m33"
  10. NVM_RESET_BIN = f"{WORKSPACE_ROOT}/imc/utils/nvm_reset.elf"
  11. OPENOCD_SCRIPT = f"{WORKSPACE_ROOT}/imc_freertos_app_m33.cfg"
  12. def main():
  13. pps = PPS_E36311A()
  14. config = get_default_build_config()
  15. benchmarks = [
  16. "vBasicMath", "vCrc", "vFFT", "vSha"
  17. # "vSha"
  18. ]
  19. for benchmark in benchmarks:
  20. config.bench_name = benchmark
  21. config.insert_compiler_checkpoints = True
  22. config.use_checkpoint_pass_counter = False
  23. config.use_checkpoint_voltage_check = True
  24. config.checkpoint_pass_count = 100
  25. config.bench_infinite_loop = True
  26. pps.set_voltage(3.3, 1)
  27. pps.set_current(0.1, 1)
  28. pps.output_on(1)
  29. env = TestEnv(WORKSPACE_ROOT, NVM_RESET_BIN, OPENOCD_SCRIPT)
  30. with tempfile.TemporaryDirectory() as build_dir:
  31. binary = env.build_binary(config, build_dir)
  32. env.clear_nvm_and_load_binary(binary, resume=True)
  33. pps.set_current(0.015, 1)
  34. time.sleep(1)
  35. total_iterations = 5
  36. records = measure_execution_time(benchmark, total_iterations)
  37. df = pd.DataFrame(records)
  38. save_records(benchmark, df)
  39. print(df)
  40. def measure_execution_time(bench_nanme, total_iterations):
  41. ser = imc_utils.serial_device.get_serial()
  42. num_finished = 0
  43. start_detected = False
  44. time_takens = []
  45. time_total = 0
  46. outputs = []
  47. records = []
  48. num_recovery = 0
  49. ser.reset_input_buffer()
  50. while num_finished < total_iterations:
  51. if ser.readable():
  52. res = ser.readline()
  53. try:
  54. line = res.decode()[: len(res) - 1]
  55. except:
  56. print("readline() exception")
  57. continue
  58. if line.startswith("hardfault"):
  59. print("\nHARD FAULT")
  60. if not start_detected:
  61. if line.startswith("Start benchmark"):
  62. print("\nbenchmark start detected")
  63. t_start = time.time()
  64. start_detected = True
  65. else:
  66. if line.startswith("End benchmark"):
  67. t_end = time.time()
  68. t_diff = t_end - t_start
  69. time_takens.append(t_diff)
  70. time_total += t_diff
  71. num_finished += 1
  72. print(
  73. f"\nbenchmark end detected, time: {t_diff:.2f} secs, finished: {num_finished}, average: {time_total/num_finished:.2f} secs"
  74. )
  75. start_detected = False
  76. record = {
  77. "bench_name": bench_nanme,
  78. "start": t_start,
  79. "end": t_end,
  80. "time_taken": t_diff,
  81. "recovery": num_recovery,
  82. "outputs": outputs,
  83. "is_correct": check_output_is_correct(bench_nanme, outputs)
  84. }
  85. records.append(record)
  86. outputs = []
  87. num_recovery = 0
  88. elif line.startswith("(OUT)"):
  89. print(line)
  90. outputs.append(line[6:].strip())
  91. elif line.startswith("Start recovery"):
  92. num_recovery += 1
  93. print(f"recovery: #{num_recovery}", end="\r")
  94. return records
  95. def get_default_build_config():
  96. config = BuildConfigM33()
  97. config.bench_name = "vBasicMath"
  98. config.insert_compiler_checkpoints = True
  99. config.enable_extension = True
  100. config.use_checkpoint_pass_counter = False
  101. config.use_checkpoint_voltage_check = True
  102. config.bench_infinite_loop = True
  103. config.checkpoint_pass_count = 100
  104. config.print_recovery_message = True
  105. return config
  106. correct_outputs = {
  107. "vBasicMath": "Sum: -9313",
  108. "vCrc": "210692533",
  109. "vFFT": "2807, 915",
  110. "vSha": "4926a88d 0ca714f4 a9ebc1eb def37b8e 3911ee0f",
  111. }
  112. def check_output_is_correct(bench_name, outputs):
  113. if len(outputs) == 0 or bench_name not in correct_outputs:
  114. return False
  115. is_single_output = len(outputs) == 1
  116. is_output_correct = correct_outputs[bench_name] == outputs[0]
  117. return is_single_output and is_output_correct
  118. def save_records(bench_name, df):
  119. with open(f"output/{bench_name}.pickle", "wb") as f:
  120. pickle.dump(df, f)
  121. if __name__ == "__main__":
  122. main()