validation.py 4.7 KB

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