diff options
Diffstat (limited to 'driver_library/src/ethosu.cpp')
-rw-r--r-- | driver_library/src/ethosu.cpp | 232 |
1 files changed, 232 insertions, 0 deletions
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; +} + +} |