blob: f79239943ae0d82072c5d608dc3df8f7278fcbf9 [file] [log] [blame]
Kristofer Jonsson116a6352020-08-20 17:25:23 +02001/*
Kristofer Jonsson3c6a2602022-03-10 11:17:29 +01002 * Copyright (c) 2020-2022 Arm Limited.
Kristofer Jonsson116a6352020-08-20 17:25:23 +02003 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Licensed under the Apache License, Version 2.0 (the License); you may
7 * not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 * www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
14 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
17 */
18
Kristofer Jonssonb74492c2020-09-10 13:26:01 +020019#include "autogen/tflite_schema.hpp"
20
Kristofer Jonsson116a6352020-08-20 17:25:23 +020021#include <ethosu.hpp>
22#include <uapi/ethosu.h>
23
24#include <algorithm>
25#include <exception>
Kristofer Jonsson35de9e62022-03-08 13:25:45 +010026#include <fstream>
Kristofer Jonsson116a6352020-08-20 17:25:23 +020027#include <iostream>
28
Kristofer Jonsson116a6352020-08-20 17:25:23 +020029#include <fcntl.h>
30#include <poll.h>
Davide Grohmanne446b422021-10-19 15:33:23 +020031#include <signal.h>
Kristofer Jonsson79689c52020-10-16 14:42:19 +020032#include <sys/ioctl.h>
33#include <sys/mman.h>
Kristofer Jonsson116a6352020-08-20 17:25:23 +020034#include <unistd.h>
35
36using namespace std;
37
Per Åstrandec3f2b02021-06-09 10:43:38 +020038namespace EthosU {
39__attribute__((weak)) int eioctl(int fd, unsigned long cmd, void *data = nullptr) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +020040 int ret = ::ioctl(fd, cmd, data);
Kristofer Jonsson79689c52020-10-16 14:42:19 +020041 if (ret < 0) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +020042 throw EthosU::Exception("IOCTL failed");
43 }
44
45 return ret;
46}
Kristofer Jonssonb74492c2020-09-10 13:26:01 +020047
Per Åstrandec3f2b02021-06-09 10:43:38 +020048__attribute__((weak)) int eopen(const char *pathname, int flags) {
49 int fd = ::open(pathname, flags);
Per Åstrandec3f2b02021-06-09 10:43:38 +020050 if (fd < 0) {
51 throw Exception("Failed to open device");
52 }
53
54 return fd;
55}
56
Davide Grohmanne446b422021-10-19 15:33:23 +020057__attribute__((weak)) int
58eppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmo_p, const sigset_t *sigmask) {
59 int result = ::ppoll(fds, nfds, tmo_p, sigmask);
Davide Grohmannc90bfab2021-10-19 13:59:27 +020060 if (result < 0) {
Davide Grohmanne446b422021-10-19 15:33:23 +020061 throw Exception("Failed to wait for ppoll event or signal");
Davide Grohmannc90bfab2021-10-19 13:59:27 +020062 }
63
64 return result;
Per Åstrandec3f2b02021-06-09 10:43:38 +020065}
66
67__attribute__((weak)) int eclose(int fd) {
Davide Grohmannc90bfab2021-10-19 13:59:27 +020068 int result = ::close(fd);
69 if (result < 0) {
70 throw Exception("Failed to close file");
71 }
72
73 return result;
Per Åstrandec3f2b02021-06-09 10:43:38 +020074}
75__attribute((weak)) void *emmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset) {
Davide Grohmannc90bfab2021-10-19 13:59:27 +020076 void *ptr = ::mmap(addr, length, prot, flags, fd, offset);
77 if (ptr == MAP_FAILED) {
78 throw Exception("Failed to mmap file");
79 }
80
81 return ptr;
Per Åstrandec3f2b02021-06-09 10:43:38 +020082}
83
84__attribute__((weak)) int emunmap(void *addr, size_t length) {
Davide Grohmannc90bfab2021-10-19 13:59:27 +020085 int result = ::munmap(addr, length);
86 if (result < 0) {
87 throw Exception("Failed to munmap file");
88 }
89
90 return result;
Per Åstrandec3f2b02021-06-09 10:43:38 +020091}
92
93} // namespace EthosU
94
Kristofer Jonssonb74492c2020-09-10 13:26:01 +020095/****************************************************************************
96 * TFL micro helpers
97 ****************************************************************************/
Per Åstrandec3f2b02021-06-09 10:43:38 +020098namespace {
Kristofer Jonsson79689c52020-10-16 14:42:19 +020099size_t getShapeSize(const flatbuffers::Vector<int32_t> *shape) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200100 size_t size = 1;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200101
Jonny Svärd2c017132021-04-12 15:56:44 +0200102 if (shape == nullptr) {
103 throw EthosU::Exception("getShapeSize(): nullptr arg");
104 }
105
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200106 for (auto it = shape->begin(); it != shape->end(); ++it) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200107 size *= *it;
108 }
109
110 return size;
111}
112
Kristofer Jonsson5e632c22020-11-25 10:58:38 +0100113size_t getTensorTypeSize(const enum tflite::TensorType type) {
114 switch (type) {
115 case tflite::TensorType::TensorType_UINT8:
116 case tflite::TensorType::TensorType_INT8:
117 return 1;
118 case tflite::TensorType::TensorType_INT16:
119 return 2;
Henrik Hoglind3db0ffa2021-11-23 11:55:48 +0100120 case tflite::TensorType::TensorType_INT32:
Henrik Hoglind031f4c12021-03-25 08:32:23 +0100121 case tflite::TensorType::TensorType_FLOAT32:
122 return 4;
Kristofer Jonsson5e632c22020-11-25 10:58:38 +0100123 default:
124 throw EthosU::Exception("Unsupported tensor type");
125 }
126}
127
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200128vector<size_t> getSubGraphDims(const tflite::SubGraph *subgraph, const flatbuffers::Vector<int32_t> *tensorMap) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200129 vector<size_t> dims;
130
Jonny Svärd2c017132021-04-12 15:56:44 +0200131 if (subgraph == nullptr || tensorMap == nullptr) {
132 throw EthosU::Exception("getSubGraphDims(): nullptr arg(s)");
133 }
134
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200135 for (auto index = tensorMap->begin(); index != tensorMap->end(); ++index) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200136 auto tensor = subgraph->tensors()->Get(*index);
137 size_t size = getShapeSize(tensor->shape());
Kristofer Jonsson5e632c22020-11-25 10:58:38 +0100138 size *= getTensorTypeSize(tensor->type());
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200139
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200140 if (size > 0) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200141 dims.push_back(size);
142 }
143 }
144
145 return dims;
146}
147
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200148} // namespace
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200149
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200150namespace EthosU {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200151
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200152/****************************************************************************
153 * Exception
154 ****************************************************************************/
155
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200156Exception::Exception(const char *msg) : msg(msg) {}
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200157
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200158Exception::~Exception() throw() {}
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200159
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200160const char *Exception::what() const throw() {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200161 return msg.c_str();
162}
163
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200164/****************************************************************************
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200165 * Semantic Version
166 ****************************************************************************/
167
168bool SemanticVersion::operator==(const SemanticVersion &other) {
169 return other.major == major && other.minor == minor && other.patch == patch;
170}
171
172bool SemanticVersion::operator<(const SemanticVersion &other) {
173 if (other.major > major)
174 return true;
175 if (other.minor > minor)
176 return true;
177 return other.patch > patch;
178}
179
180bool SemanticVersion::operator<=(const SemanticVersion &other) {
181 return *this < other || *this == other;
182}
183
184bool SemanticVersion::operator!=(const SemanticVersion &other) {
185 return !(*this == other);
186}
187
188bool SemanticVersion::operator>(const SemanticVersion &other) {
189 return !(*this <= other);
190}
191
192bool SemanticVersion::operator>=(const SemanticVersion &other) {
193 return !(*this < other);
194}
195
196ostream &operator<<(ostream &out, const SemanticVersion &v) {
197 return out << "{ major=" << unsigned(v.major) << ", minor=" << unsigned(v.minor) << ", patch=" << unsigned(v.patch)
198 << " }";
199}
200
201/****************************************************************************
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200202 * Device
203 ****************************************************************************/
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200204Device::Device(const char *device) {
Per Åstrandec3f2b02021-06-09 10:43:38 +0200205 fd = eopen(device, O_RDWR | O_NONBLOCK);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200206}
207
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200208Device::~Device() {
Per Åstrandec3f2b02021-06-09 10:43:38 +0200209 eclose(fd);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200210}
211
Per Åstrandafb399f2021-11-26 12:50:35 +0100212int Device::ioctl(unsigned long cmd, void *data) const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200213 return eioctl(fd, cmd, data);
214}
215
Per Åstrandafb399f2021-11-26 12:50:35 +0100216Capabilities Device::capabilities() const {
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200217 ethosu_uapi_device_capabilities uapi;
218 (void)eioctl(fd, ETHOSU_IOCTL_CAPABILITIES_REQ, static_cast<void *>(&uapi));
219
220 Capabilities capabilities(
221 HardwareId(uapi.hw_id.version_status,
222 SemanticVersion(uapi.hw_id.version_major, uapi.hw_id.version_minor),
223 SemanticVersion(uapi.hw_id.product_major),
224 SemanticVersion(uapi.hw_id.arch_major_rev, uapi.hw_id.arch_minor_rev, uapi.hw_id.arch_patch_rev)),
Davide Grohmann40e23d12021-06-17 09:59:40 +0200225 HardwareConfiguration(uapi.hw_cfg.macs_per_cc, uapi.hw_cfg.cmd_stream_version, bool(uapi.hw_cfg.custom_dma)),
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200226 SemanticVersion(uapi.driver_major_rev, uapi.driver_minor_rev, uapi.driver_patch_rev));
227 return capabilities;
228}
229
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200230/****************************************************************************
231 * Buffer
232 ****************************************************************************/
233
Per Åstrandafb399f2021-11-26 12:50:35 +0100234Buffer::Buffer(const Device &device, const size_t capacity) : fd(-1), dataPtr(nullptr), dataCapacity(capacity) {
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200235 ethosu_uapi_buffer_create uapi = {static_cast<uint32_t>(dataCapacity)};
236 fd = device.ioctl(ETHOSU_IOCTL_BUFFER_CREATE, static_cast<void *>(&uapi));
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200237
Davide Grohmann2ba3c1d2021-11-08 15:08:48 +0100238 void *d;
239 try {
240 d = emmap(nullptr, dataCapacity, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
241 } catch (std::exception &e) {
242 try {
243 eclose(fd);
244 } catch (...) { std::throw_with_nested(e); }
245 }
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200246 dataPtr = reinterpret_cast<char *>(d);
247}
248
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200249Buffer::~Buffer() {
Per Åstrandec3f2b02021-06-09 10:43:38 +0200250 emunmap(dataPtr, dataCapacity);
251 eclose(fd);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200252}
253
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200254size_t Buffer::capacity() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200255 return dataCapacity;
256}
257
Per Åstrandafb399f2021-11-26 12:50:35 +0100258void Buffer::clear() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200259 resize(0, 0);
260}
261
Per Åstrandafb399f2021-11-26 12:50:35 +0100262char *Buffer::data() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200263 return dataPtr + offset();
264}
265
Per Åstrandafb399f2021-11-26 12:50:35 +0100266void Buffer::resize(size_t size, size_t offset) const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200267 ethosu_uapi_buffer uapi;
268 uapi.offset = offset;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200269 uapi.size = size;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200270 eioctl(fd, ETHOSU_IOCTL_BUFFER_SET, static_cast<void *>(&uapi));
271}
272
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200273size_t Buffer::offset() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200274 ethosu_uapi_buffer uapi;
275 eioctl(fd, ETHOSU_IOCTL_BUFFER_GET, static_cast<void *>(&uapi));
276 return uapi.offset;
277}
278
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200279size_t Buffer::size() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200280 ethosu_uapi_buffer uapi;
281 eioctl(fd, ETHOSU_IOCTL_BUFFER_GET, static_cast<void *>(&uapi));
282 return uapi.size;
283}
284
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200285int Buffer::getFd() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200286 return fd;
287}
288
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200289/****************************************************************************
290 * Network
291 ****************************************************************************/
292
Per Åstrandafb399f2021-11-26 12:50:35 +0100293Network::Network(const Device &device, shared_ptr<Buffer> &buffer) : fd(-1), buffer(buffer) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200294 // Create buffer handle
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200295 ethosu_uapi_network_create uapi;
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100296 uapi.type = ETHOSU_UAPI_NETWORK_BUFFER;
297 uapi.fd = buffer->getFd();
298 fd = device.ioctl(ETHOSU_IOCTL_NETWORK_CREATE, static_cast<void *>(&uapi));
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200299
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100300 try {
301 parseModel(buffer->data());
302 } catch (...) {
303 eclose(fd);
304 throw;
Jonny Svärd2c017132021-04-12 15:56:44 +0200305 }
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100306}
Jonny Svärd2c017132021-04-12 15:56:44 +0200307
Kristofer Jonsson3c6a2602022-03-10 11:17:29 +0100308Network::Network(const Device &device, const unsigned index) : fd(-1) {
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100309 // Create buffer handle
310 ethosu_uapi_network_create uapi;
311 uapi.type = ETHOSU_UAPI_NETWORK_INDEX;
312 uapi.index = index;
313 fd = device.ioctl(ETHOSU_IOCTL_NETWORK_CREATE, static_cast<void *>(&uapi));
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200314
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100315 try {
Kristofer Jonsson3c6a2602022-03-10 11:17:29 +0100316 ethosu_uapi_network_info info;
317 ioctl(ETHOSU_IOCTL_NETWORK_INFO, static_cast<void *>(&info));
318
319 for (uint32_t i = 0; i < info.ifm_count; i++) {
320 ifmDims.push_back(info.ifm_size[i]);
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100321 }
322
Kristofer Jonsson3c6a2602022-03-10 11:17:29 +0100323 for (uint32_t i = 0; i < info.ofm_count; i++) {
324 ofmDims.push_back(info.ofm_size[i]);
325 }
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100326 } catch (...) {
327 eclose(fd);
328 throw;
329 }
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200330}
331
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200332Network::~Network() {
Per Åstrandec3f2b02021-06-09 10:43:38 +0200333 eclose(fd);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200334}
335
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200336int Network::ioctl(unsigned long cmd, void *data) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200337 return eioctl(fd, cmd, data);
338}
339
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200340shared_ptr<Buffer> Network::getBuffer() {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200341 return buffer;
342}
343
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200344const std::vector<size_t> &Network::getIfmDims() const {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200345 return ifmDims;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200346}
347
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200348size_t Network::getIfmSize() const {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200349 size_t size = 0;
350
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200351 for (auto s : ifmDims) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200352 size += s;
353 }
354
355 return size;
356}
357
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200358const std::vector<size_t> &Network::getOfmDims() const {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200359 return ofmDims;
360}
361
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200362size_t Network::getOfmSize() const {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200363 size_t size = 0;
364
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200365 for (auto s : ofmDims) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200366 size += s;
367 }
368
369 return size;
370}
371
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100372void Network::parseModel(const char *data) {
373 // Create model handle
374 const tflite::Model *model = tflite::GetModel(reinterpret_cast<const void *>(data));
375
376 if (model->subgraphs() == nullptr) {
377 EthosU::Exception("Failed to get subgraphs: nullptr");
378 }
379
380 // Get input dimensions for first subgraph
381 auto *subgraph = *model->subgraphs()->begin();
382 ifmDims = getSubGraphDims(subgraph, subgraph->inputs());
383
384 // Get output dimensions for last subgraph
385 subgraph = *model->subgraphs()->rbegin();
386 ofmDims = getSubGraphDims(subgraph, subgraph->outputs());
387}
388
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200389/****************************************************************************
390 * Inference
391 ****************************************************************************/
392
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200393Inference::~Inference() {
Per Åstrandec3f2b02021-06-09 10:43:38 +0200394 eclose(fd);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200395}
396
Per Åstrand2354d3e2020-10-24 20:17:10 +0200397void Inference::create(std::vector<uint32_t> &counterConfigs, bool cycleCounterEnable = false) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200398 ethosu_uapi_inference_create uapi;
399
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200400 if (ifmBuffers.size() > ETHOSU_FD_MAX) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200401 throw Exception("IFM buffer overflow");
402 }
403
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200404 if (ofmBuffers.size() > ETHOSU_FD_MAX) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200405 throw Exception("OFM buffer overflow");
406 }
407
Per Åstrand2354d3e2020-10-24 20:17:10 +0200408 if (counterConfigs.size() != ETHOSU_PMU_EVENT_MAX) {
409 throw Exception("Wrong size of counter configurations");
410 }
411
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200412 uapi.ifm_count = 0;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200413 for (auto it : ifmBuffers) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200414 uapi.ifm_fd[uapi.ifm_count++] = it->getFd();
415 }
416
417 uapi.ofm_count = 0;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200418 for (auto it : ofmBuffers) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200419 uapi.ofm_fd[uapi.ofm_count++] = it->getFd();
420 }
421
Per Åstrand2354d3e2020-10-24 20:17:10 +0200422 for (int i = 0; i < ETHOSU_PMU_EVENT_MAX; i++) {
423 uapi.pmu_config.events[i] = counterConfigs[i];
424 }
425
426 uapi.pmu_config.cycle_count = cycleCounterEnable;
427
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200428 fd = network->ioctl(ETHOSU_IOCTL_INFERENCE_CREATE, static_cast<void *>(&uapi));
429}
430
Per Åstrand2354d3e2020-10-24 20:17:10 +0200431std::vector<uint32_t> Inference::initializeCounterConfig() {
432 return std::vector<uint32_t>(ETHOSU_PMU_EVENT_MAX, 0);
433}
434
435uint32_t Inference::getMaxPmuEventCounters() {
436 return ETHOSU_PMU_EVENT_MAX;
437}
438
Per Åstrandafb399f2021-11-26 12:50:35 +0100439int Inference::wait(int64_t timeoutNanos) const {
Davide Grohmanne446b422021-10-19 15:33:23 +0200440 struct pollfd pfd;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200441 pfd.fd = fd;
442 pfd.events = POLLIN | POLLERR;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200443 pfd.revents = 0;
444
Davide Grohmanne446b422021-10-19 15:33:23 +0200445 // if timeout negative wait forever
446 if (timeoutNanos < 0) {
447 return eppoll(&pfd, 1, NULL, NULL);
448 }
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200449
Davide Grohmanne446b422021-10-19 15:33:23 +0200450 struct timespec tmo_p;
451 int64_t nanosec = 1000000000;
452 tmo_p.tv_sec = timeoutNanos / nanosec;
453 tmo_p.tv_nsec = timeoutNanos % nanosec;
Per Åstrand2354d3e2020-10-24 20:17:10 +0200454
Davide Grohmanne446b422021-10-19 15:33:23 +0200455 return eppoll(&pfd, 1, &tmo_p, NULL);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200456}
457
Per Åstrandafb399f2021-11-26 12:50:35 +0100458bool Inference::failed() const {
Per Åstrand2354d3e2020-10-24 20:17:10 +0200459 ethosu_uapi_result_status uapi;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200460
Per Åstrand2354d3e2020-10-24 20:17:10 +0200461 eioctl(fd, ETHOSU_IOCTL_INFERENCE_STATUS, static_cast<void *>(&uapi));
462
463 return uapi.status != ETHOSU_UAPI_STATUS_OK;
464}
465
Per Åstrandafb399f2021-11-26 12:50:35 +0100466const std::vector<uint32_t> Inference::getPmuCounters() const {
Per Åstrand2354d3e2020-10-24 20:17:10 +0200467 ethosu_uapi_result_status uapi;
468 std::vector<uint32_t> counterValues = std::vector<uint32_t>(ETHOSU_PMU_EVENT_MAX, 0);
469
470 eioctl(fd, ETHOSU_IOCTL_INFERENCE_STATUS, static_cast<void *>(&uapi));
471
472 for (int i = 0; i < ETHOSU_PMU_EVENT_MAX; i++) {
473 if (uapi.pmu_config.events[i]) {
474 counterValues.at(i) = uapi.pmu_count.events[i];
475 }
476 }
477
478 return counterValues;
479}
480
Per Åstrandafb399f2021-11-26 12:50:35 +0100481uint64_t Inference::getCycleCounter() const {
Per Åstrand2354d3e2020-10-24 20:17:10 +0200482 ethosu_uapi_result_status uapi;
483
484 eioctl(fd, ETHOSU_IOCTL_INFERENCE_STATUS, static_cast<void *>(&uapi));
485
486 return uapi.pmu_count.cycle_count;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200487}
488
Per Åstrandafb399f2021-11-26 12:50:35 +0100489int Inference::getFd() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200490 return fd;
491}
492
Per Åstrandafb399f2021-11-26 12:50:35 +0100493const shared_ptr<Network> Inference::getNetwork() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200494 return network;
495}
496
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200497vector<shared_ptr<Buffer>> &Inference::getIfmBuffers() {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200498 return ifmBuffers;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200499}
500
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200501vector<shared_ptr<Buffer>> &Inference::getOfmBuffers() {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200502 return ofmBuffers;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200503}
504
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200505} // namespace EthosU