Skip to content

Commit

Permalink
[Fix] support validate feature with etiss_pulpino
Browse files Browse the repository at this point in the history
ETISS does print the simulation return code to stdout. This means that the exit code handling needs to happen at a different level.
  • Loading branch information
PhilippvK committed Mar 29, 2022
1 parent 0ac0cf2 commit 375ba57
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 29 deletions.
8 changes: 5 additions & 3 deletions mlonmcu/platform/espidf_target.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,11 +87,13 @@ def parse_stdout(self, out):
time_us = int(float(cpu_time_us.group(1)))
return cycles, time_us

def get_metrics(self, elf, directory):
def get_metrics(self, elf, directory, handle_exit=None):
if self.print_outputs:
out = self.exec(elf, cwd=directory, live=True)
out = self.exec(elf, cwd=directory, live=True, handle_exit=handle_exit)
else:
out = self.exec(elf, cwd=directory, live=False, print_func=lambda *args, **kwargs: None)
out = self.exec(
elf, cwd=directory, live=False, print_func=lambda *args, **kwargs: None, handle_exit=handle_exit
)
cycles, time_us = self.parse_stdout(out)

metrics = Metrics()
Expand Down
14 changes: 7 additions & 7 deletions mlonmcu/platform/mlif_target.py
Original file line number Diff line number Diff line change
Expand Up @@ -76,12 +76,13 @@ def __init__(self, features=None, config=None):
self.platform = platform
self.validation_result = None

def exec(self, program, *args, cwd=os.getcwd(), **kwargs):
def get_metrics(self, elf, directory, handle_exit=None):

# This is wrapper around the original exec function to catch special return codes thrown by the inout data
# feature (TODO: catch edge cases: no input data available (skipped) and no return code (real hardware))
if self.platform.validate_outputs:
if self.platform.validate_outputs and handle_exit is None:

def handle_exit(code):
def _handle_exit(code):
if code == 0:
self.validation_result = True
else:
Expand All @@ -93,11 +94,10 @@ def handle_exit(code):
code = 0
return code

kwargs["handle_exit"] = handle_exit
return super().exec(program, *args, cwd=cwd, **kwargs)
handle_exit = _handle_exit

metrics, out = super().get_metrics(elf, directory, handle_exit=handle_exit)

def get_metrics(self, elf, directory):
metrics, out = super().get_metrics(elf, directory)
if self.platform.validate_outputs:
metrics.add("Validation", self.validation_result)
return metrics, out
Expand Down
8 changes: 5 additions & 3 deletions mlonmcu/target/corstone300.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,12 +142,14 @@ def parse_stdout(self, out):
# mips = None # TODO: parse mips?
return cycles

def get_metrics(self, elf, directory):
def get_metrics(self, elf, directory, handle_exit=None):
out = ""
if self.print_outputs:
out += self.exec(elf, cwd=directory, live=True)
out += self.exec(elf, cwd=directory, live=True, handle_exit=handle_exit)
else:
out += self.exec(elf, cwd=directory, live=False, print_func=lambda *args, **kwargs: None)
out += self.exec(
elf, cwd=directory, live=False, print_func=lambda *args, **kwargs: None, handle_exit=handle_exit
)
cycles = self.parse_stdout(out)

metrics = Metrics()
Expand Down
18 changes: 11 additions & 7 deletions mlonmcu/target/etiss_pulpino.py
Original file line number Diff line number Diff line change
Expand Up @@ -162,11 +162,13 @@ def exec(self, program, *args, cwd=os.getcwd(), **kwargs):
)
return ret

def parse_stdout(self, out):
def parse_stdout(self, out, handle_exit=None):
exit_match = re.search(r"exit called with code: (.*)", out)
if exit_match:
exit_code = exit_match.group(1)
if int(exit_code) != 0:
exit_code = int(exit_match.group(1))
if handle_exit is not None:
exit_code = handle_exit(exit_code)
if exit_code != 0:
logger.error("Execution failed - " + out)
raise RuntimeError(f"unexpected exit code: {exit_code}")
error_match = re.search(r"ETISS: Error: (.*)", out)
Expand All @@ -189,7 +191,7 @@ def parse_stdout(self, out):

