From d486d4c98fca6bc3ed5421909a385e22df497172 Mon Sep 17 00:00:00 2001 From: Mehrdad Hessar Date: Wed, 15 Sep 2021 00:22:44 -0700 Subject: [PATCH 1/6] fix test and cleanup --- python/tvm/micro/session.py | 12 ++++++++---- python/tvm/micro/testing.py | 30 ++++++++++++++++++++++++++++++ src/runtime/rpc/rpc_endpoint.cc | 6 +++--- src/runtime/rpc/rpc_endpoint.h | 8 ++++---- tests/micro/zephyr/test_zephyr.py | 13 +++++++++++-- tests/python/unittest/test_crt.py | 11 +++++------ 6 files changed, 61 insertions(+), 19 deletions(-) create mode 100644 python/tvm/micro/testing.py diff --git a/python/tvm/micro/session.py b/python/tvm/micro/session.py index ced20b7ebfbf..b9ffe25f8e6b 100644 --- a/python/tvm/micro/session.py +++ b/python/tvm/micro/session.py @@ -87,6 +87,8 @@ def __init__( self._rpc = None self._graph_executor = None + self._exit_called = False + def get_system_lib(self): return self._rpc.get_function("runtime.SystemLib")() @@ -130,7 +132,7 @@ def __enter__(self): int(timeouts.session_start_retry_timeout_sec * 1e6), int(timeouts.session_start_timeout_sec * 1e6), int(timeouts.session_established_timeout_sec * 1e6), - self._shutdown, + self._cleanup, ) ) self.device = self._rpc.cpu(0) @@ -144,8 +146,10 @@ def __exit__(self, exc_type, exc_value, exc_traceback): """Tear down this session and associated RPC session resources.""" self.transport.__exit__(exc_type, exc_value, exc_traceback) - def _shutdown(self): - self.__exit__(None, None, None) + def _cleanup(self): + if not self._exit_called: + self._exit_called = True + self.__exit__(None, None, None) def lookup_remote_linked_param(mod, storage_id, template_tensor, device): @@ -289,6 +293,6 @@ def compile_and_create_micro_session( transport = generated_project.transport() rpc_session = Session(transport_context_manager=transport) - # RPC exit is called by shutdown function. + # RPC exit is called by cleanup function. rpc_session.__enter__() return rpc_session._rpc._sess diff --git a/python/tvm/micro/testing.py b/python/tvm/micro/testing.py new file mode 100644 index 000000000000..a22f3be3d35b --- /dev/null +++ b/python/tvm/micro/testing.py @@ -0,0 +1,30 @@ +# 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 json +from typing import Union + +def _check_tune_log(log_path: Union[pathlib.Path, str]): + """Reads tune log and check each result""" + results = [] + with open(log_path, "r") as f: + results.append(json.loads(f.readline())) + + for item in results: + tune_result = item["result"] + assert tune_result[0][0] < 1000000000.0 diff --git a/src/runtime/rpc/rpc_endpoint.cc b/src/runtime/rpc/rpc_endpoint.cc index 2f1fc54f39d0..d76ce61c489d 100644 --- a/src/runtime/rpc/rpc_endpoint.cc +++ b/src/runtime/rpc/rpc_endpoint.cc @@ -692,12 +692,12 @@ void RPCEndpoint::Init() { */ std::shared_ptr RPCEndpoint::Create(std::unique_ptr channel, std::string name, std::string remote_key, - TypedPackedFunc fshutdown) { + TypedPackedFunc fcleanup) { std::shared_ptr endpt = std::make_shared(); endpt->channel_ = std::move(channel); endpt->name_ = std::move(name); endpt->remote_key_ = std::move(remote_key); - endpt->fshutdown_ = fshutdown; + endpt->fcleanup_ = fcleanup; endpt->Init(); return endpt; } @@ -736,7 +736,7 @@ void RPCEndpoint::ServerLoop() { (*f)(); } channel_.reset(nullptr); - if (fshutdown_ != nullptr) fshutdown_(); + if (fcleanup_ != nullptr) fcleanup_(); } int RPCEndpoint::ServerAsyncIOEventHandler(const std::string& in_bytes, int event_flag) { diff --git a/src/runtime/rpc/rpc_endpoint.h b/src/runtime/rpc/rpc_endpoint.h index f6784faba0f6..19611a3fe61b 100644 --- a/src/runtime/rpc/rpc_endpoint.h +++ b/src/runtime/rpc/rpc_endpoint.h @@ -161,13 +161,13 @@ class RPCEndpoint { * \param channel The communication channel. * \param name The local name of the session, used for debug * \param remote_key The remote key of the session - * \param fshutdown The shutdown Packed function + * \param fcleanup The cleanup Packed function * if remote_key equals "%toinit", we need to re-intialize * it by event handler. */ static std::shared_ptr Create(std::unique_ptr channel, std::string name, std::string remote_key, - TypedPackedFunc fshutdown = nullptr); + TypedPackedFunc fcleanup = nullptr); private: class EventHandler; @@ -192,8 +192,8 @@ class RPCEndpoint { std::string name_; // The remote key std::string remote_key_; - // The shutdown Packed Function - TypedPackedFunc fshutdown_; + // Invoked when the RPC session is terminated + TypedPackedFunc fcleanup_; }; /*! diff --git a/tests/micro/zephyr/test_zephyr.py b/tests/micro/zephyr/test_zephyr.py index d2d5522b1a0a..4f5d4736a8d0 100644 --- a/tests/micro/zephyr/test_zephyr.py +++ b/tests/micro/zephyr/test_zephyr.py @@ -21,6 +21,7 @@ import subprocess import sys import logging +import json import pytest import numpy as np @@ -38,6 +39,8 @@ from tvm.relay.expr_functor import ExprMutator from tvm.relay.op.annotation import compiler_begin, compiler_end +from tvm.micro.testing import _check_tune_log + import conftest _LOG = logging.getLogger(__name__) @@ -430,13 +433,18 @@ def test_autotune_conv2d(temp_dir, board, west_cmd, tvm_debug): "project_type": "host_driven", }, ) + + timeout = 200 builder = tvm.autotvm.LocalBuilder( + timeout=timeout, n_parallel=1, build_kwargs={"build_option": {"tir.disable_vectorize": True}}, do_fork=True, build_func=tvm.micro.autotvm_build_func, ) - runner = tvm.autotvm.LocalRunner(number=1, repeat=1, timeout=100, module_loader=module_loader) + runner = tvm.autotvm.LocalRunner( + number=1, repeat=1, timeout=timeout, module_loader=module_loader + ) measure_option = tvm.autotvm.measure_option(builder=builder, runner=runner) @@ -456,8 +464,9 @@ def test_autotune_conv2d(temp_dir, board, west_cmd, tvm_debug): ], si_prefix="M", ) + assert tuner.best_flops > 0 - assert tuner.best_flops > 0 + _check_tune_log(log_path) # Build without tuning with pass_context: diff --git a/tests/python/unittest/test_crt.py b/tests/python/unittest/test_crt.py index af14a38c9f9a..487bfd454105 100644 --- a/tests/python/unittest/test_crt.py +++ b/tests/python/unittest/test_crt.py @@ -15,18 +15,14 @@ # specific language governing permissions and limitations # under the License. -import contextlib -import copy -import glob import os import pathlib import pytest import shutil +import json pytest.importorskip("pty") import sys -import subprocess -import textwrap import numpy as np import pytest @@ -39,6 +35,8 @@ from tvm.topi.utils import get_const_tuple from tvm.topi.testing import conv2d_nchw_python +from tvm.micro.testing import _check_tune_log + BUILD = True DEBUG = False @@ -285,8 +283,9 @@ def test_autotune(): ], si_prefix="M", ) + assert tuner.best_flops > 0 - assert tuner.best_flops > 0 + _check_tune_log(tune_log_file) # Build without tuning with pass_context: From 2da1a7a366afde245310ef131d83c9a698d9c215 Mon Sep 17 00:00:00 2001 From: Mehrdad Hessar Date: Wed, 15 Sep 2021 07:42:27 -0700 Subject: [PATCH 2/6] fix tutorial doc --- python/tvm/micro/testing.py | 3 +++ tutorials/micro/micro_autotune.py | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/python/tvm/micro/testing.py b/python/tvm/micro/testing.py index a22f3be3d35b..32995a64618e 100644 --- a/python/tvm/micro/testing.py +++ b/python/tvm/micro/testing.py @@ -15,10 +15,13 @@ # specific language governing permissions and limitations # under the License. +"""Defines testing methods used with microTVM.""" + import pathlib import json from typing import Union + def _check_tune_log(log_path: Union[pathlib.Path, str]): """Reads tune log and check each result""" results = [] diff --git a/tutorials/micro/micro_autotune.py b/tutorials/micro/micro_autotune.py index f89432ff01cf..ccc515f5c417 100644 --- a/tutorials/micro/micro_autotune.py +++ b/tutorials/micro/micro_autotune.py @@ -20,7 +20,9 @@ Autotuning with micro TVM ========================= -**Author**: `Andrew Reusch `_, `Mehrdad Hessar ` +**Authors**: +`Andrew Reusch `_, +`Mehrdad Hessar `_ This tutorial explains how to autotune a model using the C runtime. """ From f6d2b5f0f8e9d3be7b09bca0e4dc0e94cff6f1ce Mon Sep 17 00:00:00 2001 From: Mehrdad Hessar Date: Wed, 15 Sep 2021 09:15:01 -0700 Subject: [PATCH 3/6] fix verbose for tutorial --- src/runtime/crt/host/Makefile | 8 ++++++-- src/runtime/crt/host/microtvm_api_server.py | 8 ++++++-- tutorials/micro/micro_autotune.py | 20 +++++++++++++------- 3 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/runtime/crt/host/Makefile b/src/runtime/crt/host/Makefile index efed3c438699..858ed52958f8 100644 --- a/src/runtime/crt/host/Makefile +++ b/src/runtime/crt/host/Makefile @@ -28,7 +28,11 @@ CC ?= ${PREFIX}gcc CXX ?= ${PREFIX}g++ RANLIB ?= ${PREFIX}ranlib -QUIET ?= @ +$(ifeq VERBOSE,1) +QUIET ?= +$(else) +QUIET = @ +$(endif) PWD = $(shell pwd) BUILD_DIR = build @@ -38,7 +42,7 @@ CRT_LIBS = $(patsubst %, $(BUILD_DIR)/crt/lib%.a, $(CRT_LIB_NAMES)) CRT_INCLUDES = $(glob crt/include/**) $(BUILD_DIR)/crt/lib%.a: $(glob crt/src/runtime/%/*.c) - ${QUIET}cd crt && $(MAKE) \ + ${QUIET}cd crt && $(MAKE) -s \ BUILD_DIR=../$(BUILD_DIR)/crt \ CRT_CONFIG=$(PWD)/crt_config/crt_config.h \ EXTRA_CFLAGS="$(CFLAGS)" \ diff --git a/src/runtime/crt/host/microtvm_api_server.py b/src/runtime/crt/host/microtvm_api_server.py index 5f9019817e82..546ac1448011 100644 --- a/src/runtime/crt/host/microtvm_api_server.py +++ b/src/runtime/crt/host/microtvm_api_server.py @@ -51,7 +51,11 @@ def server_info_query(self, tvm_version): model_library_format_path="" if IS_TEMPLATE else PROJECT_DIR / MODEL_LIBRARY_FORMAT_RELPATH, - project_options=[server.ProjectOption("verbose", help="Run make with verbose output")], + project_options=[ + server.ProjectOption( + "verbose", help="Run make with verbose output", choices=(True, False) + ) + ], ) # These files and directories will be recursively copied into generated projects from the CRT. @@ -111,7 +115,7 @@ def generate_project(self, model_library_format_path, standalone_crt_dir, projec def build(self, options): args = ["make"] if options.get("verbose"): - args.append("QUIET=") + args.append("VERBOSE=1") args.append(self.BUILD_TARGET) diff --git a/tutorials/micro/micro_autotune.py b/tutorials/micro/micro_autotune.py index ccc515f5c417..a10a537b608c 100644 --- a/tutorials/micro/micro_autotune.py +++ b/tutorials/micro/micro_autotune.py @@ -119,7 +119,7 @@ module_loader = tvm.micro.AutoTvmModuleLoader( template_project_dir=repo_root / "src" / "runtime" / "crt" / "host", - project_options={}, + project_options={"verbose": False}, ) builder = tvm.autotvm.LocalBuilder( n_parallel=1, @@ -138,7 +138,7 @@ # project_options={ # "zephyr_board": BOARD, # "west_cmd": "west", -# "verbose": 1, +# "verbose": False, # "project_type": "host_driven", # }, # ) @@ -150,7 +150,7 @@ # ) # runner = tvm.autotvm.LocalRunner(number=1, repeat=1, timeout=100, module_loader=module_loader) -# measure_option = tvm.autotvm.measure_option(builder=builder, runner=runner) +# measure_option = tvm.autotvm.measure_option(builder=builder, runner=runner) ################ # Run Autotuning @@ -183,7 +183,10 @@ temp_dir = tvm.contrib.utils.tempdir() project = tvm.micro.generate_project( - str(repo_root / "src" / "runtime" / "crt" / "host"), lowered, temp_dir / "project" + str(repo_root / "src" / "runtime" / "crt" / "host"), + lowered, + temp_dir / "project", + {"verbose": False}, ) # Compiling for physical hardware @@ -195,7 +198,7 @@ # { # "zephyr_board": BOARD, # "west_cmd": "west", -# "verbose": 1, +# "verbose": False, # "project_type": "host_driven", # }, # ) @@ -223,7 +226,10 @@ temp_dir = tvm.contrib.utils.tempdir() project = tvm.micro.generate_project( - str(repo_root / "src" / "runtime" / "crt" / "host"), lowered_tuned, temp_dir / "project" + str(repo_root / "src" / "runtime" / "crt" / "host"), + lowered_tuned, + temp_dir / "project", + {"verbose": False}, ) # Compiling for physical hardware @@ -235,7 +241,7 @@ # { # "zephyr_board": BOARD, # "west_cmd": "west", -# "verbose": 1, +# "verbose": False, # "project_type": "host_driven", # }, # ) From 607af0961eba41d0206f45025638c468d545133c Mon Sep 17 00:00:00 2001 From: Mehrdad Hessar Date: Wed, 15 Sep 2021 11:27:09 -0700 Subject: [PATCH 4/6] fix tune check --- python/tvm/micro/testing.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/python/tvm/micro/testing.py b/python/tvm/micro/testing.py index 32995a64618e..c2c67347759c 100644 --- a/python/tvm/micro/testing.py +++ b/python/tvm/micro/testing.py @@ -26,7 +26,10 @@ def _check_tune_log(log_path: Union[pathlib.Path, str]): """Reads tune log and check each result""" results = [] with open(log_path, "r") as f: - results.append(json.loads(f.readline())) + line = f.readline() + while line: + results.append(json.loads(line)) + line = f.readline() for item in results: tune_result = item["result"] From c5e8ee02679ac108977ddb6a5037ded97d569d4e Mon Sep 17 00:00:00 2001 From: Mehrdad Hessar Date: Thu, 16 Sep 2021 09:15:31 -0700 Subject: [PATCH 5/6] address comments --- python/tvm/micro/session.py | 8 ++++---- python/tvm/micro/testing.py | 15 ++++++--------- src/runtime/crt/host/Makefile | 10 +++++----- src/runtime/rpc/rpc_endpoint.cc | 9 +++++---- src/runtime/rpc/rpc_endpoint.h | 2 +- tests/micro/zephyr/test_zephyr.py | 4 ++-- tests/python/unittest/test_crt.py | 4 ++-- tutorials/micro/micro_autotune.py | 2 +- 8 files changed, 26 insertions(+), 28 deletions(-) diff --git a/python/tvm/micro/session.py b/python/tvm/micro/session.py index b9ffe25f8e6b..d545f2e7daa4 100644 --- a/python/tvm/micro/session.py +++ b/python/tvm/micro/session.py @@ -144,12 +144,12 @@ def __enter__(self): def __exit__(self, exc_type, exc_value, exc_traceback): """Tear down this session and associated RPC session resources.""" - self.transport.__exit__(exc_type, exc_value, exc_traceback) - - def _cleanup(self): if not self._exit_called: self._exit_called = True - self.__exit__(None, None, None) + self.transport.__exit__(exc_type, exc_value, exc_traceback) + + def _cleanup(self): + self.__exit__(None, None, None) def lookup_remote_linked_param(mod, storage_id, template_tensor, device): diff --git a/python/tvm/micro/testing.py b/python/tvm/micro/testing.py index c2c67347759c..5fd5ed3f4ee2 100644 --- a/python/tvm/micro/testing.py +++ b/python/tvm/micro/testing.py @@ -22,15 +22,12 @@ from typing import Union -def _check_tune_log(log_path: Union[pathlib.Path, str]): +def check_tune_log(log_path: Union[pathlib.Path, str]): """Reads tune log and check each result""" - results = [] with open(log_path, "r") as f: - line = f.readline() - while line: - results.append(json.loads(line)) - line = f.readline() + lines = f.readlines() - for item in results: - tune_result = item["result"] - assert tune_result[0][0] < 1000000000.0 + for line in lines: + if len(line) > 0: + tune_result = json.loads(line) + assert tune_result["result"][0][0] < 1000000000.0 diff --git a/src/runtime/crt/host/Makefile b/src/runtime/crt/host/Makefile index 858ed52958f8..98a810e0d1b1 100644 --- a/src/runtime/crt/host/Makefile +++ b/src/runtime/crt/host/Makefile @@ -28,11 +28,11 @@ CC ?= ${PREFIX}gcc CXX ?= ${PREFIX}g++ RANLIB ?= ${PREFIX}ranlib -$(ifeq VERBOSE,1) -QUIET ?= -$(else) -QUIET = @ -$(endif) +ifeq (${VERBOSE}, 1) +QUIET ?= +else +QUIET ?= @ +endif PWD = $(shell pwd) BUILD_DIR = build diff --git a/src/runtime/rpc/rpc_endpoint.cc b/src/runtime/rpc/rpc_endpoint.cc index d76ce61c489d..07b90058ce99 100644 --- a/src/runtime/rpc/rpc_endpoint.cc +++ b/src/runtime/rpc/rpc_endpoint.cc @@ -684,11 +684,12 @@ void RPCEndpoint::Init() { /*! * \brief Create a new RPCEndpoint instance. - * \param channel RPCChannel used to communicate + * \param channel RPCChannel used to communicate. * \param name Name of this session, used to identify log messages from this RPCEndpoint instance. - * \param The remote key reported during protocol initialization, or "%toinit" if the RPCEndpoint - * should handle this phase of the protocol for you. Some servers may prefer to access parts of - * the key to modify their behavior. + * \param remote_key The remote key reported during protocol initialization, or "%toinit" if the + * RPCEndpoint should handle this phase of the protocol for you. Some servers may prefer to access + * parts of the key to modify their behavior. + * \param fcleanup The cleanup Packed function. */ std::shared_ptr RPCEndpoint::Create(std::unique_ptr channel, std::string name, std::string remote_key, diff --git a/src/runtime/rpc/rpc_endpoint.h b/src/runtime/rpc/rpc_endpoint.h index 19611a3fe61b..ed19a3f59e58 100644 --- a/src/runtime/rpc/rpc_endpoint.h +++ b/src/runtime/rpc/rpc_endpoint.h @@ -161,9 +161,9 @@ class RPCEndpoint { * \param channel The communication channel. * \param name The local name of the session, used for debug * \param remote_key The remote key of the session - * \param fcleanup The cleanup Packed function * if remote_key equals "%toinit", we need to re-intialize * it by event handler. + * \param fcleanup The cleanup Packed function. */ static std::shared_ptr Create(std::unique_ptr channel, std::string name, std::string remote_key, diff --git a/tests/micro/zephyr/test_zephyr.py b/tests/micro/zephyr/test_zephyr.py index 4f5d4736a8d0..b6396ce53315 100644 --- a/tests/micro/zephyr/test_zephyr.py +++ b/tests/micro/zephyr/test_zephyr.py @@ -39,7 +39,7 @@ from tvm.relay.expr_functor import ExprMutator from tvm.relay.op.annotation import compiler_begin, compiler_end -from tvm.micro.testing import _check_tune_log +from tvm.micro.testing import check_tune_log import conftest @@ -466,7 +466,7 @@ def test_autotune_conv2d(temp_dir, board, west_cmd, tvm_debug): ) assert tuner.best_flops > 0 - _check_tune_log(log_path) + check_tune_log(log_path) # Build without tuning with pass_context: diff --git a/tests/python/unittest/test_crt.py b/tests/python/unittest/test_crt.py index 487bfd454105..62e68ab01ce5 100644 --- a/tests/python/unittest/test_crt.py +++ b/tests/python/unittest/test_crt.py @@ -35,7 +35,7 @@ from tvm.topi.utils import get_const_tuple from tvm.topi.testing import conv2d_nchw_python -from tvm.micro.testing import _check_tune_log +from tvm.micro.testing import check_tune_log BUILD = True DEBUG = False @@ -285,7 +285,7 @@ def test_autotune(): ) assert tuner.best_flops > 0 - _check_tune_log(tune_log_file) + check_tune_log(tune_log_file) # Build without tuning with pass_context: diff --git a/tutorials/micro/micro_autotune.py b/tutorials/micro/micro_autotune.py index a10a537b608c..e7a1fa84a110 100644 --- a/tutorials/micro/micro_autotune.py +++ b/tutorials/micro/micro_autotune.py @@ -149,7 +149,7 @@ # build_func=tvm.micro.autotvm_build_func, # ) # runner = tvm.autotvm.LocalRunner(number=1, repeat=1, timeout=100, module_loader=module_loader) - +# # measure_option = tvm.autotvm.measure_option(builder=builder, runner=runner) ################ From 926037cb681078686c3ee7e7a6215345a51ed8ba Mon Sep 17 00:00:00 2001 From: Mehrdad Hessar Date: Thu, 16 Sep 2021 13:14:29 -0700 Subject: [PATCH 6/6] address comments --- python/tvm/micro/testing.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/python/tvm/micro/testing.py b/python/tvm/micro/testing.py index 5fd5ed3f4ee2..124f66e021a3 100644 --- a/python/tvm/micro/testing.py +++ b/python/tvm/micro/testing.py @@ -15,7 +15,7 @@ # specific language governing permissions and limitations # under the License. -"""Defines testing methods used with microTVM.""" +"""Defines the test methods used with microTVM.""" import pathlib import json @@ -23,7 +23,7 @@ def check_tune_log(log_path: Union[pathlib.Path, str]): - """Reads tune log and check each result""" + """Read the tuning log and check each result.""" with open(log_path, "r") as f: lines = f.readlines()