Skip to content

Commit

Permalink
[microTVM] Update Zephyr version and Zephyr SDK version (#13818)
Browse files Browse the repository at this point in the history
This commit updates the microTVM code to use Zephyr 3.2 and SDK 0.15.2.
                                                                       
As a result of this change, there are a few other changes that are     
included:           

- A launch script was added for Zephyr and Arduino template project to 
run the Project API server from a different Python ENV than TVM Python 
ENV;

- For Zephyr, the launch script uses global python3.8 which is where   
west is registered. However, for Arduino it uses a separate virtual ENV
with python3 version that exists in the host;
                                                                       
- tests/micro/project_api/test_arduino_microtvm_api_server.py was      
removed since these tests were using Arduino microTVM API server by    
importing it from TVM. We no longer support Arduino/Zephyr dependencies
in TVM testing python ENV;
                                                                       
- Disables a demo and test due to a CMSIS-NN bug:                      
[Bug] CMSIS-NN BYOC fails with Zephyr 3.2 #13856;                      
                
There will be a follow up work to move Zephyr to a completely separate 
virtual ENV as it was done in this commit for Arduino in the launch
script.
  • Loading branch information
mehrdadh authored Feb 1, 2023
1 parent a1229f6 commit d6f78b1
Show file tree
Hide file tree
Showing 21 changed files with 193 additions and 269 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#!/bin/bash
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

function show_usage() {
cat <<EOF
This script is for running microtvm_api_server with Arduino.
Usage: launch_microtvm_api_server.sh <microtvm_api_server.py> --read-fd <READ_FD_PATH> --write-fd <WRITE_FD_PATH>
EOF
}

if [ "$#" -lt 5 -o "$1" == "--help" ]; then
show_usage
exit -1
fi

ARDUINO_VENV_PATH=${HOME}/.tvm/micro_arduino

# Create virtual env
mkdir -p ${HOME}/.tvm
PYTHON_CMD=$(which python3)
$PYTHON_CMD -m venv ${ARDUINO_VENV_PATH}
ARDUINO_PYTHON_CMD="${ARDUINO_VENV_PATH}/bin/python3"

# Install dependencies
$ARDUINO_PYTHON_CMD -m pip install pyusb packaging

# Run server
$ARDUINO_PYTHON_CMD $1 $2 $3 $4 $5
13 changes: 11 additions & 2 deletions apps/microtvm/arduino/template_project/microtvm_api_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
from string import Template
from packaging import version

from tvm.micro.project_api import server
import server

_LOG = logging.getLogger(__name__)

Expand Down Expand Up @@ -387,7 +387,16 @@ def generate_project(self, model_library_format_path, standalone_crt_dir, projec
source_dir.mkdir()

# Copies files from the template folder to project_dir
shutil.copy2(API_SERVER_DIR / "microtvm_api_server.py", project_dir)
for file in os.listdir(API_SERVER_DIR):
if file.endswith(".py"):
shutil.copy2(API_SERVER_DIR / file, project_dir / file)

# Copy launch script
shutil.copy2(
API_SERVER_DIR / "launch_microtvm_api_server.sh",
project_dir / "launch_microtvm_api_server.sh",
)

shutil.copy2(BOARDS, project_dir / BOARDS.name)
self._copy_project_files(API_SERVER_DIR, project_dir, project_type)

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
#!/bin/bash
# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements. See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership. The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License. You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing,
# software distributed under the License is distributed on an
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
# KIND, either express or implied. See the License for the
# specific language governing permissions and limitations
# under the License.

function show_usage() {
cat <<EOF
This script is for running microtvm_api_server with Zephyr.
Usage: launch_microtvm_api_server.sh <microtvm_api_server.py> --read-fd <READ_FD_PATH> --write-fd <WRITE_FD_PATH>
EOF
}

if [ "$#" -lt 5 -o "$1" == "--help" ]; then
show_usage
exit -1
fi

PYTHON_CMD=$(sed 's/#!//; q' $(which west))

# Run server
$PYTHON_CMD $1 $2 $3 $4 $5
41 changes: 24 additions & 17 deletions apps/microtvm/zephyr/template_project/microtvm_api_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
import serial.tools.list_ports
import yaml

from tvm.micro.project_api import server
import server


_LOG = logging.getLogger(__name__)
Expand All @@ -68,7 +68,7 @@

# Used to check Zephyr version installed on the host.
# We only check two levels of the version.
ZEPHYR_VERSION = 2.7
ZEPHYR_VERSION = 3.2

WEST_CMD = default = sys.executable + " -m west" if sys.executable else None

Expand Down Expand Up @@ -317,7 +317,10 @@ def _get_nrf_device_args(serial_number: str = None) -> list:
),
server.ProjectOption(
"west_cmd",
optional=["generate_project"],
required=(
["generate_project", "build", "flash", "open_transport"] if not WEST_CMD else None
),
optional=(["generate_project", "build", "flash", "open_transport"] if WEST_CMD else None),
type="str",
default=WEST_CMD,
help=(
Expand Down Expand Up @@ -551,9 +554,18 @@ def generate_project(self, model_library_format_path, standalone_crt_dir, projec
# Make project directory.
project_dir.mkdir()

# Copy ourselves to the generated project. TVM may perform further build steps on the generated project
# Copy ourselves and other python scripts to the generated project. TVM may perform further build steps on the generated project
# by launching the copy.
shutil.copy2(__file__, project_dir / os.path.basename(__file__))
current_dir = pathlib.Path(__file__).parent.absolute()
for file in os.listdir(current_dir):
if file.endswith(".py"):
shutil.copy2(current_dir / file, project_dir / file)

# Copy launch script
shutil.copy2(
current_dir / "launch_microtvm_api_server.sh",
project_dir / "launch_microtvm_api_server.sh",
)

# Copy boards.json file to generated project.
shutil.copy2(BOARDS, project_dir / BOARDS.name)
Expand Down Expand Up @@ -660,8 +672,6 @@ def generate_project(self, model_library_format_path, standalone_crt_dir, projec
tf.extractall(project_dir)

def build(self, options):
verbose = options.get("verbose")

if BUILD_DIR.exists():
shutil.rmtree(BUILD_DIR)
BUILD_DIR.mkdir()
Expand All @@ -680,12 +690,7 @@ def build(self, options):
st.st_mode | stat.S_IEXEC,
)

check_call(["cmake", "-GNinja", ".."], cwd=BUILD_DIR, env=env)

args = ["ninja"]
if verbose:
args.append("-v")
check_call(args, cwd=BUILD_DIR, env=env)
check_call(options["west_cmd"].split(" ") + ["build"], cwd=API_SERVER_DIR, env=env)

# A list of all zephyr_board values which are known to launch using QEMU. Many platforms which
# launch through QEMU by default include "qemu" in their name. However, not all do. This list
Expand Down Expand Up @@ -748,15 +753,16 @@ def flash(self, options):
)

def open_transport(self, options):
west_cmd = options["west_cmd"]
zephyr_board = _find_board_from_cmake_file(API_SERVER_DIR / CMAKELIST_FILENAME)
emu_platform = _find_platform_from_cmake_file(API_SERVER_DIR / CMAKELIST_FILENAME)
if self._is_fvp(zephyr_board, emu_platform == "armfvp"):
arm_fvp_path = options["arm_fvp_path"]
verbose = options.get("verbose")
transport = ZephyrFvpTransport(arm_fvp_path, verbose)
transport = ZephyrFvpTransport(west_cmd, arm_fvp_path, verbose)
elif self._is_qemu(zephyr_board):
gdbserver_port = options.get("gdbserver_port")
transport = ZephyrQemuTransport(gdbserver_port)
transport = ZephyrQemuTransport(west_cmd, gdbserver_port)
else:
zephyr_base = options["zephyr_base"]
serial_number = options.get("serial_number")
Expand Down Expand Up @@ -921,13 +927,14 @@ class ZephyrQemuMakeResult(enum.Enum):
class ZephyrQemuTransport:
"""The user-facing Zephyr QEMU transport class."""

def __init__(self, gdbserver_port: int = None):
def __init__(self, west_cmd: str, gdbserver_port: int = None):
self._gdbserver_port = gdbserver_port
self.proc = None
self.pipe_dir = None
self.read_fd = None
self.write_fd = None
self._queue = queue.Queue()
self._west_cmd = west_cmd

def open(self):
with open(BUILD_DIR / "CMakeCache.txt", "r") as cmake_cache_f:
Expand All @@ -947,7 +954,7 @@ def open(self):
env["TVM_QEMU_GDBSERVER_PORT"] = self._gdbserver_port

self.proc = subprocess.Popen(
["ninja", "run"],
self._west_cmd.split(" ") + ["build", "-t", "run"],
cwd=BUILD_DIR,
env=env,
stdout=subprocess.PIPE,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,14 @@

#include <assert.h>
#include <float.h>
#include <kernel.h>
#include <stdio.h>
#include <string.h>
#include <sys/reboot.h>
#include <tvm/runtime/c_runtime_api.h>
#include <tvm/runtime/crt/logging.h>
#include <tvm/runtime/crt/stack_allocator.h>
#include <unistd.h>
#include <zephyr.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/reboot.h>

#include "input_data.h"
#include "output_data.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@
*/
#include "zephyr_uart.h"

#include <drivers/uart.h>
#include <sys/ring_buffer.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/sys/ring_buffer.h>

#include "crt_config.h"

Expand Down Expand Up @@ -76,7 +76,7 @@ uint32_t TVMPlatformWriteSerial(const char* data, uint32_t size) {
// Initialize UART
void TVMPlatformUARTInit() {
// Claim console device.
g_microtvm_uart = device_get_binding(DT_LABEL(DT_CHOSEN(zephyr_console)));
g_microtvm_uart = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
const struct uart_config config = {.baudrate = 115200,
.parity = UART_CFG_PARITY_NONE,
.stop_bits = UART_CFG_STOP_BITS_1,
Expand Down
22 changes: 11 additions & 11 deletions apps/microtvm/zephyr/template_project/src/host_driven/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,20 +28,20 @@
* intended to be a demonstration, since typically you will want to incorporate
* this logic into your own application.
*/
#include <drivers/gpio.h>
#include <drivers/uart.h>
#include <fatal.h>
#include <kernel.h>
#include <random/rand32.h>
#include <stdio.h>
#include <sys/printk.h>
#include <sys/reboot.h>
#include <sys/ring_buffer.h>
#include <timing/timing.h>
#include <string.h>
#include <tvm/runtime/crt/logging.h>
#include <tvm/runtime/crt/microtvm_rpc_server.h>
#include <unistd.h>
#include <zephyr.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/fatal.h>
#include <zephyr/kernel.h>
#include <zephyr/random/rand32.h>
#include <zephyr/sys/printk.h>
#include <zephyr/sys/reboot.h>
#include <zephyr/sys/ring_buffer.h>
#include <zephyr/timing/timing.h>

#ifdef FVP
#include "fvp/semihost.h"
Expand Down Expand Up @@ -253,7 +253,7 @@ void main(void) {
#endif

// Claim console device.
tvm_uart = device_get_binding(DT_LABEL(DT_CHOSEN(zephyr_console)));
tvm_uart = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
uart_rx_init(&uart_rx_rbuf, tvm_uart);

// Initialize system timing. We could stop and start it every time, but we'll
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@

#include "api/submitter_implemented.h"

#include <drivers/gpio.h>
#include <kernel.h>
#include <tvm/runtime/crt/platform.h>
#include <unistd.h>
#include <zephyr/drivers/gpio.h>
#include <zephyr/kernel.h>

#include "api/internally_implemented.h"
#include "tvmruntime.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@

#include <assert.h>
#include <float.h>
#include <kernel.h>
#include <math.h>
#include <power/reboot.h>
#include <stdint.h>
#include <stdio.h>
#include <tvm/runtime/c_runtime_api.h>
#include <tvm/runtime/crt/logging.h>
#include <tvm/runtime/crt/platform.h>
#include <tvm/runtime/crt/stack_allocator.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/reboot.h>

#include "output_data.h"
#include "tvmgen_default.h"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@

#include "zephyr_uart.h"

#include <drivers/uart.h>
#include <sys/ring_buffer.h>
#include <tvm/runtime/crt/error_codes.h>
#include <zephyr/drivers/uart.h>
#include <zephyr/sys/ring_buffer.h>

#include "crt_config.h"

Expand Down Expand Up @@ -79,7 +79,7 @@ uint32_t TVMPlatformWriteSerial(const char* data, uint32_t size) {
// Initialize UART.
void TVMPlatformUARTInit(uint32_t baudrate /* = TVM_UART_DEFAULT_BAUDRATE */) {
// Claim console device.
g_microtvm_uart = device_get_binding(DT_LABEL(DT_CHOSEN(zephyr_console)));
g_microtvm_uart = DEVICE_DT_GET(DT_CHOSEN(zephyr_console));
const struct uart_config config = {.baudrate = baudrate,
.parity = UART_CFG_PARITY_NONE,
.stop_bits = UART_CFG_STOP_BITS_1,
Expand Down
4 changes: 2 additions & 2 deletions apps/microtvm/zephyr_cmsisnn/src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/printk.h>
#include <tvm/runtime/c_runtime_api.h>
#include <tvm/runtime/crt/stack_allocator.h>
#include <zephyr.h>
#include <zephyr/kernel.h>
#include <zephyr/sys/printk.h>

#include "tvmgen_default.h"

Expand Down
2 changes: 1 addition & 1 deletion ci/jenkins/docker-images.ini
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
# This data file is read during when Jenkins runs job to determine docker images.
[jenkins]
ci_arm: tlcpack/ci-arm:20221013-060115-61c9742ea
ci_cortexm: tlcpack/ci-cortexm:20230116-133924-dad13d1c1
ci_cortexm: tlcpackstaging/ci_cortexm:20230124-233207-fd3f8035c
ci_cpu: tlcpack/ci-cpu:20230110-070003-d00168ffb
ci_gpu: tlcpack/ci-gpu:20221128-070141-ae4fd7df7
ci_hexagon: tlcpack/ci_hexagon:20230127-185848-95fa22308
Expand Down
2 changes: 2 additions & 0 deletions cmake/modules/Arduino.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ if(USE_MICRO)
APPEND
ARDUINO_FILE_COPY_JOBS
"apps/microtvm/arduino/template_project microtvm_api_server.py -> arduino"
"python/tvm/micro/project_api server.py -> arduino"
"apps/microtvm/arduino/template_project launch_microtvm_api_server.sh -> arduino"
"apps/microtvm/arduino/template_project boards.json -> arduino"
"apps/microtvm/arduino/template_project/src/example_project *.c -> arduino/src/example_project"
"apps/microtvm/arduino/template_project/src/example_project *.h -> arduino/src/example_project"
Expand Down
2 changes: 2 additions & 0 deletions cmake/modules/Zephyr.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ if(USE_MICRO)
APPEND
ZEPHYR_FILE_COPY_JOBS
"apps/microtvm/zephyr/template_project microtvm_api_server.py -> zephyr"
"python/tvm/micro/project_api server.py -> zephyr"
"apps/microtvm/zephyr/template_project launch_microtvm_api_server.sh -> zephyr"
"apps/microtvm/zephyr/template_project boards.json -> zephyr"
"apps/microtvm/zephyr/template_project CMakeLists.txt.template -> zephyr"
"apps/microtvm/zephyr/template_project/src/aot_standalone_demo *.c -> zephyr/src/aot_standalone_demo"
Expand Down
Loading

0 comments on commit d6f78b1

Please sign in to comment.