The example above only shows a basic example of how ACL can be used for offloading a single
Maxpool2D. If you would like to see more examples for each implemented operator and for
networks refer to the tests: `tests/python/contrib/test_arm_compute_lib`. Here you can modify
-`infrastructure.py` to use the remote device you have setup.
+`test_config.json` to configure how a remote device is created in `infrastructure.py` and,
+as a result, how runtime tests will be run.
+
+An example configuration for `test_config.json`:
+
+* connection_type - The type of RPC connection. Options: local, tracker, remote.
+* host - The host device to connect to.
+* port - The port to use when connecting.
+* target - The target to use for compilation.
+* device_key - The device key when connecting via a tracker.
+* cross_compile - Path to cross compiler when connecting from a non-arm platform e.g. aarch64-linux-gnu-g++.
+
+.. code:: json
+
+ {
+ "connection_type": "local",
+ "host": "localhost",
+ "port": 9090,
+ "target": "llvm -mtriple=aarch64-linux-gnu -mattr=+neon",
+ "device_key": "",
+ "cross_compile": ""
+ }
Operator support
# under the License.
from itertools import zip_longest, combinations
import json
+import os
+import warnings
import numpy as np
from tvm.contrib import graph_runtime
from tvm.relay.op.contrib import arm_compute_lib
from tvm.contrib import util
+from tvm.autotvm.measure import request_remote
class Device:
- """Adjust the following settings to connect to and use a remote device for tests."""
- use_remote = False
+ """
+ Configuration for Arm Compute Library tests.
+
+ Check tests/python/contrib/arm_compute_lib/ for the presence of an test_config.json file.
+ This file can be used to override the default configuration here which will attempt to run the Arm
+ Compute Library runtime tests locally if the runtime is available. Changing the configuration
+ will allow these runtime tests to be offloaded to a remote Arm device via a tracker for example.
+
+ Notes
+ -----
+ The test configuration will be loaded once when the the class is created. If the configuration
+ changes between tests, any changes will not be picked up.
+
+ Parameters
+ ----------
+ device : RPCSession
+ Allows tests to connect to and use remote device.
+
+ Attributes
+ ----------
+ connection_type : str
+ Details the type of RPC connection to use. Options:
+ local - Use the local device,
+ tracker - Connect to a tracker to request a remote device,
+ remote - Connect to a remote device directly.
+ host : str
+ Specify IP address or hostname of remote target.
+ port : int
+ Specify port number of remote target.
+ target : str
+ The compilation target.
+ device_key : str
+ The device key of the remote target. Use when connecting to a remote device via a tracker.
+ cross_compile : str
+ Specify path to cross compiler to use when connecting a remote device from a non-arm platform.
+ """
+ connection_type = "local"
+ host = "localhost"
+ port = 9090
target = "llvm -mtriple=aarch64-linux-gnu -mattr=+neon"
- # Enable cross compilation when connecting a remote device from a non-arm platform.
- cross_compile = None
- # cross_compile = "aarch64-linux-gnu-g++"
+ device_key = ""
+ cross_compile = ""
def __init__(self):
"""Keep remote device for lifetime of object."""
@classmethod
def _get_remote(cls):
"""Get a remote (or local) device to use for testing."""
- if cls.use_remote:
- # Here you may adjust settings to run the ACL unit tests via a remote
- # device using the RPC mechanism. Use this in the case you want to compile
- # an ACL module on a different machine to what you run the module on i.e.
- # x86 -> AArch64.
- #
- # Use the following to connect directly to a remote device:
- # device = rpc.connect(
- # hostname="0.0.0.0",
- # port=9090)
- #
- # Or connect via a tracker:
- # device = tvm.autotvm.measure.request_remote(
- # host="0.0.0.0",
- # port=9090,
- # device_key="device_key",
- # timeout=1000)
- #
- # return device
- raise NotImplementedError(
- "Please adjust these settings to connect to your remote device.")
- else:
+ if cls.connection_type == "tracker":
+ device = request_remote(cls.device_key,
+ cls.host,
+ cls.port,
+ timeout=1000)
+ elif cls.connection_type == "remote":
+ device = rpc.connect(cls.host, cls.port)
+ elif cls.connection_type == "local":
device = rpc.LocalSession()
- return device
+ else:
+ raise ValueError("connection_type in test_config.json should be one of: "
+ "local, tracker, remote.")
+
+ return device
+
+ @classmethod
+ def load(cls, file_name):
+ """Load test config
+
+ Load the test configuration by looking for file_name relative
+ to the test_arm_compute_lib directory.
+ """
+ location = os.path.realpath(os.path.join(os.getcwd(), os.path.dirname(__file__)))
+ config_file = os.path.join(location, file_name)
+ if not os.path.exists(config_file):
+ warnings.warn("Config file doesn't exist, resuming Arm Compute Library tests with default config.")
+ return
+ with open(config_file, mode="r") as config:
+ test_config = json.load(config)
+
+ cls.connection_type = test_config["connection_type"]
+ cls.host = test_config["host"]
+ cls.port = test_config["port"]
+ cls.target = test_config["target"]
+ cls.device_key = test_config.get("device_key") or ""
+ cls.cross_compile = test_config.get("cross_compile") or ""
def get_cpu_op_count(mod):
return True
# Remote device is in use or ACL runtime not present
- if not Device.use_remote and not arm_compute_lib.is_arm_compute_runtime_enabled():
+ # Note: Ensure that the device config has been loaded before this check
+ if not Device.connection_type != "local" and not arm_compute_lib.is_arm_compute_runtime_enabled():
print("Skip because runtime isn't present or a remote device isn't being used.")
return True