Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions python/tvm/relay/op/contrib/ethosn.py
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -46,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")()


Expand Down Expand Up @@ -80,6 +89,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} is unsupported. "
f"Please use version {expected_api_version}."
)

if params:
mod["main"] = bind_params_by_name(mod["main"], params)

Expand Down Expand Up @@ -298,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() == 2205:
if ethosn_api_version() >= LooseVersion("3.0.1"):
return False
if not support.split(expr):
return False
Expand Down
5 changes: 3 additions & 2 deletions src/relay/backend/contrib/ethosn/codegen.cc
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
* \brief The Relay -> Arm(R) Ethos(TM)-N command stream compiler.
*/
#include <tvm/relay/expr_functor.h>
#include <tvm/runtime/container/string.h>
#include <tvm/runtime/module.h>

#include "codegen_ethosn.h"
Expand Down Expand Up @@ -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
Expand Down
1 change: 0 additions & 1 deletion src/relay/backend/contrib/ethosn/codegen_ethosn.h
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand Down
1 change: 0 additions & 1 deletion src/relay/backend/contrib/ethosn/ethosn_api.cc
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@
#include <utility>
#include <vector>

#include "ethosn_api_version.h"
#include "ethosn_support_library/Support.hpp"
#include "ethosn_support_library/SupportQueries.hpp"
#include "tvm/relay/qnn/attrs.h"
Expand Down
58 changes: 0 additions & 58 deletions src/relay/backend/contrib/ethosn/ethosn_api_version.h

This file was deleted.

32 changes: 0 additions & 32 deletions src/runtime/contrib/ethosn/ethosn_device.cc
Original file line number Diff line number Diff line change
Expand Up @@ -80,16 +80,9 @@ void CopyOutput(dl::Buffer* source_buffers[], std::vector<DLTensor*>* outputs) {
dl::Buffer* source_buffer = source_buffers[0];
T* dest_pointer = static_cast<T*>(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++;
}
}
Expand All @@ -107,17 +100,10 @@ void CreateBuffers(std::vector<std::shared_ptr<dl::Buffer> >* fm,
}
}

#if _ETHOSN_API_VERSION_ <= 2102
bool Inference(tvm::runtime::TVMArgs args, sl::CompiledNetwork* network,
const std::vector<uint32_t>& input_order, const std::vector<uint32_t>& output_order,
const std::vector<uint32_t>& input_sizes,
const std::vector<uint32_t>& output_sizes) {
#else
bool Inference(tvm::runtime::TVMArgs args, dl::Network* npu,
const std::vector<uint32_t>& input_order, const std::vector<uint32_t>& output_order,
const std::vector<uint32_t>& input_sizes,
const std::vector<uint32_t>& output_sizes) {
#endif
// Unpack parameters
size_t n_inputs = input_order.size();
size_t n_outputs = output_order.size();
Expand Down Expand Up @@ -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<dl::Network>(*network);
#endif

// Execute the inference.
std::unique_ptr<dl::Inference> result(
npu->ScheduleInference(ifm_raw, sizeof(ifm_raw) / sizeof(ifm_raw[0]), ofm_raw,
Expand All @@ -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<uint8_t*>(tensor->data);
if (source_buffer_data != dest_pointer) {
CopyOutput<uint8_t>(ofm_raw, &outputs);
break;
}
#if _ETHOSN_API_VERSION_ >= 2111
source_buffer->Unmap();
#else
#endif
}
break;
}
Expand Down Expand Up @@ -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<uint32_t>& input_order, const std::vector<uint32_t>& output_order,
const std::vector<uint32_t>& input_sizes,
const std::vector<uint32_t>& output_sizes) {
#else
bool Inference(tvm::runtime::TVMArgs args, dl::Network* /* npu */,
const std::vector<uint32_t>& input_order, const std::vector<uint32_t>& output_order,
const std::vector<uint32_t>& input_sizes,
const std::vector<uint32_t>& output_sizes) {
#endif
std::vector<DLTensor*> outputs;
for (int argc = input_order.size(); argc < args.size(); argc++) {
outputs.push_back(args[argc]);
Expand Down
7 changes: 0 additions & 7 deletions src/runtime/contrib/ethosn/ethosn_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@

#include <vector>

#include "../../../relay/backend/contrib/ethosn/ethosn_api_version.h"
#include "ethosn_runtime.h"

namespace tvm {
Expand All @@ -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<uint32_t>& input_order,
const std::vector<uint32_t>& output_order, const std::vector<uint32_t>& input_sizes,
const std::vector<uint32_t>& output_sizes);
#else
bool Inference(tvm::runtime::TVMArgs args, dl::Network* npu,
const std::vector<uint32_t>& input_order, const std::vector<uint32_t>& output_order,
const std::vector<uint32_t>& input_sizes, const std::vector<uint32_t>& output_sizes);
#endif

} // namespace ethosn
} // namespace runtime
Expand Down
12 changes: 0 additions & 12 deletions src/runtime/contrib/ethosn/ethosn_runtime.cc
Original file line number Diff line number Diff line change
Expand Up @@ -53,11 +53,9 @@ EthosnModule::EthosnModule(std::vector<OrderedCompiledNetwork>* 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;
Expand All @@ -69,15 +67,9 @@ PackedFunc EthosnModule::GetFunction(const std::string& name,
const ObjectPtr<Object>& 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();
Expand Down Expand Up @@ -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<dl::Network>(cmm.c_str(), cmm.size());
#endif
#endif
// Read the number of inputs
stream->Read<uint64_t>(&input_size);
Expand Down
3 changes: 0 additions & 3 deletions src/runtime/contrib/ethosn/ethosn_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
#include <unordered_map>
#include <vector>

#include "../../../relay/backend/contrib/ethosn/ethosn_api_version.h"
#include "ethosn_driver_library/Network.hpp"
#include "ethosn_support_library/Support.hpp"

Expand All @@ -46,9 +45,7 @@ namespace dl = ::ethosn::driver_library;

struct OrderedCompiledNetwork {
std::unique_ptr<sl::CompiledNetwork> compiled_cmm;
#if _ETHOSN_API_VERSION_ > 2102
std::unique_ptr<dl::Network> runtime_cmm;
#endif
std::string name;
std::vector<uint32_t> inputs;
std::vector<uint32_t> outputs;
Expand Down
32 changes: 0 additions & 32 deletions tests/python/contrib/test_ethosn/infrastructure.py
Original file line number Diff line number Diff line change
Expand Up @@ -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"""

Expand Down Expand Up @@ -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")
2 changes: 1 addition & 1 deletion tests/python/contrib/test_ethosn/test_conv2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
2 changes: 1 addition & 1 deletion tests/python/contrib/test_ethosn/test_fullyconnected.py
Original file line number Diff line number Diff line change
Expand Up @@ -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),
Expand Down
Loading