From 6957d59d62c2372ec26c6553b2abce9d9db6af0c Mon Sep 17 00:00:00 2001 From: Luke Hutton Date: Fri, 22 Jul 2022 09:28:48 +0000 Subject: [PATCH 1/2] [ETHOSN] Remove support for older versions of the driver stack Removes support for driver stack versions older than 22.05 (semantic 3.0.1). Additionally, changes the integration to make version checks using semantic versioning rather than the previous year.month versioning method. Change-Id: Ib2d1320f3ea6ace2a2b19cf122603911e7081db2 --- python/tvm/relay/op/contrib/ethosn.py | 11 +++- src/relay/backend/contrib/ethosn/codegen.cc | 5 +- .../backend/contrib/ethosn/codegen_ethosn.h | 1 - .../backend/contrib/ethosn/ethosn_api.cc | 1 - .../contrib/ethosn/ethosn_api_version.h | 58 ------------------- src/runtime/contrib/ethosn/ethosn_device.cc | 32 ---------- src/runtime/contrib/ethosn/ethosn_device.h | 7 --- src/runtime/contrib/ethosn/ethosn_runtime.cc | 12 ---- src/runtime/contrib/ethosn/ethosn_runtime.h | 3 - .../contrib/test_ethosn/infrastructure.py | 32 ---------- .../python/contrib/test_ethosn/test_conv2d.py | 2 +- .../test_ethosn/test_fullyconnected.py | 2 +- .../contrib/test_ethosn/test_networks.py | 50 ++-------------- .../python/contrib/test_ethosn/test_split.py | 15 +++-- .../contrib/test_ethosn/test_topologies.py | 22 ++++--- 15 files changed, 42 insertions(+), 211 deletions(-) delete mode 100644 src/relay/backend/contrib/ethosn/ethosn_api_version.h diff --git a/python/tvm/relay/op/contrib/ethosn.py b/python/tvm/relay/op/contrib/ethosn.py index 8db5aaca6605..4f10d86ac7e8 100644 --- a/python/tvm/relay/op/contrib/ethosn.py +++ b/python/tvm/relay/op/contrib/ethosn.py @@ -18,6 +18,7 @@ """Arm(R) Ethos(TM)-N NPU supported operators.""" from enum import Enum import warnings +from distutils.version import LooseVersion import tvm.ir from tvm.relay import transform @@ -80,6 +81,14 @@ def partition_for_ethosn(mod, params=None, **opts): elif opts["variant"] != "n78": raise ValueError("When targeting Ethos(TM)-N78, -variant=n78 should be set.") + api_version = ethosn_api_version() + expected_api_version = "3.0.1" + if api_version != LooseVersion(expected_api_version): + raise ValueError( + f"Driver stack version {api_version} unsupported. " + f"Please use version {expected_api_version}." + ) + if params: mod["main"] = bind_params_by_name(mod["main"], params) @@ -298,7 +307,7 @@ def split(expr): """Check if a split is supported by Ethos-N.""" if not ethosn_available(): return False - if ethosn_api_version() == 2205: + if ethosn_api_version() != LooseVersion("3.0.1"): return False if not support.split(expr): return False diff --git a/src/relay/backend/contrib/ethosn/codegen.cc b/src/relay/backend/contrib/ethosn/codegen.cc index 5ae580861aaa..f5cce30e4521 100644 --- a/src/relay/backend/contrib/ethosn/codegen.cc +++ b/src/relay/backend/contrib/ethosn/codegen.cc @@ -22,6 +22,7 @@ * \brief The Relay -> Arm(R) Ethos(TM)-N command stream compiler. */ #include +#include #include #include "codegen_ethosn.h" @@ -965,8 +966,8 @@ TVM_REGISTER_GLOBAL("relay.ethos-n.query").set_body([](tvm::TVMArgs args, tvm::T #endif }); -TVM_REGISTER_GLOBAL("relay.ethos-n.api.version").set_body_typed([]() -> int { - return _ETHOSN_API_VERSION_; +TVM_REGISTER_GLOBAL("relay.ethos-n.api.version").set_body_typed([]() -> String { + return sl::GetLibraryVersion().ToString(); }); } // namespace ethosn diff --git a/src/relay/backend/contrib/ethosn/codegen_ethosn.h b/src/relay/backend/contrib/ethosn/codegen_ethosn.h index 3fbf5a77a70b..66aefab16d2d 100644 --- a/src/relay/backend/contrib/ethosn/codegen_ethosn.h +++ b/src/relay/backend/contrib/ethosn/codegen_ethosn.h @@ -46,7 +46,6 @@ #include "../../../../runtime/contrib/ethosn/ethosn_runtime.h" #include "../codegen_c/codegen_c.h" #include "ethosn_api.h" -#include "ethosn_api_version.h" #include "ethosn_support_library/Support.hpp" #include "ethosn_support_library/SupportQueries.hpp" diff --git a/src/relay/backend/contrib/ethosn/ethosn_api.cc b/src/relay/backend/contrib/ethosn/ethosn_api.cc index 2a9dd330e230..c828762096d6 100644 --- a/src/relay/backend/contrib/ethosn/ethosn_api.cc +++ b/src/relay/backend/contrib/ethosn/ethosn_api.cc @@ -36,7 +36,6 @@ #include #include -#include "ethosn_api_version.h" #include "ethosn_support_library/Support.hpp" #include "ethosn_support_library/SupportQueries.hpp" #include "tvm/relay/qnn/attrs.h" diff --git a/src/relay/backend/contrib/ethosn/ethosn_api_version.h b/src/relay/backend/contrib/ethosn/ethosn_api_version.h deleted file mode 100644 index b1067679f22c..000000000000 --- a/src/relay/backend/contrib/ethosn/ethosn_api_version.h +++ /dev/null @@ -1,58 +0,0 @@ -/* - * 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. - */ - -/*! - * \file src/relay/backend/contrib/ethosn/ethosn_api_version.h - * \brief Arm(R) Ethos(TM)-N versioning - */ -#include "ethosn_support_library/Support.hpp" - -#ifndef TVM_RELAY_BACKEND_CONTRIB_ETHOSN_ETHOSN_API_VERSION_H_ -#define TVM_RELAY_BACKEND_CONTRIB_ETHOSN_ETHOSN_API_VERSION_H_ - -/*! - * \brief To be used as a temperory switch to ensure - * compatibility with the previous version of the api - * while needed e.g. by docker images. Can be removed - * along with associated compatibility measures when no - * longer necessary. - */ - -#if ETHOSN_SUPPORT_LIBRARY_VERSION_MAJOR == 3 && ETHOSN_SUPPORT_LIBRARY_VERSION_MINOR == 0 && \ - ETHOSN_SUPPORT_LIBRARY_VERSION_PATCH == 1 -#define _ETHOSN_API_VERSION_ 2205 -#elif ETHOSN_SUPPORT_LIBRARY_VERSION_MAJOR == 3 && ETHOSN_SUPPORT_LIBRARY_VERSION_MINOR == 0 && \ - ETHOSN_SUPPORT_LIBRARY_VERSION_PATCH == 0 -#define _ETHOSN_API_VERSION_ 2111 -#else -#if ETHOSN_SUPPORT_LIBRARY_VERSION_MAJOR == 1 && ETHOSN_SUPPORT_LIBRARY_VERSION_MINOR == 1 && \ - ETHOSN_SUPPORT_LIBRARY_VERSION_PATCH == 0 -#define _ETHOSN_API_VERSION_ 2108 -#else -#ifndef ETHOSN_API_VERSION -#define _ETHOSN_API_VERSION_ 2102 -#elif ~(~ETHOSN_API_VERSION + 0) == 0 && ~(~ETHOSN_API_VERSION + 1) == 1 -#define _ETHOSN_API_VERSION_ 2102 -#else -#define _ETHOSN_API_VERSION_ ETHOSN_API_VERSION -#endif -#endif -#endif - -#endif // TVM_RELAY_BACKEND_CONTRIB_ETHOSN_ETHOSN_API_VERSION_H_ diff --git a/src/runtime/contrib/ethosn/ethosn_device.cc b/src/runtime/contrib/ethosn/ethosn_device.cc index 348a55046059..628f99788d16 100644 --- a/src/runtime/contrib/ethosn/ethosn_device.cc +++ b/src/runtime/contrib/ethosn/ethosn_device.cc @@ -80,16 +80,9 @@ void CopyOutput(dl::Buffer* source_buffers[], std::vector* outputs) { dl::Buffer* source_buffer = source_buffers[0]; T* dest_pointer = static_cast(tensor->data); size_t size = source_buffer->GetSize(); -#if _ETHOSN_API_VERSION_ < 2111 - uint8_t* source_buffer_data = source_buffer->GetMappedBuffer(); -#else uint8_t* source_buffer_data = source_buffer->Map(); -#endif std::copy_backward(source_buffer_data, source_buffer_data + size, dest_pointer + size); -#if _ETHOSN_API_VERSION_ >= 2111 source_buffer->Unmap(); -#else -#endif source_buffers++; } } @@ -107,17 +100,10 @@ void CreateBuffers(std::vector >* fm, } } -#if _ETHOSN_API_VERSION_ <= 2102 -bool Inference(tvm::runtime::TVMArgs args, sl::CompiledNetwork* network, - const std::vector& input_order, const std::vector& output_order, - const std::vector& input_sizes, - const std::vector& output_sizes) { -#else bool Inference(tvm::runtime::TVMArgs args, dl::Network* npu, const std::vector& input_order, const std::vector& output_order, const std::vector& input_sizes, const std::vector& output_sizes) { -#endif // Unpack parameters size_t n_inputs = input_order.size(); size_t n_outputs = output_order.size(); @@ -149,10 +135,6 @@ bool Inference(tvm::runtime::TVMArgs args, dl::Network* npu, ofm_raw[i] = ofm[i].get(); } -#if _ETHOSN_API_VERSION_ <= 2102 - auto npu = std::make_unique(*network); -#endif - // Execute the inference. std::unique_ptr result( npu->ScheduleInference(ifm_raw, sizeof(ifm_raw) / sizeof(ifm_raw[0]), ofm_raw, @@ -164,20 +146,13 @@ bool Inference(tvm::runtime::TVMArgs args, dl::Network* npu, dl::Buffer** ofms = &ofm_raw[0]; for (DLTensor* tensor : outputs) { dl::Buffer* source_buffer = (*ofms++); -#if _ETHOSN_API_VERSION_ < 2111 - uint8_t* source_buffer_data = source_buffer->GetMappedBuffer(); -#else uint8_t* source_buffer_data = source_buffer->Map(); -#endif uint8_t* dest_pointer = static_cast(tensor->data); if (source_buffer_data != dest_pointer) { CopyOutput(ofm_raw, &outputs); break; } -#if _ETHOSN_API_VERSION_ >= 2111 source_buffer->Unmap(); -#else -#endif } break; } @@ -229,17 +204,10 @@ TVM_REGISTER_GLOBAL("relay.ethos-n.test.infra.inference_result") }); // Allow the ethos-n support code to be tested without a device -#if _ETHOSN_API_VERSION_ <= 2102 -bool Inference(tvm::runtime::TVMArgs args, sl::CompiledNetwork* network, - const std::vector& input_order, const std::vector& output_order, - const std::vector& input_sizes, - const std::vector& output_sizes) { -#else bool Inference(tvm::runtime::TVMArgs args, dl::Network* /* npu */, const std::vector& input_order, const std::vector& output_order, const std::vector& input_sizes, const std::vector& output_sizes) { -#endif std::vector outputs; for (int argc = input_order.size(); argc < args.size(); argc++) { outputs.push_back(args[argc]); diff --git a/src/runtime/contrib/ethosn/ethosn_device.h b/src/runtime/contrib/ethosn/ethosn_device.h index 2d1e536ef8e7..acef104515e1 100644 --- a/src/runtime/contrib/ethosn/ethosn_device.h +++ b/src/runtime/contrib/ethosn/ethosn_device.h @@ -28,7 +28,6 @@ #include -#include "../../../relay/backend/contrib/ethosn/ethosn_api_version.h" #include "ethosn_runtime.h" namespace tvm { @@ -39,15 +38,9 @@ namespace dl = ::ethosn::driver_library; using tvm::runtime::TVMArgs; -#if _ETHOSN_API_VERSION_ <= 2102 -bool Inference(TVMArgs args, sl::CompiledNetwork* npu, const std::vector& input_order, - const std::vector& output_order, const std::vector& input_sizes, - const std::vector& output_sizes); -#else bool Inference(tvm::runtime::TVMArgs args, dl::Network* npu, const std::vector& input_order, const std::vector& output_order, const std::vector& input_sizes, const std::vector& output_sizes); -#endif } // namespace ethosn } // namespace runtime diff --git a/src/runtime/contrib/ethosn/ethosn_runtime.cc b/src/runtime/contrib/ethosn/ethosn_runtime.cc index 295ff537b379..dc2d4da853f8 100644 --- a/src/runtime/contrib/ethosn/ethosn_runtime.cc +++ b/src/runtime/contrib/ethosn/ethosn_runtime.cc @@ -53,11 +53,9 @@ EthosnModule::EthosnModule(std::vector* cmms) { if (it.compiled_cmm != nullptr) { network_map_[it.name].compiled_cmm = std::move(it.compiled_cmm); } -#if _ETHOSN_API_VERSION_ > 2102 if (it.runtime_cmm != nullptr) { network_map_[it.name].runtime_cmm = std::move(it.runtime_cmm); } -#endif network_map_[it.name].inputs = it.inputs; network_map_[it.name].outputs = it.outputs; network_map_[it.name].input_sizes = it.input_sizes; @@ -69,15 +67,9 @@ PackedFunc EthosnModule::GetFunction(const std::string& name, const ObjectPtr& sptr_to_self) { if (network_map_.find(name) != network_map_.end()) { return PackedFunc([sptr_to_self, this, name](TVMArgs args, TVMRetValue* rv) { -#if _ETHOSN_API_VERSION_ <= 2102 - *rv = Inference(args, network_map_[name].compiled_cmm.get(), network_map_[name].inputs, - network_map_[name].outputs, network_map_[name].input_sizes, - network_map_[name].output_sizes); -#else *rv = Inference(args, network_map_[name].runtime_cmm.get(), network_map_[name].inputs, network_map_[name].outputs, network_map_[name].input_sizes, network_map_[name].output_sizes); -#endif }); } else { return PackedFunc(); @@ -119,14 +111,10 @@ Module EthosnModule::LoadFromBinary(void* strm) { // Read the serialized command stream stream->Read(&cmm); std::istringstream cmm_strm(cmm); -#if _ETHOSN_API_VERSION_ <= 2102 - compiled.compiled_cmm = sl::DeserializeCompiledNetwork(cmm_strm); -#else #if defined ETHOSN_HW // If hardware unavaiable use the mock inference functionality. If hardware is // avaiable, deserialize the compiled graph. compiled.runtime_cmm = std::make_unique(cmm.c_str(), cmm.size()); -#endif #endif // Read the number of inputs stream->Read(&input_size); diff --git a/src/runtime/contrib/ethosn/ethosn_runtime.h b/src/runtime/contrib/ethosn/ethosn_runtime.h index b60250754b31..7c8c32e784be 100644 --- a/src/runtime/contrib/ethosn/ethosn_runtime.h +++ b/src/runtime/contrib/ethosn/ethosn_runtime.h @@ -33,7 +33,6 @@ #include #include -#include "../../../relay/backend/contrib/ethosn/ethosn_api_version.h" #include "ethosn_driver_library/Network.hpp" #include "ethosn_support_library/Support.hpp" @@ -46,9 +45,7 @@ namespace dl = ::ethosn::driver_library; struct OrderedCompiledNetwork { std::unique_ptr compiled_cmm; -#if _ETHOSN_API_VERSION_ > 2102 std::unique_ptr runtime_cmm; -#endif std::string name; std::vector inputs; std::vector outputs; diff --git a/tests/python/contrib/test_ethosn/infrastructure.py b/tests/python/contrib/test_ethosn/infrastructure.py index e551f0a929ae..c227ef5c3aea 100644 --- a/tests/python/contrib/test_ethosn/infrastructure.py +++ b/tests/python/contrib/test_ethosn/infrastructure.py @@ -270,33 +270,6 @@ def test_error(mod, params, err_msg): assert err_msg in caught, caught -def get_overall_scale_range_expected_error_message(): - """ - Get the expected error message when the overall scale is out of range. - Different versions of the driver stack support different scale ranges, - so creating a unified utility to obtain the expected message. - """ - if get_ethosn_api_version() >= 2205: - lb = "2^-32" - elif get_ethosn_api_version() > 2102: - lb = "2.328306e-10" - else: - lb = "0" - - if get_ethosn_api_version() >= 2205: - ub = "65536" - else: - ub = "1" - - lb_bracket = "(" if get_ethosn_api_version() >= 2205 else "[" - ub_bracket = ")" - - return ( - "Overall scale (of the input * weights / output) should be in the range " - f"{lb_bracket}{lb}, {ub}{ub_bracket}" - ) - - def get_conv2d(var, shape, dtype): """Standard convolution to test activation functions""" @@ -359,10 +332,5 @@ def get_conv2d_qnn_params( return output_zp, output_sc -def get_ethosn_api_version(): - gf = tvm.get_global_func("relay.ethos-n.api.version", True) - return gf() if gf else None - - def get_ethosn_variant(): return os.getenv("ETHOSN_VARIANT_CONFIG", default="Ethos-N78_1TOPS_2PLE_RATIO") diff --git a/tests/python/contrib/test_ethosn/test_conv2d.py b/tests/python/contrib/test_ethosn/test_conv2d.py index dbf790321820..a411701ea0bc 100644 --- a/tests/python/contrib/test_ethosn/test_conv2d.py +++ b/tests/python/contrib/test_ethosn/test_conv2d.py @@ -226,7 +226,7 @@ def test_conv2d_failure(): "uint8", 8, "HWIO", - tei.get_overall_scale_range_expected_error_message(), + "Overall scale (of the input * weights / output) should be in the range (2^-32, 65536)", ), ( (1, 4, 4, 4), diff --git a/tests/python/contrib/test_ethosn/test_fullyconnected.py b/tests/python/contrib/test_ethosn/test_fullyconnected.py index 95f68622d912..2caca9e890a2 100644 --- a/tests/python/contrib/test_ethosn/test_fullyconnected.py +++ b/tests/python/contrib/test_ethosn/test_fullyconnected.py @@ -127,7 +127,7 @@ def test_fullyconnected_failure(): 0, 1, "uint8", - tei.get_overall_scale_range_expected_error_message(), + "Overall scale (of the input * weights / output) should be in the range (2^-32, 65536)", ), ( (1, 1, 1, 64), diff --git a/tests/python/contrib/test_ethosn/test_networks.py b/tests/python/contrib/test_ethosn/test_networks.py index c23bd01e0960..abc4d37a7359 100644 --- a/tests/python/contrib/test_ethosn/test_networks.py +++ b/tests/python/contrib/test_ethosn/test_networks.py @@ -25,7 +25,6 @@ from tvm import relay from tvm.testing import requires_ethosn from tvm.contrib import download -from tvm.testing import requires_ethosn import tvm.relay.testing.tf as tf_testing import tflite.Model @@ -123,16 +122,7 @@ def test_mobilenet_v1(): # codegen, which could come about from either a change in Support Library # version or a change in the Ethos-N codegen. To update this requires running # on hardware that isn't available in CI. - if tei.get_ethosn_api_version() == 2205: - _compile_hash = {"50186822915909303e813205db80e032"} - elif tei.get_ethosn_api_version() == 2111: - _compile_hash = {"c523c3c2bb9add1fee508217eb73af1a"} - elif tei.get_ethosn_api_version() == 2102: - _compile_hash = {"46ccafc840633633aca441645e41b444"} - if tei.get_ethosn_variant() == "Ethos-N78_1TOPS_2PLE_RATIO": - _compile_hash = {"e4ed29dceb1187505948ab17fc3cc6d6"} - else: - _compile_hash = {"393a19dfb980345cdd3bbeddbc36424d"} + _compile_hash = {"50186822915909303e813205db80e032"} _test_image_network( model_url="https://storage.googleapis.com/download.tensorflow.org/" "models/mobilenet_v1_2018_08_02/mobilenet_v1_1.0_224_quant.tgz", @@ -153,10 +143,7 @@ def test_resnet_50_int8(): # codegen, which could come about from either a change in Support Library # version or a change in the Ethos-N codegen. To update this requires running # on hardware that isn't available in CI. - if tei.get_ethosn_api_version() == 2205: - _compile_hash = {"60404ad60fc2bfbb68464d8a14cc0452", "4225fa951c145bb1e48e28cad6a3bdd4"} - else: - _compile_hash = {"60404ad60fc2bfbb68464d8a14cc0452", "5b9d72b9accfea7ed89eb09ca0aa5487"} + _compile_hash = {"60404ad60fc2bfbb68464d8a14cc0452", "4225fa951c145bb1e48e28cad6a3bdd4"} _test_image_network( model_url="https://raw.githubusercontent.com/dmlc/web-data/main/tensorflow/" "models/Quantized/resnet_50_quantized.tflite", @@ -176,16 +163,7 @@ def test_inception_v3(): # codegen, which could come about from either a change in Support Library # version or a change in the Ethos-N codegen. To update this requires running # on hardware that isn't available in CI. - if tei.get_ethosn_api_version() == 2205: - _compile_hash = {"a5a2b5d2b618de754bf9a01033a020c0"} - elif tei.get_ethosn_api_version() == 2111: - _compile_hash = {"88db2c7928240be9833c1b5ef367de28"} - elif tei.get_ethosn_api_version() == 2102: - _compile_hash = {"43dc2097127eb224c0191b1a15f8acca"} - if tei.get_ethosn_variant() == "Ethos-N78_1TOPS_2PLE_RATIO": - _compile_hash = {"7db23387bdc5af6eaa1ae3f7d456caf0"} - else: - _compile_hash = {"2c7ff5487e1a21e62b3b42eec624fed4"} + _compile_hash = {"a5a2b5d2b618de754bf9a01033a020c0"} _test_image_network( model_url="https://storage.googleapis.com/download.tensorflow.org/" "models/tflite_11_05_08/inception_v3_quant.tgz", @@ -205,16 +183,7 @@ def test_inception_v4(): # codegen, which could come about from either a change in Support Library # version or a change in the Ethos-N codegen. To update this requires running # on hardware that isn't available in CI. - if tei.get_ethosn_api_version() == 2205: - _compile_hash = {"61b4ade41898d7cb2451dbdc3340aced"} - elif tei.get_ethosn_api_version() == 2111: - _compile_hash = {"37648682f97cbbcecdc13945b7f2212f"} - elif tei.get_ethosn_api_version() == 2102: - _compile_hash = {"fab6c2297502f95d33079c6ce1a737f9"} - if tei.get_ethosn_variant() == "Ethos-N78_1TOPS_2PLE_RATIO": - _compile_hash = {"8da68849b75613ac3dffd3fff2dd87da"} - else: - _compile_hash = {"4245dbd02e1432dc261a67fc8e632a00"} + _compile_hash = {"61b4ade41898d7cb2451dbdc3340aced"} _test_image_network( model_url="https://storage.googleapis.com/download.tensorflow.org/" "models/inception_v4_299_quant_20181026.tgz", @@ -234,16 +203,7 @@ def test_ssd_mobilenet_v1(): # codegen, which could come about from either a change in Support Library # version or a change in the Ethos-N codegen. To update this requires running # on hardware that isn't available in CI. - if tei.get_ethosn_api_version() == 2205: - _compile_hash = {"789906c7d8ac787809b303d82781fc9d", "6b699f94795785d31b39940a5cf84a81"} - elif tei.get_ethosn_api_version() == 2111: - _compile_hash = {"7b8b0a3ad7cfe1695dee187f21f03785", "6b699f94795785d31b39940a5cf84a81"} - elif tei.get_ethosn_api_version() == 2102: - _compile_hash = {"7795b6c67178da9d1f9b98063bad75b1", "10826406ae724e52f360a06c35ced09d"} - if tei.get_ethosn_variant() == "Ethos-N78_1TOPS_2PLE_RATIO": - _compile_hash = {"928dc6ae5ce49a4ad63ca87f7575970f", "b092f9820f7e9341fc53daa781b98772"} - else: - _compile_hash = {"5ee8ed6af9a7f31fc14957b51a8e7423", "e6a91ccc47ba4c6b4614fcd676bd726f"} + _compile_hash = {"789906c7d8ac787809b303d82781fc9d", "6b699f94795785d31b39940a5cf84a81"} _test_image_network( model_url="https://storage.googleapis.com/download.tensorflow.org/" "models/tflite/coco_ssd_mobilenet_v1_1.0_quant_2018_06_29.zip", diff --git a/tests/python/contrib/test_ethosn/test_split.py b/tests/python/contrib/test_ethosn/test_split.py index bd75371c9441..9c92abda5b85 100644 --- a/tests/python/contrib/test_ethosn/test_split.py +++ b/tests/python/contrib/test_ethosn/test_split.py @@ -17,11 +17,16 @@ """Split tests for Arm(R) Ethos(TM)-N""" +from distutils.version import LooseVersion + import numpy as np import pytest + import tvm from tvm import relay from tvm.testing import requires_ethosn +from tvm.relay.op.contrib.ethosn import ethosn_api_version + from . import infrastructure as tei @@ -32,8 +37,8 @@ def _get_model(shape, dtype, splits, axis): @pytest.mark.skipif( - tei.get_ethosn_api_version() == 2205, - reason="Split is not supported by the 22.05 release of the driver stack", + ethosn_api_version() >= LooseVersion("3.0.1"), + reason="Split is not supported by this release of the driver stack", ) @requires_ethosn @pytest.mark.parametrize("dtype", ["uint8", "int8"]) @@ -42,8 +47,6 @@ def test_split(dtype): ((1, 16, 16, 32), (2, 7, 10), 2), ((1, 12, 8, 16), 3, 1), ] - if tei.get_ethosn_api_version() < 2111: - trials.append(((1, 66), 11, 1)) np.random.seed(0) for shape, splits, axis in trials: @@ -65,8 +68,8 @@ def test_split(dtype): @pytest.mark.skipif( - tei.get_ethosn_api_version() == 2205, - reason="Split is not supported by the 22.05 release of the driver stack", + ethosn_api_version() >= LooseVersion("3.0.1"), + reason="Split is not supported by this release of the driver stack", ) @requires_ethosn def test_split_failure(): diff --git a/tests/python/contrib/test_ethosn/test_topologies.py b/tests/python/contrib/test_ethosn/test_topologies.py index 8f8c353de28f..7665572855f7 100644 --- a/tests/python/contrib/test_ethosn/test_topologies.py +++ b/tests/python/contrib/test_ethosn/test_topologies.py @@ -17,12 +17,16 @@ """Arm(R) Ethos(TM)-N tests for complex network topologies.""" +from distutils.version import LooseVersion + import numpy as np import pytest + import tvm from tvm import relay from tvm.testing import requires_ethosn -from tvm.relay.op.contrib.ethosn import Available, ethosn_available +from tvm.relay.op.contrib.ethosn import Available, ethosn_available, ethosn_api_version + from . import infrastructure as tei @@ -74,11 +78,11 @@ def get_model(input_shape, dtype, var_names): model = get_model(inputs["a"].shape, dtype, iter(inputs)) mod = tei.make_module(model, []) - expected_host_ops = 1 if tei.get_ethosn_api_version() == 2205 else 0 - npu_partitions = 2 if tei.get_ethosn_api_version() == 2205 else 1 + expected_host_ops = 1 + npu_partitions = 2 # Mock inference is only supported when the whole graph is offloaded to the NPU - if tei.get_ethosn_api_version() == 2205 and ethosn_available() == Available.SW_ONLY: + if ethosn_available() == Available.SW_ONLY: tei.build( mod, {}, npu=npu, expected_host_ops=expected_host_ops, npu_partitions=npu_partitions ) @@ -272,11 +276,11 @@ def get_model(shape, dtype, splits, axis): model = get_model(shape, dtype, splits, axis) mod = tei.make_module(model, {}) - expected_host_ops = 1 if tei.get_ethosn_api_version() == 2205 else 0 - npu_partitions = 2 if tei.get_ethosn_api_version() == 2205 else 1 + expected_host_ops = 1 + npu_partitions = 2 # Mock inference is only supported when the whole graph is offloaded to the NPU - if tei.get_ethosn_api_version() == 2205 and ethosn_available() == Available.SW_ONLY: + if ethosn_available() == Available.SW_ONLY: tei.build( mod, {}, @@ -302,8 +306,8 @@ def get_model(shape, dtype, splits, axis): @pytest.mark.skipif( - tei.get_ethosn_api_version() == 2205, - reason="Split is not supported by the 22.05 release of the driver stack", + ethosn_api_version() >= LooseVersion("3.0.1"), + reason="Split is not supported by this release of the driver stack", ) @requires_ethosn @pytest.mark.parametrize("dtype", ["uint8", "int8"]) From 3cf068f685d9bf491d6a9c4af2b7a1086d889190 Mon Sep 17 00:00:00 2001 From: Luke Hutton Date: Tue, 9 Aug 2022 14:22:42 +0000 Subject: [PATCH 2/2] Fix case when driver stack version is not available Change-Id: Ie6e09982169cb8f435c2ba4683159deb2aa6fd20 --- python/tvm/relay/op/contrib/ethosn.py | 16 ++++++++++++---- tests/python/contrib/test_ethosn/test_split.py | 13 ++----------- .../contrib/test_ethosn/test_topologies.py | 9 ++------- 3 files changed, 16 insertions(+), 22 deletions(-) diff --git a/python/tvm/relay/op/contrib/ethosn.py b/python/tvm/relay/op/contrib/ethosn.py index 4f10d86ac7e8..eb753ef1391f 100644 --- a/python/tvm/relay/op/contrib/ethosn.py +++ b/python/tvm/relay/op/contrib/ethosn.py @@ -47,8 +47,16 @@ def ethosn_available(): return Available.SW_AND_HW if hw else Available.SW_ONLY -def ethosn_api_version(): - """Returns the version of the driver stack api that is being used.""" +def ethosn_api_version() -> str: + """ + Returns the semantic version of the driver stack api that is + being used. + + Returns + ------- + str + Semantic version string (e.g. 3.0.1). + """ return tvm.get_global_func("relay.ethos-n.api.version")() @@ -85,7 +93,7 @@ def partition_for_ethosn(mod, params=None, **opts): expected_api_version = "3.0.1" if api_version != LooseVersion(expected_api_version): raise ValueError( - f"Driver stack version {api_version} unsupported. " + f"Driver stack version {api_version} is unsupported. " f"Please use version {expected_api_version}." ) @@ -307,7 +315,7 @@ def split(expr): """Check if a split is supported by Ethos-N.""" if not ethosn_available(): return False - if ethosn_api_version() != LooseVersion("3.0.1"): + if ethosn_api_version() >= LooseVersion("3.0.1"): return False if not support.split(expr): return False diff --git a/tests/python/contrib/test_ethosn/test_split.py b/tests/python/contrib/test_ethosn/test_split.py index 9c92abda5b85..4d1743d07a32 100644 --- a/tests/python/contrib/test_ethosn/test_split.py +++ b/tests/python/contrib/test_ethosn/test_split.py @@ -17,15 +17,12 @@ """Split tests for Arm(R) Ethos(TM)-N""" -from distutils.version import LooseVersion - import numpy as np import pytest import tvm from tvm import relay from tvm.testing import requires_ethosn -from tvm.relay.op.contrib.ethosn import ethosn_api_version from . import infrastructure as tei @@ -36,10 +33,7 @@ def _get_model(shape, dtype, splits, axis): return split.astuple() -@pytest.mark.skipif( - ethosn_api_version() >= LooseVersion("3.0.1"), - reason="Split is not supported by this release of the driver stack", -) +@pytest.mark.skip("Split is not supported by the 3.0.1 version of the driver stack.") @requires_ethosn @pytest.mark.parametrize("dtype", ["uint8", "int8"]) def test_split(dtype): @@ -67,10 +61,7 @@ def test_split(dtype): tei.verify(outputs, dtype, 0) -@pytest.mark.skipif( - ethosn_api_version() >= LooseVersion("3.0.1"), - reason="Split is not supported by this release of the driver stack", -) +@pytest.mark.skip("Split is not supported by the 3.0.1 version of the driver stack.") @requires_ethosn def test_split_failure(): trials = [ diff --git a/tests/python/contrib/test_ethosn/test_topologies.py b/tests/python/contrib/test_ethosn/test_topologies.py index 7665572855f7..970f7dce5cbd 100644 --- a/tests/python/contrib/test_ethosn/test_topologies.py +++ b/tests/python/contrib/test_ethosn/test_topologies.py @@ -17,15 +17,13 @@ """Arm(R) Ethos(TM)-N tests for complex network topologies.""" -from distutils.version import LooseVersion - import numpy as np import pytest import tvm from tvm import relay from tvm.testing import requires_ethosn -from tvm.relay.op.contrib.ethosn import Available, ethosn_available, ethosn_api_version +from tvm.relay.op.contrib.ethosn import Available, ethosn_available from . import infrastructure as tei @@ -305,10 +303,7 @@ def get_model(shape, dtype, splits, axis): tei.verify(outputs, dtype, 0) -@pytest.mark.skipif( - ethosn_api_version() >= LooseVersion("3.0.1"), - reason="Split is not supported by this release of the driver stack", -) +@pytest.mark.skip("Split is not supported by the 3.0.1 version of the driver stack.") @requires_ethosn @pytest.mark.parametrize("dtype", ["uint8", "int8"]) def test_output_tuple_propagation(dtype):