Skip to content

Commit

Permalink
[µTVM] Print .elf statistics for a model runtime built with Zephyr (a…
Browse files Browse the repository at this point in the history
…pache#7449)

* [µTVM] Print .elf statistics for a model runtime built with Zephyr

Currently there isn't any statistics about the used resources by a model
runtime built with Zephyr, making it difficult to have any idea about, for
instance, the amount of memory taken by the operations necessary to run the
model.

Since Zephyr's SDK already exposes the statistics about various memory
regions on linking by passing '--print-memory-usage' to the linker, it's
possible to use it to have an idea about the amount of memory used by the
model and how much memory is left on the device.

That commit adds a simple method to extract the memory region information
out of the build output and then uses it to show memory usage statistics
for various memory regions when Zephyr finishes building the image to be
flashed to the target device.

Signed-off-by: Gustavo Romero <[email protected]>

* v2: Fixes accordingly to Andrew review

- Catch StopIteration in case of a weird output or no additional lines
  after the last memory region
- Use of _LOG.info() instead of plain print() for better control over
  the output by the main script
- Set log level in micro_tflite.py script as an example on how to get
  the new memory usage statistics and also because currently that's the
  main script used to test microTVM + Zephyr's SDK
- Improve statistics header

Signed-off-by: Gustavo Romero <[email protected]>

* Fix build

It seems build system is using Python < 3.7, so 'text' argument
is not present as an alias for 'universal_newlines'. To satisfy
it use old 'universal_newlines' argument which is available prior
to Python 3.7.

* Fix build

Avoid exception anti-pattern when catching StopIteration

* Retrigger CI
  • Loading branch information
gromero authored and trevor-m committed Mar 2, 2021
1 parent 10f3d1e commit dbbc7ba
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 2 deletions.
25 changes: 23 additions & 2 deletions python/tvm/micro/contrib/zephyr.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ def run(self, cmd, **kw):
for k, v in self.default_overrides.items():
env[k] = v

return subprocess.check_output(cmd, env=env, **kw)
return subprocess.check_output(cmd, env=env, **kw, universal_newlines=True)


class ProjectNotFoundError(Exception):
Expand Down Expand Up @@ -204,6 +204,25 @@ def library(self, output, sources, options=None):
)
return tvm.micro.MicroLibrary(build_dir, [f"lib{project_name}.a"])

def _print_make_statistics(self, output):
output = output.splitlines()
lines = iter(output)
for line in lines:
if line.startswith("Memory region"):
# print statistics header
_LOG.info(line)
_LOG.info("--------------------- ---------- ------------ ---------")
line = next(lines)
# while there is a region print it
try:
while ":" in line:
_LOG.info(line)
line = next(lines)
else:
break
except StopIteration:
pass

def binary(self, output, objects, options=None, link_main=True, main_options=None):
assert link_main, "Must pass link_main=True"
assert self._project_dir is not None, "Must supply project_dir= to build binaries"
Expand All @@ -224,7 +243,9 @@ def binary(self, output, objects, options=None, link_main=True, main_options=Non
cmake_args.append(f'-DTVM_LIBS={";".join(copied_libs)}')
self._subprocess_env.run(cmake_args, cwd=output)

self._subprocess_env.run(["make"], cwd=output)
make_output = self._subprocess_env.run(["make"], cwd=output)

self._print_make_statistics(make_output)

return tvm.micro.MicroBinary(
output,
Expand Down
6 changes: 6 additions & 0 deletions tutorials/micro/micro_tflite.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@

import os
import numpy as np
import logging

import tvm
import tvm.micro as micro
from tvm.contrib.download import download_testdata
Expand Down Expand Up @@ -229,6 +231,10 @@
# )
#
# opts = tvm.micro.default_options(f"{project_dir}/crt")
#
# enable printing memory usage statistics of the runtime image
# generated by Zephyr compiler for the physical hardware
# logging.basicConfig(level="INFO")

workspace = tvm.micro.Workspace()
micro_binary = tvm.micro.build_static_runtime(
Expand Down

0 comments on commit dbbc7ba

Please sign in to comment.