diff --git a/python/tvm/testing/utils.py b/python/tvm/testing/utils.py index b86596feed6b..8be5cc8ec471 100644 --- a/python/tvm/testing/utils.py +++ b/python/tvm/testing/utils.py @@ -404,6 +404,10 @@ def _get_targets(target_str=None): if target_kind == "cuda" and "cudnn" in tvm.target.Target(target).attrs.get("libs", []): is_enabled = tvm.support.libinfo()["USE_CUDNN"].lower() in ["on", "true", "1"] is_runnable = is_enabled and cudnn.exists() + elif target_kind == "hexagon": + is_enabled = tvm.support.libinfo()["USE_HEXAGON"].lower() in ["on", "true", "1"] + # If Hexagon has compile-time support, we can always fall back + is_runnable = is_enabled and "ANDROID_SERIAL_NUMBER" in os.environ else: is_enabled = tvm.runtime.enabled(target_kind) is_runnable = is_enabled and tvm.device(target_kind).exist diff --git a/tests/python/contrib/test_hexagon/benchmark_hexagon.py b/tests/python/contrib/test_hexagon/benchmark_hexagon.py index f17530c3efdc..979bd111707b 100644 --- a/tests/python/contrib/test_hexagon/benchmark_hexagon.py +++ b/tests/python/contrib/test_hexagon/benchmark_hexagon.py @@ -27,13 +27,7 @@ import tvm.testing from tvm import te -from tvm import relay -from tvm.relay.backend import Executor, Runtime -from tvm.contrib import utils, ndk -from tvm.contrib.hexagon.build import HexagonLauncher -import tvm.contrib.hexagon as hexagon - -from .conftest import requires_hexagon_toolchain +from tvm.contrib.hexagon.build import HexagonLauncherRPC RPC_SERVER_PORT = 7070 @@ -47,8 +41,8 @@ # server to bind to the same port until the wait time elapses. -@requires_hexagon_toolchain -def test_elemwise_add(android_serial_number, hexagon_launcher): +@tvm.testing.requires_hexagon +def test_elemwise_add(hexagon_launcher: HexagonLauncherRPC): """ Starting with an elementwise-add computation, try various schedules / optimizations to see the impact they have on performance. diff --git a/tests/python/contrib/test_hexagon/test_2d_physical_buffers.py b/tests/python/contrib/test_hexagon/test_2d_physical_buffers.py index 9de55996b031..78e1eb11ad9f 100644 --- a/tests/python/contrib/test_hexagon/test_2d_physical_buffers.py +++ b/tests/python/contrib/test_hexagon/test_2d_physical_buffers.py @@ -19,8 +19,6 @@ import contextlib import sys -import tempfile -import pathlib import pytest import numpy as np @@ -272,6 +270,12 @@ def test_lower(self, schedule_args): @requires_hexagon_toolchain def test_build(self, schedule_args, target_host, input_layout, working_layout, output_layout): + """Testing build success/failure + + * On Hexagon targets, build must succeed for both 1-d and 2-d memory. + * On non-Hexagon targets, build must succeed 1-d memory. + * On non-Hexagon targets, build must fail and report an error for 2-d memory. + """ # contextlib.nullcontext wasn't added until python3.7, and the # CI currently runs on python3.6. Therefore, using ExitStack # to manage an optional context instead. @@ -292,7 +296,7 @@ def runtime_module(self, schedule_args, target_host): return tvm.build(*schedule_args, target=target_host) - @requires_hexagon_toolchain + @tvm.testing.requires_hexagon def test_execute( self, runtime_module, diff --git a/tests/python/contrib/test_hexagon/test_launcher.py b/tests/python/contrib/test_hexagon/test_launcher.py index 7dadc8f2f4ab..5c5e8f6c39f1 100644 --- a/tests/python/contrib/test_hexagon/test_launcher.py +++ b/tests/python/contrib/test_hexagon/test_launcher.py @@ -25,10 +25,8 @@ from tvm.relay.backend import Executor, Runtime from tvm.contrib.hexagon.session import Session -from .conftest import requires_hexagon_toolchain - -@requires_hexagon_toolchain +@tvm.testing.requires_hexagon def test_add(hexagon_session: Session): dtype = "int8" A = tvm.te.placeholder((2,), dtype=dtype) @@ -53,7 +51,7 @@ def test_add(hexagon_session: Session): assert (C_data.numpy() == np.array([6, 7])).all() -@requires_hexagon_toolchain +@tvm.testing.requires_hexagon def test_add_vtcm(hexagon_session: Session): dtype = "int8" A = tvm.te.placeholder((2,), dtype=dtype) @@ -87,7 +85,7 @@ class TestMatMul: N = tvm.testing.parameter(32) K = tvm.testing.parameter(32) - @requires_hexagon_toolchain + @tvm.testing.requires_hexagon def test_matmul(self, hexagon_session, M, N, K): X = te.placeholder((M, K), dtype="float32") Y = te.placeholder((K, N), dtype="float32") @@ -122,7 +120,7 @@ def test_matmul(self, hexagon_session, M, N, K): tvm.testing.assert_allclose(zt.numpy(), ztcpu.numpy(), rtol=1e-4) -@requires_hexagon_toolchain +@tvm.testing.requires_hexagon def test_graph_executor(hexagon_session: Session): dtype = "float32" data = relay.var("data", relay.TensorType((1, 64, 64, 3), dtype)) @@ -178,7 +176,7 @@ def test_graph_executor(hexagon_session: Session): tvm.testing.assert_allclose(hexagon_output, expected_output, rtol=1e-4, atol=1e-5) -@requires_hexagon_toolchain +@tvm.testing.requires_hexagon def test_graph_executor_multiple_conv2d(hexagon_session: Session): dtype = "float32" input_shape = (1, 8, 8, 3) @@ -255,7 +253,7 @@ def test_graph_executor_multiple_conv2d(hexagon_session: Session): tvm.testing.assert_allclose(hexagon_output, expected_output, rtol=1e-4, atol=1e-5) -@requires_hexagon_toolchain +@tvm.testing.requires_hexagon def test_aot_executor(hexagon_session: Session, aot_host_target, aot_target): dtype = "float32" input_shape = (1, 128, 128, 3) @@ -314,7 +312,7 @@ def test_aot_executor(hexagon_session: Session, aot_host_target, aot_target): tvm.testing.assert_allclose(hexagon_output, expected_output, rtol=1e-4, atol=1e-5) -@requires_hexagon_toolchain +@tvm.testing.requires_hexagon def test_aot_executor_multiple_conv2d(hexagon_session: Session, aot_host_target, aot_target): dtype = "float32" input_shape = (1, 8, 8, 3) diff --git a/tests/python/contrib/test_hexagon/test_models.py b/tests/python/contrib/test_hexagon/test_models.py index 649cc5b3f4dd..74f52f20d97c 100644 --- a/tests/python/contrib/test_hexagon/test_models.py +++ b/tests/python/contrib/test_hexagon/test_models.py @@ -24,8 +24,6 @@ from tvm.relay.backend import Executor, Runtime from tvm.contrib.hexagon.session import Session -from .conftest import requires_hexagon_toolchain - def get_mobilenet(): """Download and import mobilenet model with ONNX""" @@ -38,7 +36,7 @@ def get_mobilenet(): return onnx.load(model_path) -@requires_hexagon_toolchain +@tvm.testing.requires_hexagon def test_mobilenet(hexagon_session: Session): dtype = "float32" onnx_model = get_mobilenet() @@ -88,7 +86,7 @@ def test_mobilenet(hexagon_session: Session): enable_usmp = tvm.testing.parameter(False, True) -@requires_hexagon_toolchain +@tvm.testing.requires_hexagon def test_mobilenet_aot(hexagon_session: Session, aot_host_target, aot_target, enable_usmp): if hexagon_session._launcher._serial_number == "simulator": pytest.skip(msg="Skip on simulator due to long runtime.") diff --git a/tests/python/contrib/test_hexagon/test_run_unit_tests.py b/tests/python/contrib/test_hexagon/test_run_unit_tests.py index 3a383d30e5f4..010c79b8f554 100644 --- a/tests/python/contrib/test_hexagon/test_run_unit_tests.py +++ b/tests/python/contrib/test_hexagon/test_run_unit_tests.py @@ -18,20 +18,21 @@ import os import pytest import numpy as np -from tvm.contrib.hexagon.build import HexagonLauncher -from .conftest import requires_hexagon_toolchain + +import tvm +from tvm.contrib.hexagon.session import Session # use pytest -sv to observe gtest output # use --gtest_args to pass arguments to gtest # for example to run all "foo" tests twice and observe gtest output run # pytest -sv --gtests_args="--gtest_filter=*foo* --gtest_repeat=2" -@requires_hexagon_toolchain +@tvm.testing.requires_hexagon @pytest.mark.skipif( os.environ.get("HEXAGON_GTEST") == None, reason="Test requires environment variable HEXAGON_GTEST set with a path to a Hexagon gtest version normally located at /path/to/hexagon/sdk/utils/googletest/gtest", ) -def test_run_unit_tests(hexagon_session, gtest_args): +def test_run_unit_tests(hexagon_session: Session, gtest_args): try: func = hexagon_session._rpc.get_function("hexagon.run_unit_tests") except: diff --git a/tests/python/contrib/test_hexagon/test_thread_pool.py b/tests/python/contrib/test_hexagon/test_thread_pool.py index 8a35bff7e7c9..d95c4120b775 100644 --- a/tests/python/contrib/test_hexagon/test_thread_pool.py +++ b/tests/python/contrib/test_hexagon/test_thread_pool.py @@ -25,7 +25,6 @@ import tvm.testing from tvm import te -from .conftest import requires_hexagon_toolchain from tvm.script import tir as T @@ -67,11 +66,8 @@ def benchmark_func(mod, name, args, hexagon_session): return evaluator(a, b, c, n).mean -@requires_hexagon_toolchain -def test_speedup(hexagon_session, capsys): - if hexagon_session is None: - pytest.skip(msg="Skip hardware test, ANDROID_SERIAL_NUMBER is not set.") - +@tvm.testing.requires_hexagon +def test_speedup(hexagon_session: Session, capsys): target_hexagon = tvm.target.hexagon("v68", link_params=True) func = tvm.build( ElemwiseSumIRModule, target=tvm.target.Target(target_hexagon, host=target_hexagon) @@ -85,11 +81,8 @@ def test_speedup(hexagon_session, capsys): print("... speedup of {:.2f}".format(serial_mean / parallel_mean), end=" ") -@requires_hexagon_toolchain +@tvm.testing.requires_hexagon def test_elemwise_sum_parallel(hexagon_session: Session): - if hexagon_session is None: - pytest.skip(msg="Skip hardware test, ANDROID_SERIAL_NUMBER is not set.") - target_hexagon = tvm.target.hexagon("v68", link_params=True) func = tvm.build( ElemwiseSumIRModule, target=tvm.target.Target(target_hexagon, host=target_hexagon) diff --git a/tests/python/contrib/test_hexagon/topi/test_batch_matmul.py b/tests/python/contrib/test_hexagon/topi/test_batch_matmul.py index 2816322b6d43..093ce37e5efa 100644 --- a/tests/python/contrib/test_hexagon/topi/test_batch_matmul.py +++ b/tests/python/contrib/test_hexagon/topi/test_batch_matmul.py @@ -25,8 +25,8 @@ from tvm.contrib.hexagon.session import Session import tvm.topi.testing from tvm.topi.utils import get_const_tuple +from tvm.contrib.hexagon.session import Session -from ..conftest import requires_hexagon_toolchain dtype = tvm.testing.parameter( "float32", @@ -46,7 +46,7 @@ class TestMatMulFloat: ) # TODO(mehrdadh): add dynamic testing - @requires_hexagon_toolchain + @tvm.testing.requires_hexagon def test_batch_matmul(self, hexagon_session: Session, x_batch, y_batch, M, N, K, dtype): if dtype == "float16": pytest.xfail("float16 is not supported.") @@ -98,7 +98,7 @@ class TestMatMulInt8: (5, 1, 16, 16, 32), ) - @requires_hexagon_toolchain + @tvm.testing.requires_hexagon def test_batch_matmul_int8(self, hexagon_session: Session, x_batch, y_batch, M, N, K): dtype = "int8" out_dtype = "int8" diff --git a/tests/python/contrib/test_hexagon/topi/test_cache_read_write.py b/tests/python/contrib/test_hexagon/topi/test_cache_read_write.py index bfb597f7b7f3..435ab7190752 100644 --- a/tests/python/contrib/test_hexagon/topi/test_cache_read_write.py +++ b/tests/python/contrib/test_hexagon/topi/test_cache_read_write.py @@ -21,8 +21,7 @@ import tvm.testing from tvm import te - -from ..conftest import requires_hexagon_toolchain +from tvm.contrib.hexagon.session import Session def intrin_mem_copy(shape, dtype, dst_scope, src_scope): @@ -98,7 +97,7 @@ def verify(hexagon_session: Session, s, x, y, z, size): np.testing.assert_equal(zt.numpy(), ref) -@requires_hexagon_toolchain +@tvm.testing.requires_hexagon def test_cache_read_write(hexagon_session: Session): size = 128 outer_shape = (size,) @@ -140,7 +139,7 @@ def layout_transform_2d(n): return [n // 16, te.AXIS_SEPARATOR, n % 16] -@requires_hexagon_toolchain +@tvm.testing.requires_hexagon def test_cache_read_write_2d(hexagon_session: Session): size = 128 outer_shape = (size,) diff --git a/tests/python/contrib/test_hexagon/topi/test_conv2d_nchw.py b/tests/python/contrib/test_hexagon/topi/test_conv2d_nchw.py index b3d6832ffaa9..7f530a5c4d80 100644 --- a/tests/python/contrib/test_hexagon/topi/test_conv2d_nchw.py +++ b/tests/python/contrib/test_hexagon/topi/test_conv2d_nchw.py @@ -27,8 +27,6 @@ from tvm.topi.utils import get_const_tuple from tvm.topi.nn.utils import get_pad_tuple -from ..conftest import requires_hexagon_toolchain - dtype = tvm.testing.parameter("float32") random_seed = tvm.testing.parameter(0) @@ -91,7 +89,7 @@ class BaseConv2DTests: dilation = tvm.testing.parameter(1) batch = tvm.testing.parameter(1) - @requires_hexagon_toolchain + @tvm.testing.requires_hexagon def test_conv2d_nchw( self, hexagon_session: Session, diff --git a/tests/python/contrib/test_hexagon/topi/test_conv2d_nhwc.py b/tests/python/contrib/test_hexagon/topi/test_conv2d_nhwc.py index 30b54d51348d..74a3f8dafa3e 100644 --- a/tests/python/contrib/test_hexagon/topi/test_conv2d_nhwc.py +++ b/tests/python/contrib/test_hexagon/topi/test_conv2d_nhwc.py @@ -25,9 +25,6 @@ from tvm.contrib.hexagon.session import Session import tvm.topi.testing from tvm.topi.utils import get_const_tuple -from tvm.topi.nn.utils import get_pad_tuple - -from ..conftest import requires_hexagon_toolchain dtype = tvm.testing.parameter("float32") @@ -46,7 +43,7 @@ def ref_data(dtype, batch, in_channel, in_size, num_filter, kernel, stride, padd class BaseConv2DTests: - @requires_hexagon_toolchain + @tvm.testing.requires_hexagon def test_conv2d_nhwc( self, hexagon_session: Session, diff --git a/tests/python/contrib/test_hexagon/topi/test_conv2d_transpose.py b/tests/python/contrib/test_hexagon/topi/test_conv2d_transpose.py index 0da740614f9d..629403965eae 100644 --- a/tests/python/contrib/test_hexagon/topi/test_conv2d_transpose.py +++ b/tests/python/contrib/test_hexagon/topi/test_conv2d_transpose.py @@ -22,9 +22,7 @@ from tvm import te from tvm import topi import tvm.topi.testing -from tvm.contrib.pickle_memoize import memoize from tvm.topi.utils import get_const_tuple -from ..conftest import requires_hexagon_toolchain # TODO Should add kernal to tvm.testing.fixture @@ -68,7 +66,7 @@ def shift_shape(output_padding): class BaseConv2DTransposeTests: - @requires_hexagon_toolchain + @tvm.testing.requires_hexagon def test_conv2d( self, hexagon_session: Session, diff --git a/tests/python/contrib/test_hexagon/topi/test_dense.py b/tests/python/contrib/test_hexagon/topi/test_dense.py index c63873a62d96..189b05fcaade 100644 --- a/tests/python/contrib/test_hexagon/topi/test_dense.py +++ b/tests/python/contrib/test_hexagon/topi/test_dense.py @@ -26,8 +26,6 @@ import tvm.topi.testing from tvm.topi.utils import get_const_tuple -from ..conftest import requires_hexagon_toolchain - random_seed = tvm.testing.parameter(0) use_bias = tvm.testing.parameter(True, False) @@ -68,7 +66,7 @@ def dense_ref_data(random_seed, batch_size, in_dim, out_dim, use_bias, in_dtype, return (a_np, b_np, c_np, d_np) -@requires_hexagon_toolchain +@tvm.testing.requires_hexagon def test_dense( hexagon_session: Session, batch_size, diff --git a/tests/python/contrib/test_hexagon/topi/test_depthwise_conv2d.py b/tests/python/contrib/test_hexagon/topi/test_depthwise_conv2d.py index ab2ce36e1f82..63ae0e7b3253 100644 --- a/tests/python/contrib/test_hexagon/topi/test_depthwise_conv2d.py +++ b/tests/python/contrib/test_hexagon/topi/test_depthwise_conv2d.py @@ -28,7 +28,6 @@ from tvm import te, topi from tvm.topi.utils import get_const_tuple from tvm.topi.nn.utils import get_pad_tuple -from ..conftest import requires_hexagon_toolchain random_seed = tvm.testing.parameter(0) @@ -155,7 +154,7 @@ class BaseDepthwiseConv2D: (e.g. implemented only for llvm). """ - @requires_hexagon_toolchain + @tvm.testing.requires_hexagon def test_conv2d( self, hexagon_session: Session, diff --git a/tests/python/contrib/test_hexagon/topi/test_pooling.py b/tests/python/contrib/test_hexagon/topi/test_pooling.py index 38b7f387e5c6..9ce54bf9a6eb 100644 --- a/tests/python/contrib/test_hexagon/topi/test_pooling.py +++ b/tests/python/contrib/test_hexagon/topi/test_pooling.py @@ -26,8 +26,6 @@ import tvm.topi.testing from tvm.topi.utils import get_const_tuple -from ..conftest import requires_hexagon_toolchain - class TestAdaptivePool: dshape, out_size, pool_type, layout = tvm.testing.parameters( @@ -57,7 +55,7 @@ class TestAdaptivePool: ((1, 16, 32, 32, 32), (2, 4, 4), "max", "NDHWC"), ) - @requires_hexagon_toolchain + @tvm.testing.requires_hexagon def test_adaptive_pool(self, hexagon_session: Session, dshape, out_size, pool_type, layout): dtype = "float32" np_data = np.random.uniform(low=0, high=255, size=dshape).astype(dtype) @@ -233,10 +231,10 @@ class TestPool1D: ([1, 31, 16], [3], [3], [3], [3, 0], "max", True, True, "NWC"), ) - @requires_hexagon_toolchain + @tvm.testing.requires_hexagon def test_pool1d( self, - hexagon_session, + hexagon_session: Session, input_shape, kernel, stride, @@ -310,10 +308,10 @@ class TestPool2D: ([1, 31, 31, 16], [3, 3], [3, 3], [2, 2], [3, 2, 1, 0], "max", True, True, "NHWC"), ) - @requires_hexagon_toolchain + @tvm.testing.requires_hexagon def test_pool2d( self, - hexagon_session, + hexagon_session: Session, input_shape, kernel, stride, @@ -708,10 +706,10 @@ class TestPool3D: ), ) - @requires_hexagon_toolchain + @tvm.testing.requires_hexagon def test_pool3d( self, - hexagon_session, + hexagon_session: Session, input_shape, kernel, stride, diff --git a/tests/python/contrib/test_hexagon/topi/test_reduce.py b/tests/python/contrib/test_hexagon/topi/test_reduce.py index beacb8cd1800..203a2bd31d6e 100644 --- a/tests/python/contrib/test_hexagon/topi/test_reduce.py +++ b/tests/python/contrib/test_hexagon/topi/test_reduce.py @@ -25,8 +25,6 @@ from tvm.contrib.hexagon.session import Session import tvm.topi.testing -from ..conftest import requires_hexagon_toolchain - in_shape, axis, keepdims, reduce_type, dtype = tvm.testing.parameters( ((32,), 0, False, "argmax", "float32"), @@ -101,7 +99,7 @@ def ref_data(in_shape, axis, keepdims, reduce_type, dtype): return in_npy, in_npy_map, out_npy -@requires_hexagon_toolchain +@tvm.testing.requires_hexagon def test_reduce_map( hexagon_session: Session, ref_data, in_shape, axis, keepdims, reduce_type, dtype ): diff --git a/tests/python/contrib/test_hexagon/topi/test_softmax.py b/tests/python/contrib/test_hexagon/topi/test_softmax.py index 6857decabf95..7e734af7e026 100644 --- a/tests/python/contrib/test_hexagon/topi/test_softmax.py +++ b/tests/python/contrib/test_hexagon/topi/test_softmax.py @@ -26,8 +26,6 @@ import tvm.topi.testing from tvm.topi.utils import get_const_tuple -from ..conftest import requires_hexagon_toolchain - dtype = tvm.testing.parameter( "float16", "float32", @@ -54,7 +52,7 @@ ) -@requires_hexagon_toolchain +@tvm.testing.requires_hexagon def test_softmax(hexagon_session: Session, shape, dtype, softmax_operation): if dtype == "float16": pytest.xfail("float16 is not supported.")