Skip to content

Commit

Permalink
[microTVM] Remove Arduino aot code (apache#8869)
Browse files Browse the repository at this point in the history
* Fix Arduino DLDevice includes

* microtvm_api_server fails if commands fail

* Add regression test for microtvm_api_server not failing

* Address PR comments

Break error detection tests into separate file

Address comments from Mousius

Re-add necessary fixture
  • Loading branch information
guberti authored and ylc committed Jan 13, 2022
1 parent 0cca793 commit 0778945
Show file tree
Hide file tree
Showing 7 changed files with 105 additions and 49 deletions.
2 changes: 1 addition & 1 deletion apps/microtvm/arduino/example_project/src/model.c
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@
#include "model.h"

#include "Arduino.h"
#include "standalone_crt/include/dlpack/dlpack.h"
#include "standalone_crt/include/tvm/runtime/crt/stack_allocator.h"

// AOT memory array
static uint8_t g_aot_memory[WORKSPACE_SIZE];
extern tvm_model_t tvmgen_default_network;
tvm_workspace_t app_workspace;

// Blink code for debugging purposes
Expand Down
2 changes: 2 additions & 0 deletions apps/microtvm/arduino/host_driven/src/model_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@
* under the License.
*/

#include "standalone_crt/include/dlpack/dlpack.h"
#include "standalone_crt/include/tvm/runtime/crt/error_codes.h"
#include "stdarg.h"

// Blink code for debugging purposes
Expand Down
8 changes: 5 additions & 3 deletions apps/microtvm/arduino/template_project/microtvm_api_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -370,7 +370,7 @@ def build(self, options):
compile_cmd.append("--verbose")

# Specify project to compile
subprocess.run(compile_cmd)
subprocess.run(compile_cmd, check=True)

BOARD_LIST_HEADERS = ("Port", "Type", "Board Name", "FQBN", "Core")

Expand Down Expand Up @@ -407,7 +407,9 @@ def _parse_boards_tabular_str(self, tabular_str):

def _auto_detect_port(self, options):
list_cmd = [options["arduino_cli_cmd"], "board", "list"]
list_cmd_output = subprocess.run(list_cmd, stdout=subprocess.PIPE).stdout.decode("utf-8")
list_cmd_output = subprocess.run(
list_cmd, check=True, stdout=subprocess.PIPE
).stdout.decode("utf-8")

desired_fqbn = self._get_fqbn(options)
for line in self._parse_boards_tabular_str(list_cmd_output):
Expand Down Expand Up @@ -444,7 +446,7 @@ def flash(self, options):
if options.get("verbose"):
upload_cmd.append("--verbose")

subprocess.run(upload_cmd)
subprocess.run(upload_cmd, check=True)

def open_transport(self, options):
# Zephyr example doesn't throw an error in this case
Expand Down
40 changes: 40 additions & 0 deletions tests/micro/arduino/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@

import pytest
import tvm.target.target
from tvm import micro, relay

# The models that should pass this configuration. Maps a short, identifying platform string to
# (model, zephyr_board).
Expand Down Expand Up @@ -122,3 +123,42 @@ def make_workspace_dir(test_name, platform):
t = tvm.contrib.utils.tempdir(board_workspace)
# time.sleep(200)
return t


def make_kws_project(platform, arduino_cli_cmd, tvm_debug, workspace_dir):
this_dir = pathlib.Path(__file__).parent
model, arduino_board = PLATFORMS[platform]
build_config = {"debug": tvm_debug}

with open(this_dir.parent / "testdata" / "kws" / "yes_no.tflite", "rb") as f:
tflite_model_buf = f.read()

# TFLite.Model.Model has changed to TFLite.Model from 1.14 to 2.1
try:
import tflite.Model

tflite_model = tflite.Model.Model.GetRootAsModel(tflite_model_buf, 0)
except AttributeError:
import tflite

tflite_model = tflite.Model.GetRootAsModel(tflite_model_buf, 0)

mod, params = relay.frontend.from_tflite(tflite_model)
target = tvm.target.target.micro(
model, options=["--link-params=1", "--unpacked-api=1", "--executor=aot"]
)

with tvm.transform.PassContext(opt_level=3, config={"tir.disable_vectorize": True}):
mod = relay.build(mod, target, params=params)

return tvm.micro.generate_project(
str(TEMPLATE_PROJECT_DIR),
mod,
workspace_dir / "project",
{
"arduino_board": arduino_board,
"arduino_cli_cmd": arduino_cli_cmd,
"project_type": "example_project",
"verbose": bool(build_config.get("debug")),
},
)
52 changes: 52 additions & 0 deletions tests/micro/arduino/test_arduino_error_detection.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
# 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.

import pathlib
import re
import sys

import pytest

import conftest
from tvm.micro.project_api.server import ServerError


# A new project and workspace dir is created for EVERY test
@pytest.fixture
def workspace_dir(request, platform):
return conftest.make_workspace_dir("arduino_error_detection", platform)


@pytest.fixture
def project(platform, arduino_cli_cmd, tvm_debug, workspace_dir):
return conftest.make_kws_project(platform, arduino_cli_cmd, tvm_debug, workspace_dir)


def test_blank_project_compiles(workspace_dir, project):
project.build()


# Add a bug (an extra curly brace) and make sure the project doesn't compile
def test_bugged_project_compile_fails(workspace_dir, project):
with open(workspace_dir / "project" / "project.ino", "a") as main_file:
main_file.write("}\n")
with pytest.raises(ServerError):
project.build()


if __name__ == "__main__":
sys.exit(pytest.main([__file__] + sys.argv[1:]))
4 changes: 2 additions & 2 deletions tests/micro/arduino/test_arduino_rpc_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@
import conftest


# We'll make a new workspace for each test
@pytest.fixture(scope="function")
# # A new project and workspace dir is created for EVERY test
@pytest.fixture
def workspace_dir(platform):
return conftest.make_workspace_dir("arduino_rpc_server", platform)

Expand Down
46 changes: 3 additions & 43 deletions tests/micro/arduino/test_arduino_workflow.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,6 @@
import sys

import pytest
import tvm
from tvm import micro, relay

import conftest

Expand All @@ -38,7 +36,8 @@
"""


# Since these tests are sequential, we'll use the same project for all tests
# Since these tests are sequential, we'll use the same project/workspace
# directory for all tests in this file
@pytest.fixture(scope="module")
def workspace_dir(request, platform):
return conftest.make_workspace_dir("arduino_workflow", platform)
Expand All @@ -49,49 +48,10 @@ def project_dir(workspace_dir):
return workspace_dir / "project"


def _generate_project(arduino_board, arduino_cli_cmd, workspace_dir, mod, build_config):
return tvm.micro.generate_project(
str(conftest.TEMPLATE_PROJECT_DIR),
mod,
workspace_dir / "project",
{
"arduino_board": arduino_board,
"arduino_cli_cmd": arduino_cli_cmd,
"project_type": "example_project",
"verbose": bool(build_config.get("debug")),
},
)


# We MUST pass workspace_dir, not project_dir, or the workspace will be dereferenced too soon
@pytest.fixture(scope="module")
def project(platform, arduino_cli_cmd, tvm_debug, workspace_dir):
this_dir = pathlib.Path(__file__).parent
model, arduino_board = conftest.PLATFORMS[platform]
build_config = {"debug": tvm_debug}

with open(this_dir.parent / "testdata" / "kws" / "yes_no.tflite", "rb") as f:
tflite_model_buf = f.read()

# TFLite.Model.Model has changed to TFLite.Model from 1.14 to 2.1
try:
import tflite.Model

tflite_model = tflite.Model.Model.GetRootAsModel(tflite_model_buf, 0)
except AttributeError:
import tflite

tflite_model = tflite.Model.GetRootAsModel(tflite_model_buf, 0)

mod, params = relay.frontend.from_tflite(tflite_model)
target = tvm.target.target.micro(
model, options=["--link-params=1", "--unpacked-api=1", "--executor=aot"]
)

with tvm.transform.PassContext(opt_level=3, config={"tir.disable_vectorize": True}):
mod = relay.build(mod, target, params=params)

return _generate_project(arduino_board, arduino_cli_cmd, workspace_dir, mod, build_config)
return conftest.make_kws_project(platform, arduino_cli_cmd, tvm_debug, workspace_dir)


def _get_directory_elements(directory):
Expand Down

0 comments on commit 0778945

Please sign in to comment.