Compiling and running microTVM on qemu cortex-m3 with tvmc

Hi,

I am trying to use tvmc to compile and run microTVM on qemu cortex-m3. Do you know if it is possible? If so, what commands should I use to build and run the program on QEMU? As TFLITE model, I am using the one reported in the microTVM tutorial: sine_model.tflite with tvmc.

I am compiling TVM from scratch on 0cb633777a2f65a06579b1cea7ef11e3dd659498 and with the following build options: Build options:

  • set(USE_MICRO ON)
  • set(USE_LLVM “/path/to/llvm-bin”)

Many thanks in advance for your help.

p.s. I have Zephyr SDK installed

@gmiodice we’ve just landed support for microTVM in tvmc, but there are a couple of bugs so I might suggest you wait for https://github.com/apache/tvm/pull/9584. We still won’t have a tutorial so I can’t promise this would be entirely smooth sailing, but if you replicate the project options from here when using the tvmc micro subcommand, I think that should get you pretty far.

Hi @areusch , thanks a lot for your reply. Then, I can wait for the patch to be merged. However, I tried following the tutorial for microTVM based on the sine_model.tflite, and, unfortunately, I could not run it. I got the following error:


build/crt/libcommon.a(crt_runtime_api.o): In function `SystemLibraryCreate':
/tmp/tmppj40749z/generated-project/crt/src/runtime/crt/common/crt_runtime_api.c:210: undefined reference to `TVMSystemLibEntryPoint'
collect2: error: ld returned 1 exit status
make: *** [build/main] Error 1

How can I fix this problem?

It seems to me that error is related to system-lib option in runtime backend. Make sure you use the latest version of the tutorial on main.

I have tried the sine_model.tflite with qemu_cortex_m3 board. Here is the change that you need to do to run the tutorial:

diff --git a/gallery/how_to/work_with_microtvm/micro_tflite.py b/gallery/how_to/work_with_microtvm/micro_tflite.py
index bd70fc581..f5e713649 100644
--- a/gallery/how_to/work_with_microtvm/micro_tflite.py
+++ b/gallery/how_to/work_with_microtvm/micro_tflite.py
@@ -181,7 +181,7 @@ mod, params = relay.frontend.from_tflite(
 #
 RUNTIME = tvm.relay.backend.Runtime("crt", {"system-lib": True})
 TARGET = tvm.target.target.micro("host")
-BOARD = "qemu_x86"
+BOARD = "qemu_cortex_m3"
 #
 # Compiling for physical hardware
 #  When running on physical hardware, choose a TARGET and a BOARD that describe the hardware. The
@@ -267,16 +267,16 @@ os.unlink(model_library_format_tar_path)
 import subprocess
 import pathlib
 
-template_project_path = pathlib.Path(tvm.micro.get_microtvm_template_projects("crt"))
-project_options = {}  # You can use options to provide platform-specific options through TVM.
+# template_project_path = pathlib.Path(tvm.micro.get_microtvm_template_projects("crt"))
+# project_options = {}  # You can use options to provide platform-specific options through TVM.
 
 # Compiling for physical hardware (or an emulated board, like the mps_an521)
 # --------------------------------------------------------------------------
 #  For physical hardware, you can try out the Zephyr platform by using a different template project
 #  and options:
 #
-#     template_project_path = pathlib.Path(tvm.micro.get_microtvm_template_projects("zephyr"))
-#     project_options = {"project_type": "host_driven", zephyr_board": "nucleo_f746zg"}}
+template_project_path = pathlib.Path(tvm.micro.get_microtvm_template_projects("zephyr"))
+project_options = {"project_type": "host_driven", "zephyr_board": BOARD}
 
 # Create a temporary directory
 import tvm.contrib.utils

This however ran into memory limitation issue:

/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/10.2.0/../../../../arm-zephyr-eabi/bin/ld: zephyr_prebuilt.elf section `bss' will not fit in region `SRAM'
/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/10.2.0/../../../../arm-zephyr-eabi/bin/ld: section .intList VMA [0000000020010000,0000000020010037] overlaps section bss VMA [0000000020000188,000000002003e9ca]
/opt/zephyr-sdk/arm-zephyr-eabi/bin/../lib/gcc/arm-zephyr-eabi/10.2.0/../../../../arm-zephyr-eabi/bin/ld: region `SRAM' overflowed by 194256 bytes
collect2: error: ld returned 1 exit status
zephyr/CMakeFiles/zephyr_prebuilt.dir/build.make:115: recipe for target 'zephyr/zephyr_prebuilt.elf' failed
make[2]: *** [zephyr/zephyr_prebuilt.elf] Error 1
CMakeFiles/Makefile2:2314: recipe for target 'zephyr/CMakeFiles/zephyr_prebuilt.dir/all' failed
make[1]: *** [zephyr/CMakeFiles/zephyr_prebuilt.dir/all] Error 2
Makefile:90: recipe for target 'all' failed
make: *** [all] Error 2
Traceback (most recent call last):
  File "gallery/how_to/work_with_microtvm/micro_tflite.py", line 291, in <module>
    generated_project.build()
  File "/home/mhessar/tvm/python/tvm/micro/project.py", line 89, in build
    self._api_client.build(self._options)
  File "/home/mhessar/tvm/python/tvm/micro/project_api/client.py", line 170, in build
    return self._request_reply("build", {"options": (options if options is not None else {})})
  File "/home/mhessar/tvm/python/tvm/micro/project_api/client.py", line 135, in _request_reply
    raise server.JSONRPCError.from_json(f"calling method {method}", reply["error"])
tvm.micro.project_api.server.ServerError: calling method build: JSON-RPC error # -32000: calling method build
Traceback (most recent call last):
  File "/home/mhessar/tvm/python/tvm/micro/project_api/server.py", line 481, in serve_one_request  # <--- Outermost server-side stack frame
    self._dispatch_request(request)
  File "/home/mhessar/tvm/python/tvm/micro/project_api/server.py", line 593, in _dispatch_request
    return_value = dispatch_method(**params)
  File "/tmp/tmpgbazjhii/generated-project/microtvm_api_server.py", line 513, in build
    check_call(args, cwd=BUILD_DIR)
  File "/tmp/tmpgbazjhii/generated-project/microtvm_api_server.py", line 85, in check_call
    return subprocess.check_call(cmd_args, *args, **kwargs)
  File "/usr/lib/python3.6/subprocess.py", line 311, in check_call
    raise CalledProcessError(retcode, cmd)
subprocess.CalledProcessError: Command '['make', '-j2']' returned non-zero exit status 2.

I suggest to use a small model in AOT mode, you have better chance to fit the model.

Many thanks @mehrdadh for your help. I wondered, should your changes be applied on microTVM with TFLite Models — tvm 0.8.dev0 documentation ?