return cycles, mips

def get_metrics(self, elf, directory):
def get_metrics(self, elf, directory, handle_exit=None):
out = ""
if self.trace_memory:
trace_file = os.path.join(directory, "dBusAccess.csv")
Expand All @@ -203,10 +205,12 @@ def get_metrics(self, elf, directory):
os.remove(metrics_file)

if self.print_outputs:
out += self.exec(elf, cwd=directory, live=True)
out += self.exec(elf, cwd=directory, live=True, handle_exit=handle_exit)
else:
out += self.exec(elf, cwd=directory, live=False, print_func=lambda *args, **kwargs: None)
total_cycles, mips = self.parse_stdout(out)
out += self.exec(
elf, cwd=directory, live=False, print_func=lambda *args, **kwargs: None, handle_exit=handle_exit
)
total_cycles, mips = self.parse_stdout(out, handle_exit=handle_exit)

get_metrics_args = [elf]
etiss_ini = os.path.join(directory, "custom.ini")
Expand Down
8 changes: 5 additions & 3 deletions mlonmcu/target/ovpsim.py
Original file line number Diff line number Diff line change
Expand Up @@ -147,12 +147,14 @@ def parse_stdout(self, out):
mips = float(mips_str)
return cycles, mips

def get_metrics(self, elf, directory):
def get_metrics(self, elf, directory, handle_exit=None):
out = ""
if self.print_outputs:
out += self.exec(elf, cwd=directory, live=True)
out += self.exec(elf, cwd=directory, live=True, handle_exit=handle_exit)
else:
out += self.exec(elf, cwd=directory, live=False, print_func=lambda *args, **kwargs: None)
out += self.exec(
elf, cwd=directory, live=False, print_func=lambda *args, **kwargs: None, handle_exit=handle_exit
)
cycles, mips = self.parse_stdout(out)

metrics = Metrics()
Expand Down
8 changes: 5 additions & 3 deletions mlonmcu/target/spike.py
Original file line number Diff line number Diff line change
Expand Up @@ -107,12 +107,14 @@ def parse_stdout(self, out):
# mips = None # TODO: parse mips?
return cycles

def get_metrics(self, elf, directory):
def get_metrics(self, elf, directory, handle_exit=None):
out = ""
if self.print_outputs:
out += self.exec(elf, cwd=directory, live=True)
out += self.exec(elf, cwd=directory, live=True, handle_exit=handle_exit)
else:
out += self.exec(elf, cwd=directory, live=False, print_func=lambda *args, **kwargs: None)
out += self.exec(
elf, cwd=directory, live=False, print_func=lambda *args, **kwargs: None, handle_exit=handle_exit
)
cycles = self.parse_stdout(out)

metrics = Metrics()
Expand Down
8 changes: 5 additions & 3 deletions mlonmcu/target/target.py
Original file line number Diff line number Diff line change
Expand Up @@ -108,13 +108,15 @@ def inspect(self, program: Path, *args, **kwargs):
"""Use target to inspect a executable"""
return execute(self.inspect_program, program, *self.inspect_program_args, *args, **kwargs)

def get_metrics(self, elf, directory):
def get_metrics(self, elf, directory, handle_exit=None):
# This should not be accurate, just a fallback which should be overwritten
start_time = time.time()
if self.print_outputs:
out = self.exec(elf, cwd=directory, live=True)
out = self.exec(elf, cwd=directory, live=True, handle_exit=handle_exit)
else:
out = self.exec(elf, cwd=directory, live=False, print_func=lambda *args, **kwargs: None)
out = self.exec(
elf, cwd=directory, live=False, print_func=lambda *args, **kwargs: None, handle_exit=handle_exit
)
# TODO: do something with out?
end_time = time.time()
diff = end_time - start_time
Expand Down

0 comments on commit 375ba57

Please sign in to comment.