You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@tvm.apache.org by me...@apache.org on 2022/09/21 17:48:24 UTC
[tvm] 01/01: address comments
This is an automated email from the ASF dual-hosted git repository.
mehrdadh pushed a commit to branch micro/update_project_options
in repository https://gitbox.apache.org/repos/asf/tvm.git
commit 4c921e3ff5bf4e157e35eb33384c54cc604dc9ad
Author: Mehrdad Hessar <mh...@octoml.ai>
AuthorDate: Wed Sep 21 10:43:47 2022 -0700
address comments
---
.../arduino/template_project/Makefile.template | 21 ++--
.../template_project/microtvm_api_server.py | 109 ++++++++++++---------
python/tvm/micro/project_api/server.py | 21 +---
3 files changed, 80 insertions(+), 71 deletions(-)
diff --git a/apps/microtvm/arduino/template_project/Makefile.template b/apps/microtvm/arduino/template_project/Makefile.template
index 7a51f6adae..a22bd25300 100644
--- a/apps/microtvm/arduino/template_project/Makefile.template
+++ b/apps/microtvm/arduino/template_project/Makefile.template
@@ -15,7 +15,6 @@
# specific language governing permissions and limitations
# under the License.
-MAKE_DIR := $(PWD)
FQBN ?= <FQBN>
VERBOSE_FLAG ?= <VERBOSE_FLAG>
BUILD_DIR := $(subst :,.,build)
@@ -28,12 +27,13 @@ SRC := $(wildcard *.ino)
BIN := $(BUILD_DIR)/$(SRC).bin
ELF := $(BUILD_DIR)/$(SRC).elf
-$(info FQBN is [${FQBN}])
-$(info MAKE_DIR is [${MAKE_DIR}])
-$(info BUILD_DIR is [${BUILD_DIR}])
-$(info SRC is [${SRC}])
-$(info BIN is [${BIN}])
-$(info PORT is [${PORT}])
+$(info FQBN `fully qualified board name` => [${FQBN}])
+$(info BUILD_DIR `build directory for this project` => [${BUILD_DIR}])
+$(info SRC `Arduino .ino file for this project` => [${SRC}])
+$(info BIN `generated binary file path` => [${BIN}])
+$(info PORT `board's port` => [${PORT}])
+$(info BOARD `board name` => [${BOARD}])
+$(info BUILD_EXTRA_FLAGS `build extra flags including header include directories and other compiler flags` => [${BUILD_EXTRA_FLAGS}])
all: $(ELF) flash
.PHONY: all
@@ -53,5 +53,12 @@ flash:
else $(ARUINO_CLI_CMD) upload --fqbn $(FQBN) --input-dir $(BUILD_DIR) --port $(PORT) $(VERBOSE_FLAG); \
fi
+info:
+ $(info --------------------------------------INFO--------------------------------------)
+ $(info This makefile is for building and flashing an Arduino project with TVM.)
+ $(info To build run: `make build`)
+ $(info To upload the sketch run: `make flash PORT=<Arduino board port path>`)
+ $(info --------------------------------------INFO--------------------------------------)
+
clean:
rm -rf build
diff --git a/apps/microtvm/arduino/template_project/microtvm_api_server.py b/apps/microtvm/arduino/template_project/microtvm_api_server.py
index f75983bcc2..8de0bef47c 100644
--- a/apps/microtvm/arduino/template_project/microtvm_api_server.py
+++ b/apps/microtvm/arduino/template_project/microtvm_api_server.py
@@ -161,12 +161,6 @@ class Handler(server.ProjectAPIHandler):
"src/runtime/crt/tab",
]
- FQBN_TOKEN = "<FQBN>"
- VERBOSE_FLAG_TOKEN = "<VERBOSE_FLAG>"
- ARUINO_CLI_CMD_TOKEN = "<ARUINO_CLI_CMD>"
- BOARD_TOKEN = "<BOARD>"
- BUILD_EXTRA_FLAGS_TOKEN = "<BUILD_EXTRA_FLAGS>"
-
def _remove_unused_components(self, source_dir, project_type):
unused_components = []
if project_type == "example_project":
@@ -304,43 +298,80 @@ class Handler(server.ProjectAPIHandler):
# It's probably a standard C/C++ header
return include_path
- def _cmsis_required(self, project_path: Union[str, pathlib.Path]) -> bool:
+ CMSIS_INCLUDE_HEADERS = [
+ "arm_nn_math_types.h",
+ "arm_nn_tables.h",
+ "arm_nn_types.h",
+ "arm_nnfunctions.h",
+ "arm_nnsupportfunctions.h",
+ ]
+
+ def _cmsis_required(self, project_path: pathlib.Path) -> bool:
"""Check if CMSIS dependency is required."""
project_path = pathlib.Path(project_path)
for path in (project_path / "src" / "model").iterdir():
if path.is_file():
+ # Encoding is for reading C generated code which also includes hex numbers
with open(path, "r", encoding="ISO-8859-1") as lib_f:
lib_content = lib_f.read()
- if any(
- header in lib_content
- for header in [
- "<arm_nnsupportfunctions.h>",
- "arm_nn_types.h",
- "arm_nnfunctions.h",
- ]
- ):
+ if any(header in lib_content for header in self.CMSIS_INCLUDE_HEADERS):
return True
return False
- def _copy_cmsis(self, project_path: Union[str, pathlib.Path], cmsis_path: str):
+ def _copy_cmsis(self, project_path: pathlib.Path, cmsis_path: str):
"""Copy CMSIS header files to project.
Note: We use this CMSIS package:https://www.arduino.cc/reference/en/libraries/arduino_cmsis-dsp/
However, the latest release does not include header files that are copied in this function.
"""
(project_path / "include" / "cmsis").mkdir()
cmsis_path = get_cmsis_path(cmsis_path)
- for item in [
- "arm_nn_types.h",
- "arm_nn_tables.h",
- "arm_nnsupportfunctions.h",
- "arm_nn_math_types.h",
- "arm_nnfunctions.h",
- ]:
+ for item in self.CMSIS_INCLUDE_HEADERS:
shutil.copy2(
cmsis_path / "CMSIS" / "NN" / "Include" / item,
project_path / "include" / "cmsis" / item,
)
+ # These tokens are used in the Makefile.template file.
+ # They are replaced with proper value in generate_project step.
+ FQBN_TOKEN = "<FQBN>"
+ VERBOSE_FLAG_TOKEN = "<VERBOSE_FLAG>"
+ ARUINO_CLI_CMD_TOKEN = "<ARUINO_CLI_CMD>"
+ BOARD_TOKEN = "<BOARD>"
+ BUILD_EXTRA_FLAGS_TOKEN = "<BUILD_EXTRA_FLAGS>"
+
+ def _populate_makefile(
+ self,
+ makefile_template_path: pathlib.Path,
+ makefile_path: pathlib.Path,
+ board: str,
+ verbose: bool,
+ arduino_cli_cmd: str,
+ build_extra_flags: str,
+ ):
+ """Generate Makefile from template."""
+ with open(makefile_path, "w") as makefile_f:
+ with open(makefile_template_path, "r") as makefile_template_f:
+ for line in makefile_template_f:
+ if self.FQBN_TOKEN in line:
+ line = line.replace(self.FQBN_TOKEN, self._get_fqbn(board))
+
+ if self.VERBOSE_FLAG_TOKEN in line:
+ if verbose:
+ flag = "--verbose"
+ else:
+ flag = ""
+ line = line.replace(self.VERBOSE_FLAG_TOKEN, flag)
+ if self.ARUINO_CLI_CMD_TOKEN in line:
+ line = line.replace(
+ self.ARUINO_CLI_CMD_TOKEN, self._get_arduino_cli_cmd(arduino_cli_cmd)
+ )
+ if self.BOARD_TOKEN in line:
+ line = line.replace(self.BOARD_TOKEN, board)
+ if self.BUILD_EXTRA_FLAGS_TOKEN in line:
+ line = line.replace(self.BUILD_EXTRA_FLAGS_TOKEN, build_extra_flags)
+
+ makefile_f.write(line)
+
def generate_project(self, model_library_format_path, standalone_crt_dir, project_dir, options):
# List all used project options
board = options["board"]
@@ -393,28 +424,14 @@ class Handler(server.ProjectAPIHandler):
self._copy_cmsis(project_dir, cmsis_path)
# Populate Makefile
- with open(project_dir / MAKEFILE_FILENAME, "w") as makefile_f:
- with open(API_SERVER_DIR / f"{MAKEFILE_FILENAME}.template", "r") as makefile_template_f:
- for line in makefile_template_f:
- if self.FQBN_TOKEN in line:
- line = line.replace(self.FQBN_TOKEN, self._get_fqbn(board))
-
- if self.VERBOSE_FLAG_TOKEN in line:
- if verbose:
- flag = "--verbose"
- else:
- flag = ""
- line = line.replace(self.VERBOSE_FLAG_TOKEN, flag)
- if self.ARUINO_CLI_CMD_TOKEN in line:
- line = line.replace(
- self.ARUINO_CLI_CMD_TOKEN, self._get_arduino_cli_cmd(arduino_cli_cmd)
- )
- if self.BOARD_TOKEN in line:
- line = line.replace(self.BOARD_TOKEN, board)
- if self.BUILD_EXTRA_FLAGS_TOKEN in line:
- line = line.replace(self.BUILD_EXTRA_FLAGS_TOKEN, build_extra_flags)
-
- makefile_f.write(line)
+ self._populate_makefile(
+ API_SERVER_DIR / f"{MAKEFILE_FILENAME}.template",
+ project_dir / MAKEFILE_FILENAME,
+ board,
+ verbose,
+ arduino_cli_cmd,
+ build_extra_flags,
+ )
def _get_arduino_cli_cmd(self, arduino_cli_cmd: str):
if not arduino_cli_cmd:
@@ -526,7 +543,7 @@ class Handler(server.ProjectAPIHandler):
with open(makefile_path) as makefile_f:
line = makefile_f.readline()
if "BOARD" in line:
- board = line.replace(" ", "").replace("\n", "").replace("\r", "").split(":=")[1]
+ board = re.sub(r"\s", "", line).split(":=")[1]
return board
raise RuntimeError("Board was not found in Makefile: {}".format(makefile_path))
diff --git a/python/tvm/micro/project_api/server.py b/python/tvm/micro/project_api/server.py
index e36cd0c699..a354abf5e9 100644
--- a/python/tvm/micro/project_api/server.py
+++ b/python/tvm/micro/project_api/server.py
@@ -64,25 +64,10 @@ class ProjectOption(_ProjectOption):
return super().__new__(cls, **kw)
- def replace(self, **kw):
+ def replace(self, kw):
"""Update attributes associated to the project option."""
updated_option = self
- for key, val in kw.items():
- if key == "choices":
- updated_option = updated_option._replace(choices=val)
- elif key == "default":
- updated_option = updated_option._replace(default=val)
- elif key == "type":
- updated_option = updated_option._replace(type=val)
- elif key == "required":
- updated_option = updated_option._replace(required=val)
- elif key == "optional":
- updated_option = updated_option._replace(optional=val)
- elif key == "help":
- updated_option = updated_option._replace(help=val)
- else:
- raise ValueError("Attribute {} is not supported.".format(key))
- return updated_option
+ return updated_option._replace(**kw)
ServerInfo = collections.namedtuple(
@@ -832,7 +817,7 @@ def default_project_options(**kw) -> typing.List[ProjectOption]:
option_found = False
for ind, option in enumerate(options):
if option.name == name:
- options[ind] = option.replace(**config)
+ options[ind] = option.replace(config)
option_found = True
break
if not option_found: