aboutsummaryrefslogtreecommitdiff
path: root/driver_library/src/ethosu.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'driver_library/src/ethosu.cpp')
-rw-r--r--driver_library/src/ethosu.cpp232
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;
+}
+
+}