aboutsummaryrefslogtreecommitdiff
path: root/driver_library
diff options
context:
space:
mode:
Diffstat (limited to 'driver_library')
-rw-r--r--driver_library/include/ethosu.hpp10
-rw-r--r--driver_library/python/README.md14
-rw-r--r--driver_library/python/src/ethosu_driver/_utilities/driver_utilities.py3
-rw-r--r--driver_library/python/src/ethosu_driver/swig/driver.i51
-rw-r--r--driver_library/python/src/ethosu_driver/swig/typemaps/buffer.i23
-rw-r--r--driver_library/python/test/test_driver.py86
-rw-r--r--driver_library/src/ethosu.cpp15
7 files changed, 117 insertions, 85 deletions
diff --git a/driver_library/include/ethosu.hpp b/driver_library/include/ethosu.hpp
index 47c1868..eaa1ce7 100644
--- a/driver_library/include/ethosu.hpp
+++ b/driver_library/include/ethosu.hpp
@@ -39,12 +39,12 @@
namespace EthosU {
-constexpr uint32_t DRIVER_LIBRARY_VERSION_MAJOR = 2;
+constexpr uint32_t DRIVER_LIBRARY_VERSION_MAJOR = 3;
constexpr uint32_t DRIVER_LIBRARY_VERSION_MINOR = 0;
constexpr uint32_t DRIVER_LIBRARY_VERSION_PATCH = 0;
-constexpr uint32_t MAX_SUPPORTED_KERNEL_DRIVER_MAJOR_VERSION = 2;
-constexpr uint32_t MIN_SUPPORTED_KERNEL_DRIVER_MAJOR_VERSION = 2;
+constexpr uint32_t MAX_SUPPORTED_KERNEL_DRIVER_MAJOR_VERSION = 3;
+constexpr uint32_t MIN_SUPPORTED_KERNEL_DRIVER_MAJOR_VERSION = 3;
class Exception : public std::exception {
public:
@@ -168,12 +168,11 @@ private:
class Network {
public:
- Network(const Device &device, std::shared_ptr<Buffer> &buffer);
+ Network(const Device &device, const unsigned char *networkData, size_t networkSize);
Network(const Device &device, const unsigned index);
virtual ~Network() noexcept(false);
int ioctl(unsigned long cmd, void *data = nullptr);
- std::shared_ptr<Buffer> getBuffer();
const std::vector<size_t> &getIfmDims() const;
size_t getIfmSize() const;
const std::vector<size_t> &getOfmDims() const;
@@ -183,7 +182,6 @@ private:
void collectNetworkInfo();
int fd;
- std::shared_ptr<Buffer> buffer;
std::vector<size_t> ifmDims;
std::vector<size_t> ofmDims;
};
diff --git a/driver_library/python/README.md b/driver_library/python/README.md
index 7fae749..cc67ad9 100644
--- a/driver_library/python/README.md
+++ b/driver_library/python/README.md
@@ -165,8 +165,8 @@ object:
```python
# from file:
-network_file = "/path/to/model.tflite"
-network_buffer = driver.Buffer(device, network_file)
+data_file = "/path/to/data.bin"
+buffer = driver.Buffer(device, data_file)
# from numpy:
ifm_zeros = numpy.zeros(ifm_size, dtype=np.uint8)
@@ -174,11 +174,15 @@ ifm_buffer = driver.Buffer(device, ifm_size)
ifm_buffer.from_buffer(ifm_zeros.data)
```
-To create a network object, provide memory buffer for the model file and
-created device:
+To create a network object, provide the model file or a byte array with the
+network data and the created device:
```python
-network = driver.Network(device, network_buffer)
+# from file:
+network = driver.Network(device, "path/to/model.tflite")
+
+# from byte array:
+network = driver.Network(device, network_data)
```
Inference object is instantiated with a network object and lists of input
diff --git a/driver_library/python/src/ethosu_driver/_utilities/driver_utilities.py b/driver_library/python/src/ethosu_driver/_utilities/driver_utilities.py
index fcea91f..ca39751 100644
--- a/driver_library/python/src/ethosu_driver/_utilities/driver_utilities.py
+++ b/driver_library/python/src/ethosu_driver/_utilities/driver_utilities.py
@@ -30,8 +30,7 @@ def load_model(device: Device, model: str) -> Network:
`Network`: Return the object that represent the neural __network file descriptor received from the Ethos-U device.
"""
logging.info("Creating network")
- network_buffer = Buffer(device, model)
- return Network(device, network_buffer)
+ return Network(device, model)
def populate_buffers(input_data: List[bytearray], buffers: List[Buffer]):
diff --git a/driver_library/python/src/ethosu_driver/swig/driver.i b/driver_library/python/src/ethosu_driver/swig/driver.i
index 3e4e384..6e0ad25 100644
--- a/driver_library/python/src/ethosu_driver/swig/driver.i
+++ b/driver_library/python/src/ethosu_driver/swig/driver.i
@@ -293,12 +293,12 @@ public:
buffer: data to be copied to the mapped memory.
") from_buffer;
- %mutable_buffer(char* buffer, size_t size);
+ %buffer_in(char* buffer, size_t size, BUFFER_FLAG_RW);
void from_buffer(char* buffer, size_t size) {
char* data = $self->data();
std::memcpy(data, buffer, size);
}
- %clear_mutable_buffer(char* buffer, size_t size);
+ %clear_buffer_in(char* buffer, size_t size);
}
%feature("docstring",
@@ -329,15 +329,6 @@ public:
%feature("docstring",
"
- Returns associated memory buffer.
-
- Returns:
- `Buffer`: buffer object used during initialisation.
- ") getBuffer;
- std::shared_ptr<Buffer> getBuffer();
-
- %feature("docstring",
- "
Returns saved sizes of the neural network model input feature maps.
Returns:
@@ -374,21 +365,41 @@ public:
};
%extend Network {
- Network(const Device &device, std::shared_ptr<Buffer> &buffer)
+
+ Network(const Device &device, const std::string& filename)
{
- if(buffer == nullptr){
- throw EthosU::Exception(std::string("Failed to create the network, buffer is nullptr.").c_str());
+ std::ifstream stream(filename, std::ios::binary);
+ if (!stream.is_open()) {
+ throw EthosU::Exception(std::string("Failed to open file: ").append(filename).c_str());
}
- auto network = new EthosU::Network(device, buffer);
- return network;
+
+ stream.seekg(0, std::ios_base::end);
+ size_t size = stream.tellg();
+ stream.seekg(0, std::ios_base::beg);
+
+ std::unique_ptr<unsigned char[]> buffer = std::make_unique<unsigned char[]>(size);
+ stream.read(reinterpret_cast<char*>(buffer.get()), size);
+ return new EthosU::Network(device, buffer.get(), size);
}
-}
-%extend Network {
+ %buffer_in(const unsigned char* networkData, size_t networkSize, BUFFER_FLAG_RO);
+ Network(const Device &device, const unsigned char* networkData, size_t networkSize)
+ {
+ if(networkData == nullptr){
+ throw EthosU::Exception(std::string("Failed to create the network, networkData is nullptr.").c_str());
+ }
+
+ if(networkSize == 0U){
+ throw EthosU::Exception(std::string("Failed to create the network, networkSize is zero.").c_str());
+ }
+
+ return new EthosU::Network(device, networkData, networkSize);
+ }
+ %clear_buffer_in(const unsigned char* networkData, size_t networkSize);
+
Network(const Device &device, const unsigned int index)
{
- auto network = new EthosU::Network(device, index);
- return network;
+ return new EthosU::Network(device, index);
}
}
diff --git a/driver_library/python/src/ethosu_driver/swig/typemaps/buffer.i b/driver_library/python/src/ethosu_driver/swig/typemaps/buffer.i
index 13b7909..bb4627c 100644
--- a/driver_library/python/src/ethosu_driver/swig/typemaps/buffer.i
+++ b/driver_library/python/src/ethosu_driver/swig/typemaps/buffer.i
@@ -1,19 +1,25 @@
//
-// SPDX-FileCopyrightText: Copyright 2021-2022 Arm Limited and/or its affiliates <open-source-office@arm.com>
+// SPDX-FileCopyrightText: Copyright 2021-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
// SPDX-License-Identifier: Apache-2.0
//
-%define %mutable_buffer(TYPEMAP, SIZE)
+
+%define BUFFER_FLAG_RO 0 %enddef
+%define BUFFER_FLAG_RW PyBUF_WRITABLE %enddef
+
+%define %buffer_in(TYPEMAP, SIZE, FLAG)
%typemap(in) (TYPEMAP, SIZE) {
- int res; void *buf = 0; size_t size = 0;
Py_buffer view;
- res = PyObject_GetBuffer($input, &view, PyBUF_WRITABLE);
- buf = view.buf;
- size = view.len;
- PyBuffer_Release(&view);
+
+ int res = PyObject_GetBuffer($input, &view, FLAG);
if (res < 0) {
PyErr_Clear();
%argument_fail(res, "(TYPEMAP, SIZE)", $symname, $argnum);
}
+
+ void *buf = view.buf;
+ size_t size = view.len;
+ PyBuffer_Release(&view);
+
$1 = ($1_ltype) buf;
$2 = ($2_ltype) size;
}
@@ -23,12 +29,11 @@
}
%enddef
-%define %clear_mutable_buffer(TYPEMAP, SIZE)
+%define %clear_buffer_in(TYPEMAP, SIZE)
%typemap(in) (TYPEMAP, SIZE);
%typemap(typecheck) (TYPEMAP, SIZE);
%enddef
-
%define %driver_buffer_out
%typemap(out) (char*) {
auto size = arg1->size();
diff --git a/driver_library/python/test/test_driver.py b/driver_library/python/test/test_driver.py
index 0dd207f..e9cb5c8 100644
--- a/driver_library/python/test/test_driver.py
+++ b/driver_library/python/test/test_driver.py
@@ -15,11 +15,14 @@ def device(device_name):
@pytest.fixture()
-def network_buffer(device, model_name, shared_data_folder):
+def network_file(model_name, shared_data_folder):
network_file = os.path.join(shared_data_folder, model_name)
- network_buffer = driver.Buffer(device, network_file)
- yield network_buffer
+ yield network_file
+@pytest.fixture()
+def network(device, network_file):
+ network = driver.Network(device, network_file)
+ yield network
@pytest.mark.parametrize('device_name', ['ethosu0'])
def test_check_device_swig_ownership(device):
@@ -44,12 +47,33 @@ def test_device_wrong_name(device_name):
@pytest.mark.parametrize('device_name', ['ethosu0'])
-def test_driver_network_filenotfound_exception(device, shared_data_folder):
+@pytest.mark.parametrize('model_name', ['model.tflite'])
+def test_driver_network_from_bytearray(device, network_file):
+ network_data = None
+ with open(network_file, 'rb') as file:
+ network_data = file.read()
+ network = driver.Network(device, network_data)
- network_file = os.path.join(shared_data_folder, "some_unknown_model.tflite")
+@pytest.mark.parametrize('device_name', ['ethosu0'])
+def test_driver_network_from_empty_bytearray(device):
with pytest.raises(RuntimeError) as err:
- network_buffer = driver.Buffer(device, network_file)
+ network = driver.Network(device, bytearray())
+
+ assert 'Failed to create the network, networkSize is zero' in str(err.value)
+
+
+@pytest.mark.parametrize('device_name', ['ethosu0'])
+@pytest.mark.parametrize('model_name', ['model.tflite'])
+def test_driver_network_from_file(device, network_file):
+ network = driver.Network(device, network_file)
+
+
+@pytest.mark.parametrize('device_name', ['ethosu0'])
+@pytest.mark.parametrize('model_name', ['some_unknown_model.tflite'])
+def test_driver_network_filenotfound_exception(device, network_file):
+ with pytest.raises(RuntimeError) as err:
+ network = driver.Network(device, network_file)
# Only check for part of the exception since the exception returns
# absolute path which will change on different machines.
@@ -58,57 +82,51 @@ def test_driver_network_filenotfound_exception(device, shared_data_folder):
@pytest.mark.parametrize('device_name', ['ethosu0'])
@pytest.mark.parametrize('model_name', ['model.tflite'])
-def test_check_buffer_swig_ownership(network_buffer):
+def test_check_network_swig_ownership(network):
# Check to see that SWIG has ownership for parser. This instructs SWIG to take
# ownership of the return value. This allows the value to be automatically
# garbage-collected when it is no longer in use
- assert network_buffer.thisown
+ assert network.thisown
@pytest.mark.parametrize('device_name', ['ethosu0'])
@pytest.mark.parametrize('model_name', ['model.tflite'])
-def test_check_buffer_size(network_buffer):
- assert network_buffer.size() > 0
+def test_check_network_ifm_size(device, network):
+ assert network.getIfmSize() > 0
@pytest.mark.parametrize('device_name', ['ethosu0'])
@pytest.mark.parametrize('model_name', ['model.tflite'])
-def test_check_buffer_clear(network_buffer):
- network_buffer.clear()
- for i in range(network_buffer.size()):
- assert network_buffer.data()[i] == 0
+def test_check_network_ofm_size(device, network):
+ assert network.getOfmSize() > 0
@pytest.mark.parametrize('device_name', ['ethosu0'])
-@pytest.mark.parametrize('model_name', ['model.tflite'])
-def test_check_buffer_getFd(network_buffer):
- assert network_buffer.getFd() >= 0
+def test_check_buffer_swig_ownership(device):
+ buffer = driver.Buffer(device, 1024)
+ assert buffer.thisown
@pytest.mark.parametrize('device_name', ['ethosu0'])
-@pytest.mark.parametrize('model_name', ['model.tflite'])
-def test_check_network_ifm_size(device, network_buffer):
- network = driver.Network(device, network_buffer)
- assert network.getIfmSize() > 0
- assert network_buffer.thisown
-
-
-@pytest.mark.parametrize('device_name', [('ethosu0')])
-def test_check_network_buffer_none(device):
+def test_check_buffer_getFd(device):
+ buffer = driver.Buffer(device, 1024)
+ assert buffer.getFd() >= 0
- with pytest.raises(RuntimeError) as err:
- driver.Network(device, None)
- # Only check for part of the exception since the exception returns
- # absolute path which will change on different machines.
- assert 'Failed to create the network' in str(err.value)
+@pytest.mark.parametrize('device_name', ['ethosu0'])
+def test_check_buffer_size(device):
+ buffer = driver.Buffer(device, 1024)
+ assert buffer.size() == 1024
@pytest.mark.parametrize('device_name', ['ethosu0'])
@pytest.mark.parametrize('model_name', ['model.tflite'])
-def test_check_network_ofm_size(device, network_buffer):
- network = driver.Network(device, network_buffer)
- assert network.getOfmSize() > 0
+def test_check_buffer_clear(device, network_file):
+ buffer = driver.Buffer(device, network_file)
+
+ buffer.clear()
+ for i in range(buffer.size()):
+ assert buffer.data()[i] == 0
def test_getMaxPmuEventCounters():
diff --git a/driver_library/src/ethosu.cpp b/driver_library/src/ethosu.cpp
index 3c7dc31..7aec696 100644
--- a/driver_library/src/ethosu.cpp
+++ b/driver_library/src/ethosu.cpp
@@ -333,12 +333,13 @@ int Buffer::getFd() const {
* Network
****************************************************************************/
-Network::Network(const Device &device, shared_ptr<Buffer> &buffer) : fd(-1), buffer(buffer) {
+Network::Network(const Device &device, const unsigned char *networkData, size_t networkSize) : fd(-1) {
// Create buffer handle
ethosu_uapi_network_create uapi;
- uapi.type = ETHOSU_UAPI_NETWORK_BUFFER;
- uapi.fd = buffer->getFd();
- fd = device.ioctl(ETHOSU_IOCTL_NETWORK_CREATE, static_cast<void *>(&uapi));
+ uapi.type = ETHOSU_UAPI_NETWORK_USER_BUFFER;
+ uapi.network.data_ptr = reinterpret_cast<uintptr_t>(networkData);
+ uapi.network.size = networkSize;
+ fd = device.ioctl(ETHOSU_IOCTL_NETWORK_CREATE, static_cast<void *>(&uapi));
try {
collectNetworkInfo();
} catch (std::exception &e) {
@@ -348,7 +349,7 @@ Network::Network(const Device &device, shared_ptr<Buffer> &buffer) : fd(-1), buf
throw;
}
- Log(Severity::Info) << "Network(" << &device << ", " << &*buffer << "), this=" << this << ", fd=" << fd << endl;
+ Log(Severity::Info) << "Network(" << &device << "), this=" << this << ", fd=" << fd << endl;
}
Network::Network(const Device &device, const unsigned index) : fd(-1) {
@@ -391,10 +392,6 @@ int Network::ioctl(unsigned long cmd, void *data) {
return eioctl(fd, cmd, data);
}
-shared_ptr<Buffer> Network::getBuffer() {
- return buffer;
-}
-
const std::vector<size_t> &Network::getIfmDims() const {
return ifmDims;
}