blob: 01631b35e12d1a25f0d11f23af202c99aca5fd05 [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
19#include <ethosu.hpp>
20#include <uapi/ethosu.h>
21
22#include <algorithm>
23#include <exception>
Kristofer Jonsson35de9e62022-03-08 13:25:45 +010024#include <fstream>
Kristofer Jonsson116a6352020-08-20 17:25:23 +020025#include <iostream>
26
Kristofer Jonsson116a6352020-08-20 17:25:23 +020027#include <fcntl.h>
28#include <poll.h>
Davide Grohmanne446b422021-10-19 15:33:23 +020029#include <signal.h>
Kristofer Jonsson79689c52020-10-16 14:42:19 +020030#include <sys/ioctl.h>
31#include <sys/mman.h>
Kristofer Jonsson116a6352020-08-20 17:25:23 +020032#include <unistd.h>
33
34using namespace std;
35
Per Åstrandec3f2b02021-06-09 10:43:38 +020036namespace EthosU {
37__attribute__((weak)) int eioctl(int fd, unsigned long cmd, void *data = nullptr) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +020038 int ret = ::ioctl(fd, cmd, data);
Kristofer Jonsson79689c52020-10-16 14:42:19 +020039 if (ret < 0) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +020040 throw EthosU::Exception("IOCTL failed");
41 }
42
43 return ret;
44}
Kristofer Jonssonb74492c2020-09-10 13:26:01 +020045
Per Åstrandec3f2b02021-06-09 10:43:38 +020046__attribute__((weak)) int eopen(const char *pathname, int flags) {
47 int fd = ::open(pathname, flags);
Per Åstrandec3f2b02021-06-09 10:43:38 +020048 if (fd < 0) {
49 throw Exception("Failed to open device");
50 }
51
52 return fd;
53}
54
Davide Grohmanne446b422021-10-19 15:33:23 +020055__attribute__((weak)) int
56eppoll(struct pollfd *fds, nfds_t nfds, const struct timespec *tmo_p, const sigset_t *sigmask) {
57 int result = ::ppoll(fds, nfds, tmo_p, sigmask);
Davide Grohmannc90bfab2021-10-19 13:59:27 +020058 if (result < 0) {
Davide Grohmanne446b422021-10-19 15:33:23 +020059 throw Exception("Failed to wait for ppoll event or signal");
Davide Grohmannc90bfab2021-10-19 13:59:27 +020060 }
61
62 return result;
Per Åstrandec3f2b02021-06-09 10:43:38 +020063}
64
65__attribute__((weak)) int eclose(int fd) {
Davide Grohmannc90bfab2021-10-19 13:59:27 +020066 int result = ::close(fd);
67 if (result < 0) {
68 throw Exception("Failed to close file");
69 }
70
71 return result;
Per Åstrandec3f2b02021-06-09 10:43:38 +020072}
73__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 +020074 void *ptr = ::mmap(addr, length, prot, flags, fd, offset);
75 if (ptr == MAP_FAILED) {
76 throw Exception("Failed to mmap file");
77 }
78
79 return ptr;
Per Åstrandec3f2b02021-06-09 10:43:38 +020080}
81
82__attribute__((weak)) int emunmap(void *addr, size_t length) {
Davide Grohmannc90bfab2021-10-19 13:59:27 +020083 int result = ::munmap(addr, length);
84 if (result < 0) {
85 throw Exception("Failed to munmap file");
86 }
87
88 return result;
Per Åstrandec3f2b02021-06-09 10:43:38 +020089}
90
91} // namespace EthosU
92
Kristofer Jonsson79689c52020-10-16 14:42:19 +020093namespace EthosU {
Kristofer Jonsson116a6352020-08-20 17:25:23 +020094
Kristofer Jonssonb74492c2020-09-10 13:26:01 +020095/****************************************************************************
96 * Exception
97 ****************************************************************************/
98
Kristofer Jonsson79689c52020-10-16 14:42:19 +020099Exception::Exception(const char *msg) : msg(msg) {}
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200100
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200101Exception::~Exception() throw() {}
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200102
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200103const char *Exception::what() const throw() {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200104 return msg.c_str();
105}
106
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200107/****************************************************************************
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200108 * Semantic Version
109 ****************************************************************************/
110
111bool SemanticVersion::operator==(const SemanticVersion &other) {
112 return other.major == major && other.minor == minor && other.patch == patch;
113}
114
115bool SemanticVersion::operator<(const SemanticVersion &other) {
116 if (other.major > major)
117 return true;
118 if (other.minor > minor)
119 return true;
120 return other.patch > patch;
121}
122
123bool SemanticVersion::operator<=(const SemanticVersion &other) {
124 return *this < other || *this == other;
125}
126
127bool SemanticVersion::operator!=(const SemanticVersion &other) {
128 return !(*this == other);
129}
130
131bool SemanticVersion::operator>(const SemanticVersion &other) {
132 return !(*this <= other);
133}
134
135bool SemanticVersion::operator>=(const SemanticVersion &other) {
136 return !(*this < other);
137}
138
139ostream &operator<<(ostream &out, const SemanticVersion &v) {
140 return out << "{ major=" << unsigned(v.major) << ", minor=" << unsigned(v.minor) << ", patch=" << unsigned(v.patch)
141 << " }";
142}
143
144/****************************************************************************
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200145 * Device
146 ****************************************************************************/
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200147Device::Device(const char *device) {
Per Åstrandec3f2b02021-06-09 10:43:38 +0200148 fd = eopen(device, O_RDWR | O_NONBLOCK);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200149}
150
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200151Device::~Device() {
Per Åstrandec3f2b02021-06-09 10:43:38 +0200152 eclose(fd);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200153}
154
Per Åstrandafb399f2021-11-26 12:50:35 +0100155int Device::ioctl(unsigned long cmd, void *data) const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200156 return eioctl(fd, cmd, data);
157}
158
Per Åstrandafb399f2021-11-26 12:50:35 +0100159Capabilities Device::capabilities() const {
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200160 ethosu_uapi_device_capabilities uapi;
161 (void)eioctl(fd, ETHOSU_IOCTL_CAPABILITIES_REQ, static_cast<void *>(&uapi));
162
163 Capabilities capabilities(
164 HardwareId(uapi.hw_id.version_status,
165 SemanticVersion(uapi.hw_id.version_major, uapi.hw_id.version_minor),
166 SemanticVersion(uapi.hw_id.product_major),
167 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 +0200168 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 +0200169 SemanticVersion(uapi.driver_major_rev, uapi.driver_minor_rev, uapi.driver_patch_rev));
170 return capabilities;
171}
172
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200173/****************************************************************************
174 * Buffer
175 ****************************************************************************/
176
Per Åstrandafb399f2021-11-26 12:50:35 +0100177Buffer::Buffer(const Device &device, const size_t capacity) : fd(-1), dataPtr(nullptr), dataCapacity(capacity) {
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200178 ethosu_uapi_buffer_create uapi = {static_cast<uint32_t>(dataCapacity)};
179 fd = device.ioctl(ETHOSU_IOCTL_BUFFER_CREATE, static_cast<void *>(&uapi));
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200180
Davide Grohmann2ba3c1d2021-11-08 15:08:48 +0100181 void *d;
182 try {
183 d = emmap(nullptr, dataCapacity, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
184 } catch (std::exception &e) {
185 try {
186 eclose(fd);
187 } catch (...) { std::throw_with_nested(e); }
188 }
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200189 dataPtr = reinterpret_cast<char *>(d);
190}
191
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200192Buffer::~Buffer() {
Davide Grohmann80f8ddf2022-04-07 14:50:50 +0200193 try {
194 emunmap(dataPtr, dataCapacity);
195 } catch (std::exception &e) {
196 try {
197 eclose(fd);
198 } catch (...) { std::throw_with_nested(e); }
199 }
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200200}
201
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200202size_t Buffer::capacity() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200203 return dataCapacity;
204}
205
Per Åstrandafb399f2021-11-26 12:50:35 +0100206void Buffer::clear() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200207 resize(0, 0);
208}
209
Per Åstrandafb399f2021-11-26 12:50:35 +0100210char *Buffer::data() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200211 return dataPtr + offset();
212}
213
Per Åstrandafb399f2021-11-26 12:50:35 +0100214void Buffer::resize(size_t size, size_t offset) const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200215 ethosu_uapi_buffer uapi;
216 uapi.offset = offset;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200217 uapi.size = size;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200218 eioctl(fd, ETHOSU_IOCTL_BUFFER_SET, static_cast<void *>(&uapi));
219}
220
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200221size_t Buffer::offset() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200222 ethosu_uapi_buffer uapi;
223 eioctl(fd, ETHOSU_IOCTL_BUFFER_GET, static_cast<void *>(&uapi));
224 return uapi.offset;
225}
226
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200227size_t Buffer::size() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200228 ethosu_uapi_buffer uapi;
229 eioctl(fd, ETHOSU_IOCTL_BUFFER_GET, static_cast<void *>(&uapi));
230 return uapi.size;
231}
232
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200233int Buffer::getFd() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200234 return fd;
235}
236
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200237/****************************************************************************
238 * Network
239 ****************************************************************************/
240
Per Åstrandafb399f2021-11-26 12:50:35 +0100241Network::Network(const Device &device, shared_ptr<Buffer> &buffer) : fd(-1), buffer(buffer) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200242 // Create buffer handle
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200243 ethosu_uapi_network_create uapi;
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100244 uapi.type = ETHOSU_UAPI_NETWORK_BUFFER;
245 uapi.fd = buffer->getFd();
246 fd = device.ioctl(ETHOSU_IOCTL_NETWORK_CREATE, static_cast<void *>(&uapi));
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100247 try {
Davide Grohmann80f8ddf2022-04-07 14:50:50 +0200248 collectNetworkInfo();
249 } catch (std::exception &e) {
250 try {
251 eclose(fd);
252 } catch (...) { std::throw_with_nested(e); }
Jonny Svärd2c017132021-04-12 15:56:44 +0200253 }
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100254}
Jonny Svärd2c017132021-04-12 15:56:44 +0200255
Kristofer Jonsson3c6a2602022-03-10 11:17:29 +0100256Network::Network(const Device &device, const unsigned index) : fd(-1) {
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100257 // Create buffer handle
258 ethosu_uapi_network_create uapi;
259 uapi.type = ETHOSU_UAPI_NETWORK_INDEX;
260 uapi.index = index;
261 fd = device.ioctl(ETHOSU_IOCTL_NETWORK_CREATE, static_cast<void *>(&uapi));
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100262 try {
Davide Grohmann80f8ddf2022-04-07 14:50:50 +0200263 collectNetworkInfo();
264 } catch (std::exception &e) {
265 try {
266 eclose(fd);
267 } catch (...) { std::throw_with_nested(e); }
268 }
269}
Kristofer Jonsson3c6a2602022-03-10 11:17:29 +0100270
Davide Grohmann80f8ddf2022-04-07 14:50:50 +0200271void Network::collectNetworkInfo() {
272 ethosu_uapi_network_info info;
273 ioctl(ETHOSU_IOCTL_NETWORK_INFO, static_cast<void *>(&info));
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100274
Davide Grohmann80f8ddf2022-04-07 14:50:50 +0200275 for (uint32_t i = 0; i < info.ifm_count; i++) {
276 ifmDims.push_back(info.ifm_size[i]);
277 }
278
279 for (uint32_t i = 0; i < info.ofm_count; i++) {
280 ofmDims.push_back(info.ofm_size[i]);
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100281 }
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200282}
283
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200284Network::~Network() {
Per Åstrandec3f2b02021-06-09 10:43:38 +0200285 eclose(fd);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200286}
287
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200288int Network::ioctl(unsigned long cmd, void *data) {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200289 return eioctl(fd, cmd, data);
290}
291
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200292shared_ptr<Buffer> Network::getBuffer() {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200293 return buffer;
294}
295
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200296const std::vector<size_t> &Network::getIfmDims() const {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200297 return ifmDims;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200298}
299
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200300size_t Network::getIfmSize() const {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200301 size_t size = 0;
302
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200303 for (auto s : ifmDims) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200304 size += s;
305 }
306
307 return size;
308}
309
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200310const std::vector<size_t> &Network::getOfmDims() const {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200311 return ofmDims;
312}
313
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200314size_t Network::getOfmSize() const {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200315 size_t size = 0;
316
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200317 for (auto s : ofmDims) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200318 size += s;
319 }
320
321 return size;
322}
323
324/****************************************************************************
325 * Inference
326 ****************************************************************************/
327
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200328Inference::~Inference() {
Per Åstrandec3f2b02021-06-09 10:43:38 +0200329 eclose(fd);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200330}
331
Per Åstrand2354d3e2020-10-24 20:17:10 +0200332void Inference::create(std::vector<uint32_t> &counterConfigs, bool cycleCounterEnable = false) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200333 ethosu_uapi_inference_create uapi;
334
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200335 if (ifmBuffers.size() > ETHOSU_FD_MAX) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200336 throw Exception("IFM buffer overflow");
337 }
338
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200339 if (ofmBuffers.size() > ETHOSU_FD_MAX) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200340 throw Exception("OFM buffer overflow");
341 }
342
Per Åstrand2354d3e2020-10-24 20:17:10 +0200343 if (counterConfigs.size() != ETHOSU_PMU_EVENT_MAX) {
344 throw Exception("Wrong size of counter configurations");
345 }
346
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200347 uapi.ifm_count = 0;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200348 for (auto it : ifmBuffers) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200349 uapi.ifm_fd[uapi.ifm_count++] = it->getFd();
350 }
351
352 uapi.ofm_count = 0;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200353 for (auto it : ofmBuffers) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200354 uapi.ofm_fd[uapi.ofm_count++] = it->getFd();
355 }
356
Per Åstrand2354d3e2020-10-24 20:17:10 +0200357 for (int i = 0; i < ETHOSU_PMU_EVENT_MAX; i++) {
358 uapi.pmu_config.events[i] = counterConfigs[i];
359 }
360
361 uapi.pmu_config.cycle_count = cycleCounterEnable;
362
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200363 fd = network->ioctl(ETHOSU_IOCTL_INFERENCE_CREATE, static_cast<void *>(&uapi));
364}
365
Per Åstrand2354d3e2020-10-24 20:17:10 +0200366std::vector<uint32_t> Inference::initializeCounterConfig() {
367 return std::vector<uint32_t>(ETHOSU_PMU_EVENT_MAX, 0);
368}
369
370uint32_t Inference::getMaxPmuEventCounters() {
371 return ETHOSU_PMU_EVENT_MAX;
372}
373
Per Åstrandafb399f2021-11-26 12:50:35 +0100374int Inference::wait(int64_t timeoutNanos) const {
Davide Grohmanne446b422021-10-19 15:33:23 +0200375 struct pollfd pfd;
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200376 pfd.fd = fd;
377 pfd.events = POLLIN | POLLERR;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200378 pfd.revents = 0;
379
Davide Grohmanne446b422021-10-19 15:33:23 +0200380 // if timeout negative wait forever
381 if (timeoutNanos < 0) {
382 return eppoll(&pfd, 1, NULL, NULL);
383 }
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200384
Davide Grohmanne446b422021-10-19 15:33:23 +0200385 struct timespec tmo_p;
386 int64_t nanosec = 1000000000;
387 tmo_p.tv_sec = timeoutNanos / nanosec;
388 tmo_p.tv_nsec = timeoutNanos % nanosec;
Per Åstrand2354d3e2020-10-24 20:17:10 +0200389
Davide Grohmanne446b422021-10-19 15:33:23 +0200390 return eppoll(&pfd, 1, &tmo_p, NULL);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200391}
392
Per Åstrandafb399f2021-11-26 12:50:35 +0100393bool Inference::failed() const {
Per Åstrand2354d3e2020-10-24 20:17:10 +0200394 ethosu_uapi_result_status uapi;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200395
Per Åstrand2354d3e2020-10-24 20:17:10 +0200396 eioctl(fd, ETHOSU_IOCTL_INFERENCE_STATUS, static_cast<void *>(&uapi));
397
398 return uapi.status != ETHOSU_UAPI_STATUS_OK;
399}
400
Per Åstrandafb399f2021-11-26 12:50:35 +0100401const std::vector<uint32_t> Inference::getPmuCounters() const {
Per Åstrand2354d3e2020-10-24 20:17:10 +0200402 ethosu_uapi_result_status uapi;
403 std::vector<uint32_t> counterValues = std::vector<uint32_t>(ETHOSU_PMU_EVENT_MAX, 0);
404
405 eioctl(fd, ETHOSU_IOCTL_INFERENCE_STATUS, static_cast<void *>(&uapi));
406
407 for (int i = 0; i < ETHOSU_PMU_EVENT_MAX; i++) {
408 if (uapi.pmu_config.events[i]) {
409 counterValues.at(i) = uapi.pmu_count.events[i];
410 }
411 }
412
413 return counterValues;
414}
415
Per Åstrandafb399f2021-11-26 12:50:35 +0100416uint64_t Inference::getCycleCounter() const {
Per Åstrand2354d3e2020-10-24 20:17:10 +0200417 ethosu_uapi_result_status uapi;
418
419 eioctl(fd, ETHOSU_IOCTL_INFERENCE_STATUS, static_cast<void *>(&uapi));
420
421 return uapi.pmu_count.cycle_count;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200422}
423
Per Åstrandafb399f2021-11-26 12:50:35 +0100424int Inference::getFd() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200425 return fd;
426}
427
Per Åstrandafb399f2021-11-26 12:50:35 +0100428const shared_ptr<Network> Inference::getNetwork() const {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200429 return network;
430}
431
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200432vector<shared_ptr<Buffer>> &Inference::getIfmBuffers() {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200433 return ifmBuffers;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200434}
435
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200436vector<shared_ptr<Buffer>> &Inference::getOfmBuffers() {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200437 return ofmBuffers;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200438}
439
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200440} // namespace EthosU