You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tvm.apache.org by mo...@apache.org on 2021/02/15 18:22:15 UTC

[tvm] branch main updated: [µTVM] Print .elf statistics for a model runtime built with Zephyr (#7449)

This is an automated email from the ASF dual-hosted git repository.

moreau pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git


The following commit(s) were added to refs/heads/main by this push:
     new 32c4402  [µTVM] Print .elf statistics for a model runtime built with Zephyr (#7449)
32c4402 is described below

commit 32c44025483b9aea7732cdc80e85e8e973c602ab
Author: Gustavo Romero <gr...@users.noreply.github.com>
AuthorDate: Mon Feb 15 15:22:00 2021 -0300

    [µTVM] Print .elf statistics for a model runtime built with Zephyr (#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 <gu...@linaro.org>
    
    * 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 <gu...@linaro.org>
    
    * 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
---
 python/tvm/micro/contrib/zephyr.py | 25 +++++++++++++++++++++++--
 tutorials/micro/micro_tflite.py    |  6 ++++++
 2 files changed, 29 insertions(+), 2 deletions(-)

diff --git a/python/tvm/micro/contrib/zephyr.py b/python/tvm/micro/contrib/zephyr.py
index ed1c986..29bb5ec 100644
--- a/python/tvm/micro/contrib/zephyr.py
+++ b/python/tvm/micro/contrib/zephyr.py
@@ -55,7 +55,7 @@ class SubprocessEnv(object):
         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):
@@ -204,6 +204,25 @@ class ZephyrCompiler(tvm.micro.Compiler):
         )
         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"
@@ -224,7 +243,9 @@ class ZephyrCompiler(tvm.micro.Compiler):
         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,
diff --git a/tutorials/micro/micro_tflite.py b/tutorials/micro/micro_tflite.py
index 673985e..6ad0da5 100644
--- a/tutorials/micro/micro_tflite.py
+++ b/tutorials/micro/micro_tflite.py
@@ -122,6 +122,8 @@ model with Relay.
 
 import os
 import numpy as np
+import logging
+
 import tvm
 import tvm.micro as micro
 from tvm.contrib.download import download_testdata
@@ -229,6 +231,10 @@ opts = tvm.micro.default_options(
 #     )
 #
 #     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(