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:23 UTC

[tvm] branch micro/update_project_options created (now 4c921e3ff5)

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

mehrdadh pushed a change to branch micro/update_project_options
in repository https://gitbox.apache.org/repos/asf/tvm.git


      at 4c921e3ff5 address comments

This branch includes the following new commits:

     new 4c921e3ff5 address comments

The 1 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.



[tvm] 01/01: address comments

Posted by me...@apache.org.
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: