diff options
author | Kristofer Jonsson <kristofer.jonsson@arm.com> | 2020-08-20 17:25:23 +0200 |
---|---|---|
committer | Kristofer Jonsson <kristofer.jonsson@arm.com> | 2020-08-27 13:58:01 +0200 |
commit | 116a635581f292cb4882ea1a086f842904f85c3c (patch) | |
tree | 96ed12cebd8dbf9f1dc7b8f116be7d528779a2bb /driver_library | |
parent | cd13a572fe223fe95cd58c5b55b659885fb7b4cd (diff) | |
download | ethos-u-linux-driver-stack-116a635581f292cb4882ea1a086f842904f85c3c.tar.gz |
Change-Id: I14b6becc908a0ac215769c32ee9c43db192ae6c8
Diffstat (limited to 'driver_library')
-rw-r--r-- | driver_library/CMakeLists.txt | 36 | ||||
-rw-r--r-- | driver_library/include/ethosu.hpp | 108 | ||||
-rw-r--r-- | driver_library/src/ethosu.cpp | 232 |
3 files changed, 376 insertions, 0 deletions
diff --git a/driver_library/CMakeLists.txt b/driver_library/CMakeLists.txt new file mode 100644 index 0000000..4d9001f --- /dev/null +++ b/driver_library/CMakeLists.txt @@ -0,0 +1,36 @@ +# +# Copyright (c) 2020 Arm Limited. All rights reserved. +# +# SPDX-License-Identifier: Apache-2.0 +# +# Licensed 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 +# +# 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. +# + +cmake_minimum_required(VERSION 3.0.2) + +# set the project name and version +project("driver_library" VERSION 1.0.0 LANGUAGES C CXX) + +# Build the driver library +add_library(ethosu STATIC "src/ethosu.cpp") + +# Add public include directory and select which files to install +target_include_directories(ethosu PUBLIC "include") +set_target_properties(ethosu PROPERTIES PUBLIC_HEADER "include/ethosu.hpp") +set_target_properties(ethosu PROPERTIES VERSION ${PROJECT_VERSION}) + +# Install library and public headers +install(TARGETS ethosu + LIBRARY DESTINATION "lib" + ARCHIVE DESTINATION "lib" + PUBLIC_HEADER DESTINATION "include")
\ No newline at end of file diff --git a/driver_library/include/ethosu.hpp b/driver_library/include/ethosu.hpp new file mode 100644 index 0000000..3c8f814 --- /dev/null +++ b/driver_library/include/ethosu.hpp @@ -0,0 +1,108 @@ +/* + * Copyright (c) 2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 + * + * 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. + */ + +#pragma once + +#include <uapi/ethosu.h> + +#include <memory> +#include <string> + +namespace EthosU +{ + +class Exception : + public std::exception +{ +public: + Exception(const char *msg); + virtual ~Exception() throw(); + virtual const char *what() const throw(); + +private: + std::string msg; +}; + +class Device +{ +public: + Device(const char *device = "/dev/ethosu0"); + virtual ~Device(); + + int ioctl(unsigned long cmd, void *data = nullptr); + +private: + int fd; +}; + +class Buffer +{ +public: + Buffer(Device &device, const size_t capacity); + virtual ~Buffer(); + + size_t capacity() const; + void clear(); + char *data(); + void resize(size_t size, size_t offset = 0); + size_t offset() const; + size_t size() const; + + int getFd() const; + +private: + int fd; + char *dataPtr; + const size_t dataCapacity; +}; + +class Network +{ +public: + Network(Device &device, std::shared_ptr<Buffer> &buffer); + virtual ~Network(); + + int ioctl(unsigned long cmd, void *data = nullptr); + std::shared_ptr<Buffer> getBuffer(); + +private: + int fd; + std::shared_ptr<Buffer> buffer; +}; + +class Inference +{ +public: + Inference(std::shared_ptr<Network> &network, std::shared_ptr<Buffer> &ifm, std::shared_ptr<Buffer> &ofm); + virtual ~Inference(); + + void wait(int timeoutSec = -1); + bool failed(); + int getFd(); + std::shared_ptr<Network> getNetwork(); + std::shared_ptr<Buffer> getIfmBuffer(); + std::shared_ptr<Buffer> getOfmBuffer(); + +private: + int fd; + std::shared_ptr<Network> network; + std::shared_ptr<Buffer> ifmBuffer; + std::shared_ptr<Buffer> ofmBuffer; +}; + +} diff --git a/driver_library/src/ethosu.cpp b/driver_library/src/ethosu.cpp new file mode 100644 index 0000000..6b2b3b1 --- /dev/null +++ b/driver_library/src/ethosu.cpp @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2020 Arm Limited. All rights reserved. + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed 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 + * + * 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. + */ + +#include <ethosu.hpp> +#include <uapi/ethosu.h> + +#include <algorithm> +#include <exception> +#include <iostream> + +#include <sys/ioctl.h> +#include <sys/mman.h> +#include <fcntl.h> +#include <poll.h> +#include <unistd.h> + +using namespace std; + +namespace +{ +int eioctl(int fd, unsigned long cmd, void *data = nullptr) +{ + int ret = ::ioctl(fd, cmd, data); + if (ret < 0) + { + throw EthosU::Exception("IOCTL failed"); + } + + return ret; +} +} + +namespace EthosU +{ + +Exception::Exception(const char *msg) : + msg(msg) +{} + +Exception::~Exception() throw() +{} + +const char *Exception::what() const throw() +{ + return msg.c_str(); +} + +Device::Device(const char *device) +{ + fd = open(device, O_RDWR | O_NONBLOCK); + if (fd < 0) + { + throw Exception("Failed to open device"); + } +} + +Device::~Device() +{ + close(fd); +} + +int Device::ioctl(unsigned long cmd, void *data) +{ + return eioctl(fd, cmd, data); +} + +Buffer::Buffer(Device &device, const size_t capacity) : + fd(-1), + dataPtr(nullptr), + dataCapacity(capacity) +{ + ethosu_uapi_buffer_create uapi = { static_cast<uint32_t>(dataCapacity) }; + fd = device.ioctl(ETHOSU_IOCTL_BUFFER_CREATE, static_cast<void *>(&uapi)); + + void *d = ::mmap(nullptr, dataCapacity, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0); + if (d == MAP_FAILED) + { + throw Exception("MMap failed"); + } + + dataPtr = reinterpret_cast<char *>(d); +} + +Buffer::~Buffer() +{ + close(fd); +} + +size_t Buffer::capacity() const +{ + return dataCapacity; +} + +void Buffer::clear() +{ + resize(0, 0); +} + +char *Buffer::data() +{ + return dataPtr + offset(); +} + +void Buffer::resize(size_t size, size_t offset) +{ + ethosu_uapi_buffer uapi; + uapi.offset = offset; + uapi.size = size; + + eioctl(fd, ETHOSU_IOCTL_BUFFER_SET, static_cast<void *>(&uapi)); +} + +size_t Buffer::offset() const +{ + ethosu_uapi_buffer uapi; + eioctl(fd, ETHOSU_IOCTL_BUFFER_GET, static_cast<void *>(&uapi)); + return uapi.offset; +} + +size_t Buffer::size() const +{ + ethosu_uapi_buffer uapi; + eioctl(fd, ETHOSU_IOCTL_BUFFER_GET, static_cast<void *>(&uapi)); + return uapi.size; +} + +int Buffer::getFd() const +{ + return fd; +} + +Network::Network(Device &device, shared_ptr<Buffer> &buffer) : + fd(-1), + buffer(buffer) +{ + ethosu_uapi_network_create uapi; + + uapi.fd = buffer->getFd(); + + fd = device.ioctl(ETHOSU_IOCTL_NETWORK_CREATE, static_cast<void *>(&uapi)); +} + +Network::~Network() +{ + close(fd); +} + +int Network::ioctl(unsigned long cmd, void *data) +{ + return eioctl(fd, cmd, data); +} + +std::shared_ptr<Buffer> Network::getBuffer() +{ + return buffer; +} + +Inference::Inference(std::shared_ptr<Network> &network, std::shared_ptr<Buffer> &ifmBuffer, std::shared_ptr<Buffer> &ofmBuffer) : + fd(-1), + network(network), + ifmBuffer(ifmBuffer), + ofmBuffer(ofmBuffer) +{ + ethosu_uapi_inference_create uapi; + + uapi.ifm_fd = ifmBuffer->getFd(); + uapi.ofm_fd = ofmBuffer->getFd(); + + fd = network->ioctl(ETHOSU_IOCTL_INFERENCE_CREATE, static_cast<void *>(&uapi)); +} + +Inference::~Inference() +{ + close(fd); +} + +void Inference::wait(int timeoutSec) +{ + pollfd pfd; + + pfd.fd = fd; + pfd.events = POLLIN | POLLERR; + pfd.revents = 0; + + int ret = ::poll(&pfd, 1, timeoutSec * 1000); + + cout << "Poll. ret=" << ret << ", revents=" << pfd.revents << endl; +} + +bool Inference::failed() +{ + ethosu_uapi_status status = static_cast<ethosu_uapi_status>(eioctl(fd, ETHOSU_IOCTL_INFERENCE_STATUS)); + + return status != ETHOSU_UAPI_STATUS_OK; +} + +int Inference::getFd() +{ + return fd; +} + +std::shared_ptr<Network> Inference::getNetwork() +{ + return network; +} + +std::shared_ptr<Buffer> Inference::getIfmBuffer() +{ + return ifmBuffer; +} + +std::shared_ptr<Buffer> Inference::getOfmBuffer() +{ + return ofmBuffer; +} + +} |