blob: 32d179a20e44f950dd99f6fbfd00322b60ddc11b [file] [log] [blame]
Kristofer Jonsson116a6352020-08-20 17:25:23 +02001/*
Anton Moberg4e5e0562021-03-31 11:11:36 +02002 * Copyright (c) 2020-2021 Arm Limited. All rights reserved.
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>
26#include <iostream>
27
Kristofer Jonsson116a6352020-08-20 17:25:23 +020028#include <fcntl.h>
29#include <poll.h>
Davide Grohmanne446b422021-10-19 15:33:23 +020030#include <signal.h>
Kristofer Jonsson79689c52020-10-16 14:42:19 +020031#include <sys/ioctl.h>
32#include <sys/mman.h>
Kristofer Jonsson116a6352020-08-20 17:25:23 +020033#include <unistd.h>
34
35using namespace std;
36
Per Åstrandec3f2b02021-06-09 10:43:38 +020037namespace EthosU {
38__attribute__((weak)) int eioctl(int fd, unsigned long cmd, void *data = nullptr) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +020039 int ret = ::ioctl(fd, cmd, data);
Kristofer Jonsson79689c52020-10-16 14:42:19 +020040 if (ret < 0) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +020041 throw EthosU::Exception("IOCTL failed");
42 }
43
44 return ret;
45}
Kristofer Jonssonb74492c2020-09-10 13:26:01 +020046
Per Åstrandec3f2b02021-06-09 10:43:38 +020047__attribute__((weak)) int eopen(const char *pathname, int flags) {
48 int fd = ::open(pathname, flags);
Per Åstrandec3f2b02021-06-09 10:43:38 +020049 if (fd < 0) {
50 throw Exception("Failed to open device");
51 }
52
53 return fd;
54}
55
Davide Grohmanne446b422021-10-19 15:33:23 +020056__attribute__((weak)) int
57eppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmo_p, const sigset_t *sigmask) {
58 int result = ::ppoll(fds, nfds, tmo_p, sigmask);
Davide Grohmannc90bfab2021-10-19 13:59:27 +020059 if (result < 0) {
Davide Grohmanne446b422021-10-19 15:33:23 +020060 throw Exception("Failed to wait for ppoll event or signal");
Davide Grohmannc90bfab2021-10-19 13:59:27 +020061 }
62
63 return result;
Per Åstrandec3f2b02021-06-09 10:43:38 +020064}
65
66__attribute__((weak)) int eclose(int fd) {
Davide Grohmannc90bfab2021-10-19 13:59:27 +020067 int result = ::close(fd);
68 if (result < 0) {
69 throw Exception("Failed to close file");
70 }
71
72 return result;
Per Åstrandec3f2b02021-06-09 10:43:38 +020073}
74__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 +020075 void *ptr = ::mmap(addr, length, prot, flags, fd, offset);
76 if (ptr == MAP_FAILED) {
77 throw Exception("Failed to mmap file");
78 }
79
80 return ptr;
Per Åstrandec3f2b02021-06-09 10:43:38 +020081}
82
83__attribute__((weak)) int emunmap(void *addr, size_t length) {
Davide Grohmannc90bfab2021-10-19 13:59:27 +020084 int result = ::munmap(addr, length);
85 if (result < 0) {
86 throw Exception("Failed to munmap file");
87 }
88
89 return result;
Per Åstrandec3f2b02021-06-09 10:43:38 +020090}
91
92} // namespace EthosU
93
Kristofer Jonssonb74492c2020-09-10 13:26:01 +020094/****************************************************************************
95 * TFL micro helpers
96 ****************************************************************************/
Per Åstrandec3f2b02021-06-09 10:43:38 +020097namespace {
Kristofer Jonsson79689c52020-10-16 14:42:19 +020098size_t getShapeSize(const flatbuffers::Vector<int32_t> *shape) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +020099 size_t size = 1;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200100
Jonny Svärd2c017132021-04-12 15:56:44 +0200101 if (shape == nullptr) {
102 throw EthosU::Exception("getShapeSize(): nullptr arg");
103 }
104
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200105 for (auto it = shape->begin(); it != shape->end(); ++it) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200106 size *= *it;
107 }
108
109 return size;
110}
111
Kristofer Jonsson5e632c22020-11-25 10:58:38 +0100112size_t getTensorTypeSize(const enum tflite::TensorType type) {
113 switch (type) {
114 case tflite::TensorType::TensorType_UINT8:
115 case tflite::TensorType::TensorType_INT8:
116 return 1;
117 case tflite::TensorType::TensorType_INT16:
118 return 2;
Henrik Hoglind3db0ffa2021-11-23 11:55:48 +0100119 case tflite::TensorType::TensorType_INT32:
Henrik Hoglind031f4c12021-03-25 08:32:23 +0100120 case tflite::TensorType::TensorType_FLOAT32:
121 return 4;
Kristofer Jonsson5e632c22020-11-25 10:58:38 +0100122 default:
123 throw EthosU::Exception("Unsupported tensor type");
124 }
125}
126
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200127vector<size_t> getSubGraphDims(const tflite::SubGraph *subgraph, const flatbuffers::Vector<int32_t> *tensorMap) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200128 vector<size_t> dims;
129
Jonny Svärd2c017132021-04-12 15:56:44 +0200130 if (subgraph == nullptr || tensorMap == nullptr) {
131 throw EthosU::Exception("getSubGraphDims(): nullptr arg(s)");
132 }
133
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200134 for (auto index = tensorMap->begin(); index != tensorMap->end(); ++index) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200135 auto tensor = subgraph->tensors()->Get(*index);
136 size_t size = getShapeSize(tensor->shape());
Kristofer Jonsson5e632c22020-11-25 10:58:38 +0100137 size *= getTensorTypeSize(tensor->type());
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200138
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200139 if (size > 0) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200140 dims.push_back(size);
141 }
142 }
143
144 return dims;
145}
146
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200147} // namespace
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200148
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200149namespace EthosU {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200150
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200151/****************************************************************************
152 * Exception
153 ****************************************************************************/
154
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200155Exception::Exception(const char *msg) : msg(msg) {}
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200156
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200157Exception::~Exception() throw() {}
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200158
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200159const char *Exception::what() const throw() {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200160 return msg.c_str();
161}
162
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200163/****************************************************************************
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200164 * Semantic Version
165 ****************************************************************************/
166
167bool SemanticVersion::operator==(const SemanticVersion &other) {
168 return other.major == major && other.minor == minor && other.patch == patch;
169}
170
171bool SemanticVersion::operator<(const SemanticVersion &other) {
172 if (other.major > major)
173 return true;
174 if (other.minor > minor)
175 return true;
176 return other.patch > patch;
177}
178
179bool SemanticVersion::operator<=(const SemanticVersion &other) {
180 return *this < other || *this == other;
181}
182
183bool SemanticVersion::operator!=(const SemanticVersion &other) {
184 return !(*this == other);
185}
186
187bool SemanticVersion::operator>(const SemanticVersion &other) {
188 return !(*this <= other);
189}
190
191bool SemanticVersion::operator>=(const SemanticVersion &other) {
192 return !(*this < other);
193}
194
195ostream &operator<<(ostream &out, const SemanticVersion &v) {
196 return out << "{ major=" << unsigned(v.major) << ", minor=" << unsigned(v.minor) << ", patch=" << unsigned(v.patch)
197 << " }";
198}
199
200/****************************************************************************
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200201 * Device
202 ****************************************************************************/
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200203Device::Device(const char *device) {
Per Åstrandec3f2b02021-06-09 10:43:38 +0200204 fd = eopen(device, O_RDWR | O_NONBLOCK);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200205}
206
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200207Device::~Device() {
Per Åstrandec3f2b02021-06-09 10:43:38 +0200208 eclose(fd);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200209}
210
Per Åstrandafb399f2021-11-26 12:50:35 +0100211int Device::ioctl(unsigned long cmd, void *data) const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200212 return eioctl(fd, cmd, data);
213}
214
Per Åstrandafb399f2021-11-26 12:50:35 +0100215Capabilities Device::capabilities() const {
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200216 ethosu_uapi_device_capabilities uapi;
217 (void)eioctl(fd, ETHOSU_IOCTL_CAPABILITIES_REQ, static_cast<void *>(&uapi));
218
219 Capabilities capabilities(
220 HardwareId(uapi.hw_id.version_status,
221 SemanticVersion(uapi.hw_id.version_major, uapi.hw_id.version_minor),
222 SemanticVersion(uapi.hw_id.product_major),
223 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 +0200224 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 +0200225 SemanticVersion(uapi.driver_major_rev, uapi.driver_minor_rev, uapi.driver_patch_rev));
226 return capabilities;
227}
228
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200229/****************************************************************************
230 * Buffer
231 ****************************************************************************/
232
Per Åstrandafb399f2021-11-26 12:50:35 +0100233Buffer::Buffer(const Device &device, const size_t capacity) : fd(-1), dataPtr(nullptr), dataCapacity(capacity) {
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200234 ethosu_uapi_buffer_create uapi = {static_cast<uint32_t>(dataCapacity)};
235 fd = device.ioctl(ETHOSU_IOCTL_BUFFER_CREATE, static_cast<void *>(&uapi));
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200236
Davide Grohmann2ba3c1d2021-11-08 15:08:48 +0100237 void *d;
238 try {
239 d = emmap(nullptr, dataCapacity, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
240 } catch (std::exception &e) {
241 try {
242 eclose(fd);
243 } catch (...) { std::throw_with_nested(e); }
244 }
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200245 dataPtr = reinterpret_cast<char *>(d);
246}
247
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200248Buffer::~Buffer() {
Per Åstrandec3f2b02021-06-09 10:43:38 +0200249 emunmap(dataPtr, dataCapacity);
250 eclose(fd);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200251}
252
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200253size_t Buffer::capacity() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200254 return dataCapacity;
255}
256
Per Åstrandafb399f2021-11-26 12:50:35 +0100257void Buffer::clear() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200258 resize(0, 0);
259}
260
Per Åstrandafb399f2021-11-26 12:50:35 +0100261char *Buffer::data() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200262 return dataPtr + offset();
263}
264
Per Åstrandafb399f2021-11-26 12:50:35 +0100265void Buffer::resize(size_t size, size_t offset) const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200266 ethosu_uapi_buffer uapi;
267 uapi.offset = offset;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200268 uapi.size = size;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200269 eioctl(fd, ETHOSU_IOCTL_BUFFER_SET, static_cast<void *>(&uapi));
270}
271
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200272size_t Buffer::offset() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200273 ethosu_uapi_buffer uapi;
274 eioctl(fd, ETHOSU_IOCTL_BUFFER_GET, static_cast<void *>(&uapi));
275 return uapi.offset;
276}
277
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200278size_t Buffer::size() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200279 ethosu_uapi_buffer uapi;
280 eioctl(fd, ETHOSU_IOCTL_BUFFER_GET, static_cast<void *>(&uapi));
281 return uapi.size;
282}
283
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200284int Buffer::getFd() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200285 return fd;
286}
287
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200288/****************************************************************************
289 * Network
290 ****************************************************************************/
291
Per Åstrandafb399f2021-11-26 12:50:35 +0100292Network::Network(const Device &device, shared_ptr<Buffer> &buffer) : fd(-1), buffer(buffer) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200293 // Create buffer handle
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200294 ethosu_uapi_network_create uapi;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200295 uapi.fd = buffer->getFd();
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200296 fd = device.ioctl(ETHOSU_IOCTL_NETWORK_CREATE, static_cast<void *>(&uapi));
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200297
298 // Create model handle
299 const tflite::Model *model = tflite::GetModel(reinterpret_cast<void *>(buffer->data()));
300
Jonny Svärd2c017132021-04-12 15:56:44 +0200301 if (model->subgraphs() == nullptr) {
Davide Grohmann2ba3c1d2021-11-08 15:08:48 +0100302 try {
303 eclose(fd);
304 } catch (...) { std::throw_with_nested(EthosU::Exception("Failed to get subgraphs: nullptr")); }
Jonny Svärd2c017132021-04-12 15:56:44 +0200305 }
306
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200307 // Get input dimensions for first subgraph
308 auto *subgraph = *model->subgraphs()->begin();
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200309 ifmDims = getSubGraphDims(subgraph, subgraph->inputs());
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200310
311 // Get output dimensions for last subgraph
312 subgraph = *model->subgraphs()->rbegin();
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200313 ofmDims = getSubGraphDims(subgraph, subgraph->outputs());
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200314}
315
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200316Network::~Network() {
Per Åstrandec3f2b02021-06-09 10:43:38 +0200317 eclose(fd);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200318}
319
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200320int Network::ioctl(unsigned long cmd, void *data) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200321 return eioctl(fd, cmd, data);
322}
323
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200324shared_ptr<Buffer> Network::getBuffer() {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200325 return buffer;
326}
327
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200328const std::vector<size_t> &Network::getIfmDims() const {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200329 return ifmDims;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200330}
331
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200332size_t Network::getIfmSize() const {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200333 size_t size = 0;
334
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200335 for (auto s : ifmDims) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200336 size += s;
337 }
338
339 return size;
340}
341
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200342const std::vector<size_t> &Network::getOfmDims() const {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200343 return ofmDims;
344}
345
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200346size_t Network::getOfmSize() const {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200347 size_t size = 0;
348
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200349 for (auto s : ofmDims) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200350 size += s;
351 }
352
353 return size;
354}
355
356/****************************************************************************
357 * Inference
358 ****************************************************************************/
359
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200360Inference::~Inference() {
Per Åstrandec3f2b02021-06-09 10:43:38 +0200361 eclose(fd);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200362}
363
Per Åstrand2354d3e2020-10-24 20:17:10 +0200364void Inference::create(std::vector<uint32_t> &counterConfigs, bool cycleCounterEnable = false) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200365 ethosu_uapi_inference_create uapi;
366
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200367 if (ifmBuffers.size() > ETHOSU_FD_MAX) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200368 throw Exception("IFM buffer overflow");
369 }
370
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200371 if (ofmBuffers.size() > ETHOSU_FD_MAX) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200372 throw Exception("OFM buffer overflow");
373 }
374
Per Åstrand2354d3e2020-10-24 20:17:10 +0200375 if (counterConfigs.size() != ETHOSU_PMU_EVENT_MAX) {
376 throw Exception("Wrong size of counter configurations");
377 }
378
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200379 uapi.ifm_count = 0;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200380 for (auto it : ifmBuffers) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200381 uapi.ifm_fd[uapi.ifm_count++] = it->getFd();
382 }
383
384 uapi.ofm_count = 0;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200385 for (auto it : ofmBuffers) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200386 uapi.ofm_fd[uapi.ofm_count++] = it->getFd();
387 }
388
Per Åstrand2354d3e2020-10-24 20:17:10 +0200389 for (int i = 0; i < ETHOSU_PMU_EVENT_MAX; i++) {
390 uapi.pmu_config.events[i] = counterConfigs[i];
391 }
392
393 uapi.pmu_config.cycle_count = cycleCounterEnable;
394
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200395 fd = network->ioctl(ETHOSU_IOCTL_INFERENCE_CREATE, static_cast<void *>(&uapi));
396}
397
Per Åstrand2354d3e2020-10-24 20:17:10 +0200398std::vector<uint32_t> Inference::initializeCounterConfig() {
399 return std::vector<uint32_t>(ETHOSU_PMU_EVENT_MAX, 0);
400}
401
402uint32_t Inference::getMaxPmuEventCounters() {
403 return ETHOSU_PMU_EVENT_MAX;
404}
405
Per Åstrandafb399f2021-11-26 12:50:35 +0100406int Inference::wait(int64_t timeoutNanos) const {
Davide Grohmanne446b422021-10-19 15:33:23 +0200407 struct pollfd pfd;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200408 pfd.fd = fd;
409 pfd.events = POLLIN | POLLERR;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200410 pfd.revents = 0;
411
Davide Grohmanne446b422021-10-19 15:33:23 +0200412 // if timeout negative wait forever
413 if (timeoutNanos < 0) {
414 return eppoll(&pfd, 1, NULL, NULL);
415 }
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200416
Davide Grohmanne446b422021-10-19 15:33:23 +0200417 struct timespec tmo_p;
418 int64_t nanosec = 1000000000;
419 tmo_p.tv_sec = timeoutNanos / nanosec;
420 tmo_p.tv_nsec = timeoutNanos % nanosec;
Per Åstrand2354d3e2020-10-24 20:17:10 +0200421
Davide Grohmanne446b422021-10-19 15:33:23 +0200422 return eppoll(&pfd, 1, &tmo_p, NULL);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200423}
424
Per Åstrandafb399f2021-11-26 12:50:35 +0100425bool Inference::failed() const {
Per Åstrand2354d3e2020-10-24 20:17:10 +0200426 ethosu_uapi_result_status uapi;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200427
Per Åstrand2354d3e2020-10-24 20:17:10 +0200428 eioctl(fd, ETHOSU_IOCTL_INFERENCE_STATUS, static_cast<void *>(&uapi));
429
430 return uapi.status != ETHOSU_UAPI_STATUS_OK;
431}
432
Per Åstrandafb399f2021-11-26 12:50:35 +0100433const std::vector<uint32_t> Inference::getPmuCounters() const {
Per Åstrand2354d3e2020-10-24 20:17:10 +0200434 ethosu_uapi_result_status uapi;
435 std::vector<uint32_t> counterValues = std::vector<uint32_t>(ETHOSU_PMU_EVENT_MAX, 0);
436
437 eioctl(fd, ETHOSU_IOCTL_INFERENCE_STATUS, static_cast<void *>(&uapi));
438
439 for (int i = 0; i < ETHOSU_PMU_EVENT_MAX; i++) {
440 if (uapi.pmu_config.events[i]) {
441 counterValues.at(i) = uapi.pmu_count.events[i];
442 }
443 }
444
445 return counterValues;
446}
447
Per Åstrandafb399f2021-11-26 12:50:35 +0100448uint64_t Inference::getCycleCounter() const {
Per Åstrand2354d3e2020-10-24 20:17:10 +0200449 ethosu_uapi_result_status uapi;
450
451 eioctl(fd, ETHOSU_IOCTL_INFERENCE_STATUS, static_cast<void *>(&uapi));
452
453 return uapi.pmu_count.cycle_count;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200454}
455
Per Åstrandafb399f2021-11-26 12:50:35 +0100456int Inference::getFd() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200457 return fd;
458}
459
Per Åstrandafb399f2021-11-26 12:50:35 +0100460const shared_ptr<Network> Inference::getNetwork() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200461 return network;
462}
463
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200464vector<shared_ptr<Buffer>> &Inference::getIfmBuffers() {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200465 return ifmBuffers;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200466}
467
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200468vector<shared_ptr<Buffer>> &Inference::getOfmBuffers() {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200469 return ofmBuffers;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200470}
471
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200472} // namespace EthosU