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

kparzysz pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/tvm.git


The following commit(s) were added to refs/heads/main by this push:
     new dc522a6ff6 [Hexagon] Run single RPC server on Android in each testing 
session  (#11547)
dc522a6ff6 is described below

commit dc522a6ff65b68532cd1bba43827cd981114df2c
Author: Mehrdad Hessar <mhes...@octoml.ai>
AuthorDate: Fri Jun 10 14:33:24 2022 -0700

    [Hexagon] Run single RPC server on Android in each testing session  (#11547)
    
    * Reuse hexagon launcher in test session
    
    * separate random name generation
    
    * revert get_aot_executor
    
    * Fix launcher for simulator case
    
    * add stop server for simulator
---
 python/tvm/contrib/hexagon/build.py                | 158 +++++++++++----------
 python/tvm/contrib/hexagon/pytest_plugin.py        |  66 +++++++--
 python/tvm/contrib/hexagon/session.py              |  90 +++++++-----
 tests/python/contrib/test_hexagon/test_launcher.py |   2 -
 4 files changed, 195 insertions(+), 121 deletions(-)

diff --git a/python/tvm/contrib/hexagon/build.py 
b/python/tvm/contrib/hexagon/build.py
index c659d66bec..7e29f645ce 100644
--- a/python/tvm/contrib/hexagon/build.py
+++ b/python/tvm/contrib/hexagon/build.py
@@ -28,6 +28,7 @@ import stat
 import random
 import string
 import subprocess
+import tempfile
 from typing import Union
 
 import tvm
@@ -36,6 +37,7 @@ from .session import Session
 
 
 HEXAGON_RPC_LIB_DIR = os.environ.get("HEXAGON_RPC_LIB_DIR")
+ANDROID_BASH_FILE_NAME = "android_bash.sh"
 
 
 def _get_hexagon_rpc_lib_dir() -> pathlib.Path:
@@ -116,7 +118,6 @@ class HexagonLauncherRPC(metaclass=abc.ABCMeta):
         self._rpc_info.update(rpc_info)
         self._workspace = self._create_workspace(workspace)
         self._device_key = self.HEXAGON_REMOTE_DEVICE_KEY
-        self._serial_number = None
 
     @abc.abstractmethod
     def start_server(self):
@@ -128,6 +129,11 @@ class HexagonLauncherRPC(metaclass=abc.ABCMeta):
         """Stop the RPC server"""
         ...
 
+    @abc.abstractmethod
+    def cleanup_directory(self):
+        """Cleanup working directory"""
+        ...
+
     @abc.abstractmethod
     def _copy_to_remote(
         self, local_path: Union[str, pathlib.Path], remote_path: Union[str, 
pathlib.Path]
@@ -144,13 +150,18 @@ class HexagonLauncherRPC(metaclass=abc.ABCMeta):
         ...
 
     @abc.abstractmethod
-    def _create_remote_directory(self, remote_path: Union[str, pathlib.Path]):
+    def _create_remote_directory(self, remote_path: Union[str, pathlib.Path]) 
-> pathlib.Path:
         """Create a directory in the remote location.
 
         Parameters
         ----------
         remote_path : str or pathlib.Path
             Name of the directory to be created.
+
+        Returns
+        -------
+        pathlib.Path :
+            Absolute path of the remote workspace.
         """
         ...
 
@@ -171,10 +182,9 @@ class HexagonLauncherRPC(metaclass=abc.ABCMeta):
         if not workspace:
             base_dir = self._rpc_info["workspace_base"]
             workspace = os.path.join(base_dir, _get_test_directory_name())
-        self._create_remote_directory(workspace)
-        return pathlib.Path(workspace)
+        return self._create_remote_directory(workspace)
 
-    def upload(self, local_path: Union[str, pathlib.Path], remote_filename: 
str):
+    def upload(self, local_path: Union[str, pathlib.Path], remote_filename: 
str) -> pathlib.Path:
         """Upload a local file to the remote workspace.
 
         Parameters
@@ -183,9 +193,16 @@ class HexagonLauncherRPC(metaclass=abc.ABCMeta):
             Path to the local file to be copied.
         remote_filename : str
             Name of the file in the remote workspace.
+
+        Returns
+        -------
+        pathlib.Path :
+            Uploaded file remote path.
         """
         assert self._workspace
-        self._copy_to_remote(local_path, os.path.join(str(self._workspace), 
remote_filename))
+        remote_file_path = self._workspace / remote_filename
+        self._copy_to_remote(local_path, str(remote_file_path))
+        return remote_file_path
 
     def start_session(self, session_name: str = "hexagon-rpc") -> Session:
         """Connect to the RPC server.
@@ -221,10 +238,7 @@ class HexagonLauncherRPC(metaclass=abc.ABCMeta):
             session and loaded.
 
             If the object passed is a string or pathlib.Path, it must
-            be either a bare file name (without any path components),
-            or a full path in the remote system. If it is a file name,
-            the file must already have been uploaded to the remote,
-            and be placed in the remote workspace.
+            be a full path in the remote system.
 
         session : Session
 
@@ -240,7 +254,10 @@ class HexagonLauncherRPC(metaclass=abc.ABCMeta):
         return session.load_module(module)
 
     def get_graph_executor(
-        self, graph_json: str, module_name: Union[str, pathlib.Path], session: 
Session
+        self,
+        graph_json: str,
+        module: Union[str, pathlib.Path, tvm.runtime.Module],
+        session: Session,
     ):
         """Create a local GraphModule which consumes a remote libmod.
 
@@ -248,8 +265,14 @@ class HexagonLauncherRPC(metaclass=abc.ABCMeta):
         ----------
         graph_json : str
             The string with the graph JSON.
-        module_name : str or pathlib.Path
-            Remote module filename. Same restrictions apply as in 
load_module().
+        module : Union[str, pathlib.Path, tvm.runtime.Module]
+
+            The module to load.  If `module` is a
+            `tvm.runtime.Module`, it will be uploaded to the remote
+            session and loaded.
+
+            If the object passed is a string or pathlib.Path, it must
+            be a full path in the remote system.
         session : Session
             Remote session. The session must be established (via __enter__)
             prior to calling this function.
@@ -259,13 +282,12 @@ class HexagonLauncherRPC(metaclass=abc.ABCMeta):
         GraphModule :
             Runtime graph module that can be used to execute the graph.
         """
-        graph_mod = self.load_module(module_name, session)
-        return tvm.contrib.graph_executor.create(graph_json, graph_mod, 
session.device)
+        return session.get_graph_executor(graph_json, module)
 
     def get_graph_debug_executor(
         self,
         graph_json: str,
-        module_name: Union[str, pathlib.Path],
+        module: Union[str, pathlib.Path, tvm.runtime.Module],
         session: Session,
         dump_root: Union[str, pathlib.Path] = None,
     ):
@@ -275,39 +297,24 @@ class HexagonLauncherRPC(metaclass=abc.ABCMeta):
         ----------
         graph_json : str
             The string with the graph JSON.
-        module_name : str or pathlib.Path
-            Remote module filename. Same restrictions apply as in 
load_module().
-        session : Session
-            Remote session. The session must be established (via __enter__)
-            prior to calling this function.
-
-        Returns
-        -------
-        GraphModuleDebug :
-            Runtime debug graph module that can be used to debug the graph.
-        """
-        graph_mod = self.load_module(module_name, session)
-        return tvm.contrib.debugger.debug_executor.create(
-            graph_json, graph_mod, session.device, dump_root=str(dump_root)
-        )
+        module : Union[str, pathlib.Path, tvm.runtime.Module]
 
-    def get_aot_executor(self, module_name: Union[str, pathlib.Path], session: 
Session):
-        """Create a local AoTModule which consumes a remote libmod.
+            The module to load.  If `module` is a
+            `tvm.runtime.Module`, it will be uploaded to the remote
+            session and loaded.
 
-        Parameters
-        ----------
-        module_name : str or pathlib.Path
-            Remote module filename. Same restrictions apply as in 
load_module().
+            If the object passed is a string or pathlib.Path, it must
+            be a full path in the remote system.
         session : Session
             Remote session. The session must be established (via __enter__)
             prior to calling this function.
 
         Returns
         -------
-        aot_module : AotModule
-            Runtime AOT module that can be used to execute.
+        GraphModuleDebug :
+            Runtime debug graph module that can be used to debug the graph.
         """
-        return session.get_aot_executor(module_name)
+        return session.get_graph_debug_executor(graph_json, module, 
dump_root=dump_root)
 
 
 class HexagonLauncherAndroid(HexagonLauncherRPC):
@@ -315,7 +322,6 @@ class HexagonLauncherAndroid(HexagonLauncherRPC):
 
     ANDROID_HEXAGON_TEST_BASE_DIR = 
pathlib.Path("/data/local/tmp/hexagon_test")
     ANDROID_HEXAGON_RPC_FILES = [
-        "android_bash.sh",
         "libhexagon_rpc_skel.so",
         "libtvm_runtime.so",
         "tvm_rpc_android",
@@ -354,39 +360,42 @@ class HexagonLauncherAndroid(HexagonLauncherRPC):
             self._adb_device_sub_cmd + ["push", str(local_path), 
str(remote_path)]
         )
 
-    def _create_remote_directory(self, remote_path: Union[str, pathlib.Path]):
+    def _create_remote_directory(self, remote_path: Union[str, pathlib.Path]) 
-> pathlib.Path:
         """Abstract method implementation. See description in 
HexagonLauncherRPC."""
         subprocess.check_call(self._adb_device_sub_cmd + ["shell", "mkdir", 
"-p", str(remote_path)])
+        return pathlib.Path(remote_path)
 
     def _copy_binaries(self):
         """Upload Android server binaries."""
 
         # Create bash script
-        android_bash_script_path = _get_hexagon_rpc_lib_dir() / 
"android_bash.sh"
-        with open(_get_hexagon_rpc_lib_dir() / "android_bash.sh.template", 
"r") as src_f:
-            if os.path.exists(android_bash_script_path):
-                os.remove(android_bash_script_path)
-            with open(android_bash_script_path, "w") as dest_f:
-                for line in src_f.readlines():
-                    if "<RPC_TRACKER_HOST>" in line:
-                        line = line.replace(
-                            "<RPC_TRACKER_HOST>", 
str(self._rpc_info["rpc_tracker_host"])
-                        )
-                    if "<RPC_TRACKER_PORT>" in line:
-                        line = line.replace(
-                            "<RPC_TRACKER_PORT>", 
str(self._rpc_info["rpc_tracker_port"])
-                        )
-                    if "<HEXAGON_REMOTE_DEVICE_KEY>" in line:
-                        line = line.replace("<HEXAGON_REMOTE_DEVICE_KEY>", 
self._device_key)
-                    if "<RPC_SERVER_PORT>" in line:
-                        line = line.replace(
-                            "<RPC_SERVER_PORT>", 
str(self._rpc_info["rpc_server_port"])
-                        )
-                    dest_f.write(line)
-
-        # Make shell script executable
-        android_bash_stat = os.stat(android_bash_script_path)
-        os.chmod(android_bash_script_path, android_bash_stat.st_mode | 
stat.S_IEXEC)
+        with open(_get_hexagon_rpc_lib_dir() / 
f"{ANDROID_BASH_FILE_NAME}.template", "r") as src_f:
+            with tempfile.TemporaryDirectory() as temp_dir:
+                android_bash_script_path = pathlib.Path(temp_dir) / 
ANDROID_BASH_FILE_NAME
+                with open(android_bash_script_path, "w") as dest_f:
+                    for line in src_f.readlines():
+                        if "<RPC_TRACKER_HOST>" in line:
+                            line = line.replace(
+                                "<RPC_TRACKER_HOST>", 
str(self._rpc_info["rpc_tracker_host"])
+                            )
+                        if "<RPC_TRACKER_PORT>" in line:
+                            line = line.replace(
+                                "<RPC_TRACKER_PORT>", 
str(self._rpc_info["rpc_tracker_port"])
+                            )
+                        if "<HEXAGON_REMOTE_DEVICE_KEY>" in line:
+                            line = line.replace("<HEXAGON_REMOTE_DEVICE_KEY>", 
self._device_key)
+                        if "<RPC_SERVER_PORT>" in line:
+                            line = line.replace(
+                                "<RPC_SERVER_PORT>", 
str(self._rpc_info["rpc_server_port"])
+                            )
+                        dest_f.write(line)
+
+                # Make shell script executable
+                android_bash_stat = os.stat(android_bash_script_path)
+                os.chmod(android_bash_script_path, android_bash_stat.st_mode | 
stat.S_IEXEC)
+                self._copy_to_remote(
+                    android_bash_script_path, self._workspace / 
android_bash_script_path.name
+                )
 
         # Push files
         lib_dir = _get_hexagon_rpc_lib_dir()
@@ -436,7 +445,8 @@ class HexagonLauncherAndroid(HexagonLauncherRPC):
 
         # Run server and connect to tracker
         subprocess.Popen(
-            self._adb_device_sub_cmd + ["shell", f"cd {self._workspace} && 
./android_bash.sh"],
+            self._adb_device_sub_cmd
+            + ["shell", f"cd {self._workspace} && ./{ANDROID_BASH_FILE_NAME}"],
             stdout=subprocess.PIPE,
             stdin=subprocess.PIPE,
             stderr=subprocess.PIPE,
@@ -472,8 +482,8 @@ class HexagonLauncherAndroid(HexagonLauncherRPC):
             self._adb_device_sub_cmd + ["shell", f"kill `cat 
{self._workspace}/rpc_pid.txt`"]
         )
 
-    def _cleanup_directory(self):
-        # Remove workspace directory on remote target
+    def cleanup_directory(self):
+        """Abstract method implementation. See description in 
HexagonLauncherRPC."""
         subprocess.Popen(self._adb_device_sub_cmd + ["shell", f"rm -rf 
{self._workspace}"])
 
     def start_server(self):
@@ -485,7 +495,7 @@ class HexagonLauncherAndroid(HexagonLauncherRPC):
         """Abstract method implementation. See description in 
HexagonLauncherRPC."""
         self._cleanup_port_forwarding()
         self._terminate_remote()
-        self._cleanup_directory()
+        self.cleanup_directory()
 
 
 class HexagonLauncherSimulator(HexagonLauncherRPC):
@@ -511,9 +521,10 @@ class HexagonLauncherSimulator(HexagonLauncherRPC):
         """Abstract method implementation. See description in 
HexagonLauncherRPC."""
         subprocess.check_call(["cp", str(local_path), str(remote_path)])
 
-    def _create_remote_directory(self, remote_path: Union[str, pathlib.Path]):
+    def _create_remote_directory(self, remote_path: Union[str, pathlib.Path]) 
-> pathlib.Path:
         """Abstract method implementation. See description in 
HexagonLauncherRPC."""
         subprocess.check_call(["mkdir", "-p", str(remote_path)])
+        return pathlib.Path(os.path.abspath(remote_path))
 
     def _copy_libcxx(self, dest_dir: Union[str, pathlib.Path]):
         """Copy libc++ libraries to the remote workspace."""
@@ -585,6 +596,9 @@ class HexagonLauncherSimulator(HexagonLauncherRPC):
         self._server_process = mp.Process(target=lambda *a: _start(self, *a))
         self._server_process.start()
 
+    def cleanup_directory(self):
+        """Abstract method implementation. See description in 
HexagonLauncherRPC."""
+
     def stop_server(self):
         """Abstract method implementation. See description in 
HexagonLauncherRPC."""
         self._server_process.terminate()
diff --git a/python/tvm/contrib/hexagon/pytest_plugin.py 
b/python/tvm/contrib/hexagon/pytest_plugin.py
index 278bd833da..1841c654b9 100644
--- a/python/tvm/contrib/hexagon/pytest_plugin.py
+++ b/python/tvm/contrib/hexagon/pytest_plugin.py
@@ -56,7 +56,7 @@ def _compose(args, decs):
 requires_hexagon_toolchain = 
tvm.testing.requires_hexagon(support_required="compile-only")
 
 
-@tvm.testing.fixture
+@pytest.fixture(scope="session")
 def android_serial_number() -> Optional[str]:
     serial = os.getenv(ANDROID_SERIAL_NUMBER, default="")
     # Setting ANDROID_SERIAL_NUMBER to an empty string should be
@@ -138,22 +138,29 @@ def tvm_tracker_port(_tracker_info) -> int:
     return port
 
 
-@tvm.testing.fixture
+@pytest.fixture(scope="session")
+def rpc_server_port_for_session() -> int:
+    return get_free_port()
+
+
+@pytest.fixture()
 def rpc_server_port() -> int:
     return get_free_port()
 
 
-@tvm.testing.fixture
+@pytest.fixture(scope="session")
 def adb_server_socket() -> str:
     return os.getenv(ADB_SERVER_SOCKET, default="tcp:5037")
 
 
-@tvm.testing.fixture
-def hexagon_launcher(
-    request, android_serial_number, rpc_server_port, adb_server_socket
+@pytest.fixture(scope="session")
+def hexagon_server_process(
+    request, android_serial_number, rpc_server_port_for_session, 
adb_server_socket
 ) -> HexagonLauncherRPC:
-    """Initials and returns hexagon launcher if ANDROID_SERIAL_NUMBER is 
defined"""
-    if android_serial_number is None:
+    """Initials and returns hexagon launcher if ANDROID_SERIAL_NUMBER is 
defined.
+    This launcher is started only once per test session.
+    """
+    if android_serial_number is None or android_serial_number == "simulator":
         yield None
     else:
         # Requesting these fixtures sets up a local tracker, if one
@@ -165,19 +172,54 @@ def hexagon_launcher(
         rpc_info = {
             "rpc_tracker_host": tvm_tracker_host,
             "rpc_tracker_port": tvm_tracker_port,
-            "rpc_server_port": rpc_server_port,
+            "rpc_server_port": rpc_server_port_for_session,
             "adb_server_socket": adb_server_socket,
         }
         launcher = HexagonLauncher(serial_number=android_serial_number, 
rpc_info=rpc_info)
-        launcher.start_server()
+
         try:
+            launcher.start_server()
             yield launcher
         finally:
             launcher.stop_server()
 
 
-@tvm.testing.fixture
-def hexagon_session(hexagon_launcher) -> Session:
+@pytest.fixture
+def hexagon_launcher(
+    hexagon_server_process,
+    rpc_server_port,
+    tvm_tracker_host,
+    tvm_tracker_port,
+    adb_server_socket,
+    android_serial_number,
+) -> HexagonLauncherRPC:
+    """Initials and returns hexagon launcher which reuses RPC info and Android 
serial number."""
+    if android_serial_number is None:
+        yield None
+
+    if android_serial_number != "simulator":
+        rpc_info = hexagon_server_process._rpc_info
+    else:
+        rpc_info = {
+            "rpc_tracker_host": tvm_tracker_host,
+            "rpc_tracker_port": tvm_tracker_port,
+            "rpc_server_port": rpc_server_port,
+            "adb_server_socket": adb_server_socket,
+        }
+
+    launcher = HexagonLauncher(serial_number=android_serial_number, 
rpc_info=rpc_info)
+    try:
+        if android_serial_number == "simulator":
+            launcher.start_server()
+        yield launcher
+    finally:
+        if android_serial_number == "simulator":
+            launcher.stop_server()
+        launcher.cleanup_directory()
+
+
+@pytest.fixture
+def hexagon_session(hexagon_launcher: HexagonLauncherRPC) -> Session:
     if hexagon_launcher is None:
         yield None
     else:
diff --git a/python/tvm/contrib/hexagon/session.py 
b/python/tvm/contrib/hexagon/session.py
index f30fe6e470..0c0bf296df 100644
--- a/python/tvm/contrib/hexagon/session.py
+++ b/python/tvm/contrib/hexagon/session.py
@@ -93,7 +93,8 @@ class Session:
             raise exception
 
     def __exit__(self, exc_type, exc_value, exc_traceback):
-        pass
+        # close session to the tracker
+        del self._rpc
 
     @property
     def device(self):
@@ -109,7 +110,7 @@ class Session:
 
         return self._device
 
-    def upload(self, local_path: Union[str, pathlib.Path], remote_filename: 
str):
+    def upload(self, local_path: Union[str, pathlib.Path], remote_filename: 
str) -> pathlib.Path:
         """Upload a local file to the remote workspace.
 
         Parameters
@@ -118,8 +119,13 @@ class Session:
             Path to the local file to be copied.
         remote_filename : str
             Name of the file in the remote workspace.
+
+        Returns
+        -------
+        pathlib.Path :
+            Uploaded file remote path.
         """
-        self._launcher.upload(local_path, remote_filename)
+        return self._launcher.upload(local_path, remote_filename)
 
     def load_module(self, module: Union[str, pathlib.Path, 
tvm.runtime.Module]):
         """Load TVM module.
@@ -136,10 +142,7 @@ class Session:
             session and loaded.
 
             If the object passed is a string or pathlib.Path, it must
-            be either a bare file name (without any path components),
-            or a full path in the remote system. If it is a file name,
-            the file must already have been uploaded to the remote,
-            and be placed in the remote workspace.
+            be a full path in the remote system.
 
         Returns
         -------
@@ -155,16 +158,19 @@ class Session:
                 binary_name = "test_binary.so"
                 binary_path = temp_dir / binary_name
                 module.save(str(binary_path))
-                self.upload(binary_path, binary_name)
-                module = binary_name
+                remote_file_path = self.upload(binary_path, binary_name)
+        else:
+            remote_file_path = module
 
-        assert isinstance(module, (str, pathlib.Path)), "Invalid path type:" + 
str(type(module))
-        return self._rpc.get_function("tvm.hexagon.load_module")(str(module))
+        assert isinstance(remote_file_path, (str, pathlib.Path)), "Invalid 
path type:" + str(
+            type(remote_file_path)
+        )
+        return 
self._rpc.get_function("tvm.hexagon.load_module")(str(remote_file_path))
 
     def get_graph_executor(
         self,
         graph_json: str,
-        module_name: Union[str, pathlib.Path],
+        module_name: Union[str, pathlib.Path, tvm.runtime.Module],
     ):
         """Create a local GraphModule which consumes a remote libmod.
 
@@ -173,14 +179,10 @@ class Session:
 
         Parameters
         ----------
-
-        module_name : Union[str, pathlib.Path]
-
+        module_name : Union[str, pathlib.Path, tvm.runtime.Module]
             The remote module filename, following the same restrictions
             as `load_module`.
-
         graph_json : str
-
             The string with the graph JSON.
 
         Returns
@@ -196,31 +198,54 @@ class Session:
 
     def get_aot_executor(
         self,
-        module_name: Union[str, pathlib.Path],
+        module_file: Union[str, pathlib.Path],
     ):
         """Create a local GraphModule which consumes a remote libmod.
-
         The session must be established (via __enter__) prior to
         calling this function.
-
         Parameters
         ----------
+        module_file : Union[str, pathlib.Path]
+            The remote module filename, following the same restrictions
+            as `load_module`. The filename should be an absolute path.
+        Returns
+        -------
+        GraphModule :
+            Runtime graph module that can be used to execute the graph.
+        """
+        aot_mod = self.load_module(module_file)
+        return tvm.runtime.executor.AotModule(aot_mod["default"](self.device))
 
-        module_name : Union[str, pathlib.Path]
+    def get_graph_debug_executor(
+        self,
+        graph_json: str,
+        module_name: Union[str, pathlib.Path, tvm.runtime.Module],
+        dump_root: Union[str, pathlib.Path] = None,
+    ):
+        """Create a local GraphModuleDebug which consumes a remote libmod.
 
+        Parameters
+        ----------
+        graph_json : str
+            The string with the graph JSON.
+         module_name : Union[str, pathlib.Path, tvm.runtime.Module]
             The remote module filename, following the same restrictions
             as `load_module`.
+        session : Session
+            Remote session. The session must be established (via __enter__)
+            prior to calling this function.
 
         Returns
         -------
-        GraphModule :
-            Runtime graph module that can be used to execute the graph.
-
+        GraphModuleDebug :
+            Runtime debug graph module that can be used to debug the graph.
         """
 
-        aot_mod = self.load_module(module_name)
-        self._set_device_type(aot_mod)
-        return tvm.runtime.executor.AotModule(aot_mod["default"](self.device))
+        graph_debug_mod = self.load_module(module_name)
+        self._set_device_type(graph_debug_mod)
+        return tvm.contrib.debugger.debug_executor.create(
+            graph_json, graph_debug_mod, self.device, dump_root=str(dump_root)
+        )
 
     def get_executor_from_factory(self, module: ExecutorFactoryModule):
         """Create a local GraphModule which consumes a remote libmod.
@@ -286,11 +311,7 @@ class Session:
             Runtime graph module that can be used to execute the graph.
 
         """
-
-        graph_json = module.get_graph_json()
-        graph_mod = self.load_module(module.get_lib())
-
-        return tvm.contrib.graph_executor.create(graph_json, graph_mod, 
self.device)
+        return self.get_graph_executor(module.get_graph_json(), 
module.get_lib())
 
     def _aot_executor_from_factory(
         self,
@@ -354,7 +375,6 @@ class Session:
                     f"Target kind should be from these options: [hexagon, 
llvm]."
                 )
 
-            self.upload(binary_path, binary_name)
+            remote_file_path = self.upload(binary_path, binary_name)
 
-        aot_mod = self.load_module(binary_name)
-        return tvm.runtime.executor.AotModule(aot_mod["default"](self.device))
+        return self.get_aot_executor(remote_file_path)
diff --git a/tests/python/contrib/test_hexagon/test_launcher.py 
b/tests/python/contrib/test_hexagon/test_launcher.py
index ad798925ee..aae2e598f6 100644
--- a/tests/python/contrib/test_hexagon/test_launcher.py
+++ b/tests/python/contrib/test_hexagon/test_launcher.py
@@ -15,8 +15,6 @@
 # specific language governing permissions and limitations
 # under the License.
 
-import sys
-import pytest
 import numpy as np
 
 import tvm.testing

Reply via email to