blob: 45e85258ec91c4f1a8217b8e6721243d3277d082 [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 Hoglind031f4c12021-03-25 08:32:23 +0100119 case tflite::TensorType::TensorType_FLOAT32:
120 return 4;
Kristofer Jonsson5e632c22020-11-25 10:58:38 +0100121 default:
122 throw EthosU::Exception("Unsupported tensor type");
123 }
124}
125
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200126vector<size_t> getSubGraphDims(const tflite::SubGraph *subgraph, const flatbuffers::Vector<int32_t> *tensorMap) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200127 vector<size_t> dims;
128
Jonny Svärd2c017132021-04-12 15:56:44 +0200129 if (subgraph == nullptr || tensorMap == nullptr) {
130 throw EthosU::Exception("getSubGraphDims(): nullptr arg(s)");
131 }
132
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200133 for (auto index = tensorMap->begin(); index != tensorMap->end(); ++index) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200134 auto tensor = subgraph->tensors()->Get(*index);
135 size_t size = getShapeSize(tensor->shape());
Kristofer Jonsson5e632c22020-11-25 10:58:38 +0100136 size *= getTensorTypeSize(tensor->type());
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200137
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200138 if (size > 0) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200139 dims.push_back(size);
140 }
141 }
142
143 return dims;
144}
145
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200146} // namespace
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200147
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200148namespace EthosU {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200149
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200150/****************************************************************************
151 * Exception
152 ****************************************************************************/
153
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200154Exception::Exception(const char *msg) : msg(msg) {}
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200155
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200156Exception::~Exception() throw() {}
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200157
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200158const char *Exception::what() const throw() {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200159 return msg.c_str();
160}
161
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200162/****************************************************************************
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200163 * Semantic Version
164 ****************************************************************************/
165
166bool SemanticVersion::operator==(const SemanticVersion &other) {
167 return other.major == major && other.minor == minor && other.patch == patch;
168}
169
170bool SemanticVersion::operator<(const SemanticVersion &other) {
171 if (other.major > major)
172 return true;
173 if (other.minor > minor)
174 return true;
175 return other.patch > patch;
176}
177
178bool SemanticVersion::operator<=(const SemanticVersion &other) {
179 return *this < other || *this == other;
180}
181
182bool SemanticVersion::operator!=(const SemanticVersion &other) {
183 return !(*this == other);
184}
185
186bool SemanticVersion::operator>(const SemanticVersion &other) {
187 return !(*this <= other);
188}
189
190bool SemanticVersion::operator>=(const SemanticVersion &other) {
191 return !(*this < other);
192}
193
194ostream &operator<<(ostream &out, const SemanticVersion &v) {
195 return out << "{ major=" << unsigned(v.major) << ", minor=" << unsigned(v.minor) << ", patch=" << unsigned(v.patch)
196 << " }";
197}
198
199/****************************************************************************
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200200 * Device
201 ****************************************************************************/
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200202Device::Device(const char *device) {
Per Åstrandec3f2b02021-06-09 10:43:38 +0200203 fd = eopen(device, O_RDWR | O_NONBLOCK);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200204}
205
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200206Device::~Device() {
Per Åstrandec3f2b02021-06-09 10:43:38 +0200207 eclose(fd);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200208}
209
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200210int Device::ioctl(unsigned long cmd, void *data) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200211 return eioctl(fd, cmd, data);
212}
213
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200214Capabilities Device::capabilities() {
215 ethosu_uapi_device_capabilities uapi;
216 (void)eioctl(fd, ETHOSU_IOCTL_CAPABILITIES_REQ, static_cast<void *>(&uapi));
217
218 Capabilities capabilities(
219 HardwareId(uapi.hw_id.version_status,
220 SemanticVersion(uapi.hw_id.version_major, uapi.hw_id.version_minor),
221 SemanticVersion(uapi.hw_id.product_major),
222 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 +0200223 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 +0200224 SemanticVersion(uapi.driver_major_rev, uapi.driver_minor_rev, uapi.driver_patch_rev));
225 return capabilities;
226}
227
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200228/****************************************************************************
229 * Buffer
230 ****************************************************************************/
231
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200232Buffer::Buffer(Device &device, const size_t capacity) : fd(-1), dataPtr(nullptr), dataCapacity(capacity) {
233 ethosu_uapi_buffer_create uapi = {static_cast<uint32_t>(dataCapacity)};
234 fd = device.ioctl(ETHOSU_IOCTL_BUFFER_CREATE, static_cast<void *>(&uapi));
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200235
Per Åstrandec3f2b02021-06-09 10:43:38 +0200236 void *d = emmap(nullptr, dataCapacity, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200237 dataPtr = reinterpret_cast<char *>(d);
238}
239
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200240Buffer::~Buffer() {
Per Åstrandec3f2b02021-06-09 10:43:38 +0200241 emunmap(dataPtr, dataCapacity);
242 eclose(fd);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200243}
244
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200245size_t Buffer::capacity() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200246 return dataCapacity;
247}
248
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200249void Buffer::clear() {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200250 resize(0, 0);
251}
252
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200253char *Buffer::data() {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200254 return dataPtr + offset();
255}
256
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200257void Buffer::resize(size_t size, size_t offset) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200258 ethosu_uapi_buffer uapi;
259 uapi.offset = offset;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200260 uapi.size = size;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200261 eioctl(fd, ETHOSU_IOCTL_BUFFER_SET, static_cast<void *>(&uapi));
262}
263
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200264size_t Buffer::offset() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200265 ethosu_uapi_buffer uapi;
266 eioctl(fd, ETHOSU_IOCTL_BUFFER_GET, static_cast<void *>(&uapi));
267 return uapi.offset;
268}
269
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200270size_t Buffer::size() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200271 ethosu_uapi_buffer uapi;
272 eioctl(fd, ETHOSU_IOCTL_BUFFER_GET, static_cast<void *>(&uapi));
273 return uapi.size;
274}
275
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200276int Buffer::getFd() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200277 return fd;
278}
279
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200280/****************************************************************************
281 * Network
282 ****************************************************************************/
283
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200284Network::Network(Device &device, shared_ptr<Buffer> &buffer) : fd(-1), buffer(buffer) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200285 // Create buffer handle
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200286 ethosu_uapi_network_create uapi;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200287 uapi.fd = buffer->getFd();
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200288 fd = device.ioctl(ETHOSU_IOCTL_NETWORK_CREATE, static_cast<void *>(&uapi));
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200289
290 // Create model handle
291 const tflite::Model *model = tflite::GetModel(reinterpret_cast<void *>(buffer->data()));
292
Jonny Svärd2c017132021-04-12 15:56:44 +0200293 if (model->subgraphs() == nullptr) {
294 throw EthosU::Exception("Failed to get subgraphs: nullptr");
295 }
296
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200297 // Get input dimensions for first subgraph
298 auto *subgraph = *model->subgraphs()->begin();
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200299 ifmDims = getSubGraphDims(subgraph, subgraph->inputs());
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200300
301 // Get output dimensions for last subgraph
302 subgraph = *model->subgraphs()->rbegin();
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200303 ofmDims = getSubGraphDims(subgraph, subgraph->outputs());
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200304}
305
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200306Network::~Network() {
Per Åstrandec3f2b02021-06-09 10:43:38 +0200307 eclose(fd);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200308}
309
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200310int Network::ioctl(unsigned long cmd, void *data) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200311 return eioctl(fd, cmd, data);
312}
313
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200314shared_ptr<Buffer> Network::getBuffer() {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200315 return buffer;
316}
317
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200318const std::vector<size_t> &Network::getIfmDims() const {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200319 return ifmDims;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200320}
321
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200322size_t Network::getIfmSize() const {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200323 size_t size = 0;
324
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200325 for (auto s : ifmDims) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200326 size += s;
327 }
328
329 return size;
330}
331
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200332const std::vector<size_t> &Network::getOfmDims() const {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200333 return ofmDims;
334}
335
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200336size_t Network::getOfmSize() const {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200337 size_t size = 0;
338
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200339 for (auto s : ofmDims) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200340 size += s;
341 }
342
343 return size;
344}
345
346/****************************************************************************
347 * Inference
348 ****************************************************************************/
349
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200350Inference::~Inference() {
Per Åstrandec3f2b02021-06-09 10:43:38 +0200351 eclose(fd);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200352}
353
Per Åstrand2354d3e2020-10-24 20:17:10 +0200354void Inference::create(std::vector<uint32_t> &counterConfigs, bool cycleCounterEnable = false) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200355 ethosu_uapi_inference_create uapi;
356
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200357 if (ifmBuffers.size() > ETHOSU_FD_MAX) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200358 throw Exception("IFM buffer overflow");
359 }
360
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200361 if (ofmBuffers.size() > ETHOSU_FD_MAX) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200362 throw Exception("OFM buffer overflow");
363 }
364
Per Åstrand2354d3e2020-10-24 20:17:10 +0200365 if (counterConfigs.size() != ETHOSU_PMU_EVENT_MAX) {
366 throw Exception("Wrong size of counter configurations");
367 }
368
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200369 uapi.ifm_count = 0;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200370 for (auto it : ifmBuffers) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200371 uapi.ifm_fd[uapi.ifm_count++] = it->getFd();
372 }
373
374 uapi.ofm_count = 0;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200375 for (auto it : ofmBuffers) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200376 uapi.ofm_fd[uapi.ofm_count++] = it->getFd();
377 }
378
Per Åstrand2354d3e2020-10-24 20:17:10 +0200379 for (int i = 0; i < ETHOSU_PMU_EVENT_MAX; i++) {
380 uapi.pmu_config.events[i] = counterConfigs[i];
381 }
382
383 uapi.pmu_config.cycle_count = cycleCounterEnable;
384
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200385 fd = network->ioctl(ETHOSU_IOCTL_INFERENCE_CREATE, static_cast<void *>(&uapi));
386}
387
Per Åstrand2354d3e2020-10-24 20:17:10 +0200388std::vector<uint32_t> Inference::initializeCounterConfig() {
389 return std::vector<uint32_t>(ETHOSU_PMU_EVENT_MAX, 0);
390}
391
392uint32_t Inference::getMaxPmuEventCounters() {
393 return ETHOSU_PMU_EVENT_MAX;
394}
395
Davide Grohmanne446b422021-10-19 15:33:23 +0200396int Inference::wait(int64_t timeoutNanos) {
397 struct pollfd pfd;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200398 pfd.fd = fd;
399 pfd.events = POLLIN | POLLERR;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200400 pfd.revents = 0;
401
Davide Grohmanne446b422021-10-19 15:33:23 +0200402 // if timeout negative wait forever
403 if (timeoutNanos < 0) {
404 return eppoll(&pfd, 1, NULL, NULL);
405 }
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200406
Davide Grohmanne446b422021-10-19 15:33:23 +0200407 struct timespec tmo_p;
408 int64_t nanosec = 1000000000;
409 tmo_p.tv_sec = timeoutNanos / nanosec;
410 tmo_p.tv_nsec = timeoutNanos % nanosec;
Per Åstrand2354d3e2020-10-24 20:17:10 +0200411
Davide Grohmanne446b422021-10-19 15:33:23 +0200412 return eppoll(&pfd, 1, &tmo_p, NULL);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200413}
414
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200415bool Inference::failed() {
Per Åstrand2354d3e2020-10-24 20:17:10 +0200416 ethosu_uapi_result_status uapi;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200417
Per Åstrand2354d3e2020-10-24 20:17:10 +0200418 eioctl(fd, ETHOSU_IOCTL_INFERENCE_STATUS, static_cast<void *>(&uapi));
419
420 return uapi.status != ETHOSU_UAPI_STATUS_OK;
421}
422
423const std::vector<uint32_t> Inference::getPmuCounters() {
424 ethosu_uapi_result_status uapi;
425 std::vector<uint32_t> counterValues = std::vector<uint32_t>(ETHOSU_PMU_EVENT_MAX, 0);
426
427 eioctl(fd, ETHOSU_IOCTL_INFERENCE_STATUS, static_cast<void *>(&uapi));
428
429 for (int i = 0; i < ETHOSU_PMU_EVENT_MAX; i++) {
430 if (uapi.pmu_config.events[i]) {
431 counterValues.at(i) = uapi.pmu_count.events[i];
432 }
433 }
434
435 return counterValues;
436}
437
438uint64_t Inference::getCycleCounter() {
439 ethosu_uapi_result_status uapi;
440
441 eioctl(fd, ETHOSU_IOCTL_INFERENCE_STATUS, static_cast<void *>(&uapi));
442
443 return uapi.pmu_count.cycle_count;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200444}
445
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200446int Inference::getFd() {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200447 return fd;
448}
449
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200450shared_ptr<Network> Inference::getNetwork() {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200451 return network;
452}
453
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200454vector<shared_ptr<Buffer>> &Inference::getIfmBuffers() {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200455 return ifmBuffers;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200456}
457
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200458vector<shared_ptr<Buffer>> &Inference::getOfmBuffers() {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200459 return ofmBuffers;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200460}
461
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200462} // namespace EthosU