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
2 changes: 1 addition & 1 deletion python/tvm/relay/op/contrib/ethosn.py
Original file line number Diff line number Diff line change
Expand Up @@ -117,7 +117,7 @@ def partition_for_ethosn(mod, params=None, **opts):
ret : annotated and partitioned module.
"""
api_version = ethosn_api_version()
supported_api_versions = ["3.2.0", "3.1.0"]
supported_api_versions = ["3.2.0"]
if all(api_version != LooseVersion(exp_ver) for exp_ver in supported_api_versions):
raise ValueError(
f"Driver stack version {api_version} is unsupported. "
Expand Down
80 changes: 1 addition & 79 deletions src/runtime/contrib/ethosn/ethosn_device.cc
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,7 @@

#include "ethosn_driver_library/Inference.hpp"
#include "ethosn_driver_library/Network.hpp"
#ifdef _ETHOSN_API_VERSION_3_2_0
#include "ethosn_driver_library/ProcMemAllocator.hpp"
#endif

namespace tvm {
namespace runtime {
Expand Down Expand Up @@ -90,7 +88,6 @@ InferenceWaitStatus WaitForInference(dl::Inference* inference, int timeout) {
return InferenceWaitStatus(InferenceWaitErrorCode::kSuccess);
}

#ifdef _ETHOSN_API_VERSION_3_2_0
void CreateBuffers(dl::ProcMemAllocator* proc_mem_alloc,
std::vector<std::shared_ptr<dl::Buffer>>* fm,
const std::vector<DLTensor*>& tensors, const std::vector<uint32_t>& tensor_sizes,
Expand Down Expand Up @@ -164,78 +161,6 @@ bool Inference(tvm::runtime::TVMArgs args, dl::ProcMemAllocator* proc_mem_alloc,

return true;
}
#else
void CreateBuffers(std::vector<std::shared_ptr<dl::Buffer>>* fm,
const std::vector<DLTensor*>& tensors, const std::vector<uint32_t>& tensor_sizes,
bool input) {
for (size_t i = 0; i < tensors.size(); i++) {
auto* data = static_cast<uint8_t*>(tensors[i]->data);
if (input) {
(*fm)[i] = std::make_shared<dl::Buffer>(data, tensor_sizes[i], dl::DataFormat::NHWC);
} else {
(*fm)[i] = std::make_shared<dl::Buffer>(tensor_sizes[i], dl::DataFormat::NHWC);
}
}
}

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) {
// Unpack parameters
size_t n_inputs = input_order.size();
size_t n_outputs = output_order.size();
std::vector<DLTensor*> inputs(n_inputs);
for (size_t i = 0; i < n_inputs; i++) {
inputs[i] = args[input_order[i]];
}
std::vector<DLTensor*> outputs(n_outputs);
size_t output_offset = n_inputs;
for (size_t i = 0; i < n_outputs; i++) {
outputs[i] = args[output_order[i] + output_offset];
}

// Set up input buffers
std::vector<std::shared_ptr<dl::Buffer>> ifm(n_inputs);
CreateBuffers(&ifm, inputs, input_sizes, true);

// Set up output buffers
std::vector<std::shared_ptr<dl::Buffer>> ofm(n_outputs);
CreateBuffers(&ofm, outputs, output_sizes, false);

// Raw pointers for the inference
dl::Buffer* ifm_raw[n_inputs];
for (size_t i = 0; i < n_inputs; i++) {
ifm_raw[i] = ifm[i].get();
}
dl::Buffer* ofm_raw[n_outputs];
for (size_t i = 0; i < n_outputs; i++) {
ofm_raw[i] = ofm[i].get();
}

// Execute the inference.
std::unique_ptr<dl::Inference> inference(
npu->ScheduleInference(ifm_raw, n_inputs, ofm_raw, n_outputs));
InferenceWaitStatus result = WaitForInference(inference.get(), 60);

if (result.GetErrorCode() != InferenceWaitErrorCode::kSuccess) {
LOG(FATAL) << "An error has occured waiting for the inference of a sub-graph on the NPU: "
<< result.GetErrorDescription();
}

for (size_t i = 0; i < n_outputs; i++) {
DLTensor* tensor = outputs[i];
dl::Buffer* source_buffer = ofm_raw[i];
uint8_t* dest_buffer = static_cast<uint8_t*>(tensor->data);
size_t size = source_buffer->GetSize();
uint8_t* source_buffer_data = source_buffer->Map();
std::copy(source_buffer_data, source_buffer_data + size, dest_buffer);
source_buffer->Unmap();
}

return true;
}
#endif
} // namespace ethosn
} // namespace runtime
} // namespace tvm
Expand Down Expand Up @@ -270,10 +195,7 @@ TVM_REGISTER_GLOBAL("relay.ethos-n.test.infra.inference_result")
});

// Allow the ethos-n support code to be tested without a device
bool Inference(tvm::runtime::TVMArgs args,
#ifdef _ETHOSN_API_VERSION_3_2_0
dl::ProcMemAllocator* /*proc_mem_alloc*/,
#endif
bool Inference(tvm::runtime::TVMArgs args, dl::ProcMemAllocator* /*proc_mem_alloc*/,
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) {
Expand Down
6 changes: 0 additions & 6 deletions src/runtime/contrib/ethosn/ethosn_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -38,15 +38,9 @@ namespace dl = ::ethosn::driver_library;

using tvm::runtime::TVMArgs;

#ifdef _ETHOSN_API_VERSION_3_2_0
bool Inference(tvm::runtime::TVMArgs args, dl::ProcMemAllocator* proc_mem_alloc, 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);
#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
} // namespace tvm
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);
}
#ifdef _ETHOSN_API_VERSION_3_2_0
if (it.proc_mem_alloc != nullptr) {
network_map_[it.name].proc_mem_alloc = std::move(it.proc_mem_alloc);
}
#endif
if (it.runtime_cmm != nullptr) {
network_map_[it.name].runtime_cmm = std::move(it.runtime_cmm);
}
Expand All @@ -72,16 +70,10 @@ 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) {
#ifdef _ETHOSN_API_VERSION_3_2_0
*rv = Inference(args, network_map_[name].proc_mem_alloc.get(),
network_map_[name].runtime_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 @@ -126,13 +118,9 @@ Module EthosnModule::LoadFromBinary(void* strm) {
#if defined ETHOSN_HW
// If hardware unavaiable use the mock inference functionality. If hardware is
// avaiable, deserialize the compiled graph.
#ifdef _ETHOSN_API_VERSION_3_2_0
compiled.proc_mem_alloc = std::make_unique<dl::ProcMemAllocator>();
compiled.runtime_cmm = std::make_unique<dl::Network>(
compiled.proc_mem_alloc->CreateNetwork(cmm.c_str(), cmm.size()));
#else
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
11 changes: 1 addition & 10 deletions src/runtime/contrib/ethosn/ethosn_runtime.h
Original file line number Diff line number Diff line change
Expand Up @@ -34,15 +34,8 @@
#include <vector>

#include "ethosn_driver_library/Network.hpp"
#include "ethosn_support_library/Support.hpp"

#if ETHOSN_SUPPORT_LIBRARY_VERSION_MAJOR == 3 && ETHOSN_SUPPORT_LIBRARY_VERSION_MINOR == 2 && \
ETHOSN_SUPPORT_LIBRARY_VERSION_PATCH == 0
#define _ETHOSN_API_VERSION_3_2_0
#endif
#ifdef _ETHOSN_API_VERSION_3_2_0
#include "ethosn_driver_library/ProcMemAllocator.hpp"
#endif
#include "ethosn_support_library/Support.hpp"

namespace tvm {
namespace runtime {
Expand All @@ -54,9 +47,7 @@ namespace dl = ::ethosn::driver_library;
struct OrderedCompiledNetwork {
std::unique_ptr<sl::CompiledNetwork> compiled_cmm;
std::unique_ptr<dl::Network> runtime_cmm;
#ifdef _ETHOSN_API_VERSION_3_2_0
std::unique_ptr<dl::ProcMemAllocator> proc_mem_alloc;
#endif
std::string name;
std::vector<uint32_t> inputs;
std::vector<uint32_t> outputs;
Expand Down
6 changes: 1 addition & 5 deletions tests/python/contrib/test_ethosn/test_conv2d.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

import tvm
from tvm import relay
from tvm.relay.op.contrib import ethosn_api_version
from tvm.testing import requires_ethosn

from . import infrastructure as tei
Expand Down Expand Up @@ -228,10 +227,7 @@ def test_conv2d_depthwise(
)
),
}
if ethosn_api_version() == "3.2.0":
input_zp = np.random.randint(0, np.iinfo(dtype).max)
else:
input_zp = np.random.randint(np.iinfo(dtype).min, np.iinfo(dtype).max)
input_zp = np.random.randint(0, np.iinfo(dtype).max)
Comment thread
lhutton1 marked this conversation as resolved.
input_sc = np.random.random() * 2
if qnn_per_channel:
kernel_sc = tvm.nd.array(
Expand Down
6 changes: 1 addition & 5 deletions tests/python/contrib/test_ethosn/test_leaky_relu.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@

import tvm
from tvm import relay
from tvm.relay.op.contrib import ethosn_api_version
from tvm.testing import requires_ethosn

from . import infrastructure as tei
Expand Down Expand Up @@ -56,10 +55,7 @@ def test_leaky_relu(dtype, shape, alpha):
iinfo = np.iinfo(dtype)
zp_min = iinfo.min
zp_max = iinfo.max
if ethosn_api_version() == "3.2.0":
input_zp = zp_min + 128
else:
input_zp = zp_min + 120
input_zp = zp_min + 128
input_sc = 0.0068132
output_zp = zp_min + 126 # values offset more than 126 can cause saturation
output_sc = 0.0078125
Expand Down