blob: 4dba469a28cfab03f62d18a2d482bb9c7be01d47 [file] [log] [blame]
Kristofer Jonsson116a6352020-08-20 17:25:23 +02001/*
Mikael Olsson308e7f12023-06-12 15:00:55 +02002 * SPDX-FileCopyrightText: Copyright 2020-2023 Arm Limited and/or its affiliates <open-source-office@arm.com>
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#pragma once
20
Kristofer Jonssonb74492c2020-09-10 13:26:01 +020021#include <algorithm>
Davide Grohmann35ce6c82021-06-01 15:03:51 +020022#include <iostream>
Kristofer Jonsson116a6352020-08-20 17:25:23 +020023#include <memory>
24#include <string>
Kristofer Jonssonb74492c2020-09-10 13:26:01 +020025#include <vector>
Kristofer Jonsson116a6352020-08-20 17:25:23 +020026
Davide Grohmann35ce6c82021-06-01 15:03:51 +020027/*
28 *The following undef are necessary to avoid clash with macros in GNU C Library
29 * if removed the following warning/error are produced:
30 *
31 * In the GNU C Library, "major" ("minor") is defined
32 * by <sys/sysmacros.h>. For historical compatibility, it is
33 * currently defined by <sys/types.h> as well, but we plan to
34 * remove this soon. To use "major" ("minor"), include <sys/sysmacros.h>
35 * directly. If you did not intend to use a system-defined macro
36 * "major" ("minor"), you should undefine it after including <sys/types.h>.
37 */
38#undef major
39#undef minor
40
Kristofer Jonsson79689c52020-10-16 14:42:19 +020041namespace EthosU {
Kristofer Jonsson116a6352020-08-20 17:25:23 +020042
Mikael Olsson308e7f12023-06-12 15:00:55 +020043constexpr uint32_t MAX_SUPPORTED_KERNEL_DRIVER_MAJOR_VERSION = 1;
44constexpr uint32_t MIN_SUPPORTED_KERNEL_DRIVER_MAJOR_VERSION = 1;
45
Kristofer Jonsson79689c52020-10-16 14:42:19 +020046class Exception : public std::exception {
Kristofer Jonsson116a6352020-08-20 17:25:23 +020047public:
48 Exception(const char *msg);
49 virtual ~Exception() throw();
50 virtual const char *what() const throw();
51
52private:
53 std::string msg;
54};
55
Davide Grohmann35ce6c82021-06-01 15:03:51 +020056/**
57 * Sematic Version : major.minor.patch
58 */
59class SemanticVersion {
60public:
61 SemanticVersion(uint32_t _major = 0, uint32_t _minor = 0, uint32_t _patch = 0) :
62 major(_major), minor(_minor), patch(_patch){};
63
64 bool operator==(const SemanticVersion &other);
65 bool operator<(const SemanticVersion &other);
66 bool operator<=(const SemanticVersion &other);
67 bool operator!=(const SemanticVersion &other);
68 bool operator>(const SemanticVersion &other);
69 bool operator>=(const SemanticVersion &other);
70
71 uint32_t major;
72 uint32_t minor;
73 uint32_t patch;
74};
75
76std::ostream &operator<<(std::ostream &out, const SemanticVersion &v);
77
78/*
79 * Hardware Identifier
80 * @versionStatus: Version status
81 * @version: Version revision
82 * @product: Product revision
83 * @architecture: Architecture revison
84 */
85struct HardwareId {
86public:
Davide Grohmannf0364232022-06-16 17:42:58 +020087 HardwareId(uint32_t _versionStatus = 0,
88 const SemanticVersion &_version = SemanticVersion(),
89 const SemanticVersion &_product = SemanticVersion(),
90 const SemanticVersion &_architecture = SemanticVersion()) :
Davide Grohmann35ce6c82021-06-01 15:03:51 +020091 versionStatus(_versionStatus),
92 version(_version), product(_product), architecture(_architecture) {}
93
94 uint32_t versionStatus;
95 SemanticVersion version;
96 SemanticVersion product;
97 SemanticVersion architecture;
98};
99
100/*
101 * Hardware Configuration
102 * @macsPerClockCycle: MACs per clock cycle
103 * @cmdStreamVersion: NPU command stream version
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200104 * @customDma: Custom DMA enabled
105 */
106struct HardwareConfiguration {
107public:
Davide Grohmannf0364232022-06-16 17:42:58 +0200108 HardwareConfiguration(uint32_t _macsPerClockCycle = 0, uint32_t _cmdStreamVersion = 0, bool _customDma = false) :
Davide Grohmann40e23d12021-06-17 09:59:40 +0200109 macsPerClockCycle(_macsPerClockCycle), cmdStreamVersion(_cmdStreamVersion), customDma(_customDma) {}
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200110
111 uint32_t macsPerClockCycle;
112 uint32_t cmdStreamVersion;
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200113 bool customDma;
114};
115
116/**
117 * Device capabilities
118 * @hwId: Hardware
119 * @driver: Driver revision
120 * @hwCfg Hardware configuration
121 */
122class Capabilities {
123public:
Davide Grohmannf0364232022-06-16 17:42:58 +0200124 Capabilities() {}
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200125 Capabilities(const HardwareId &_hwId, const HardwareConfiguration &_hwCfg, const SemanticVersion &_driver) :
126 hwId(_hwId), hwCfg(_hwCfg), driver(_driver) {}
127
128 HardwareId hwId;
129 HardwareConfiguration hwCfg;
130 SemanticVersion driver;
131};
132
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200133class Device {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200134public:
135 Device(const char *device = "/dev/ethosu0");
Davide Grohmannfc495592022-04-25 15:27:52 +0200136 virtual ~Device() noexcept(false);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200137
Per Åstrandafb399f2021-11-26 12:50:35 +0100138 int ioctl(unsigned long cmd, void *data = nullptr) const;
139 Capabilities capabilities() const;
Mikael Olsson308e7f12023-06-12 15:00:55 +0200140 const SemanticVersion &getDriverVersion() const;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200141
142private:
143 int fd;
Mikael Olsson308e7f12023-06-12 15:00:55 +0200144 SemanticVersion driverVersion;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200145};
146
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200147class Buffer {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200148public:
Per Åstrandafb399f2021-11-26 12:50:35 +0100149 Buffer(const Device &device, const size_t capacity);
Davide Grohmannfc495592022-04-25 15:27:52 +0200150 virtual ~Buffer() noexcept(false);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200151
152 size_t capacity() const;
Per Åstrandafb399f2021-11-26 12:50:35 +0100153 void clear() const;
154 char *data() const;
155 void resize(size_t size, size_t offset = 0) const;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200156 size_t offset() const;
157 size_t size() const;
158
159 int getFd() const;
160
161private:
162 int fd;
163 char *dataPtr;
164 const size_t dataCapacity;
165};
166
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200167class Network {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200168public:
Per Åstrandafb399f2021-11-26 12:50:35 +0100169 Network(const Device &device, std::shared_ptr<Buffer> &buffer);
Kristofer Jonsson3c6a2602022-03-10 11:17:29 +0100170 Network(const Device &device, const unsigned index);
Davide Grohmannfc495592022-04-25 15:27:52 +0200171 virtual ~Network() noexcept(false);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200172
173 int ioctl(unsigned long cmd, void *data = nullptr);
174 std::shared_ptr<Buffer> getBuffer();
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200175 const std::vector<size_t> &getIfmDims() const;
176 size_t getIfmSize() const;
177 const std::vector<size_t> &getOfmDims() const;
178 size_t getOfmSize() const;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200179
180private:
Davide Grohmann80f8ddf2022-04-07 14:50:50 +0200181 void collectNetworkInfo();
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100182
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200183 int fd;
184 std::shared_ptr<Buffer> buffer;
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200185 std::vector<size_t> ifmDims;
186 std::vector<size_t> ofmDims;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200187};
188
Davide Grohmann82d22582022-04-25 12:52:38 +0200189enum class InferenceStatus {
190 OK,
191 ERROR,
192 RUNNING,
193 REJECTED,
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100194 ABORTED,
195 ABORTING,
Davide Grohmann82d22582022-04-25 12:52:38 +0200196};
197
198std::ostream &operator<<(std::ostream &out, const InferenceStatus &v);
199
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200200class Inference {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200201public:
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200202 template <typename T>
Per Åstrandafb399f2021-11-26 12:50:35 +0100203 Inference(const std::shared_ptr<Network> &network,
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200204 const T &ifmBegin,
205 const T &ifmEnd,
206 const T &ofmBegin,
207 const T &ofmEnd) :
208 network(network) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200209 std::copy(ifmBegin, ifmEnd, std::back_inserter(ifmBuffers));
210 std::copy(ofmBegin, ofmEnd, std::back_inserter(ofmBuffers));
Per Åstrand2354d3e2020-10-24 20:17:10 +0200211 std::vector<uint32_t> counterConfigs = initializeCounterConfig();
212
213 create(counterConfigs, false);
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200214 }
Per Åstrand2354d3e2020-10-24 20:17:10 +0200215 template <typename T, typename U>
Per Åstrandafb399f2021-11-26 12:50:35 +0100216 Inference(const std::shared_ptr<Network> &network,
Per Åstrand2354d3e2020-10-24 20:17:10 +0200217 const T &ifmBegin,
218 const T &ifmEnd,
219 const T &ofmBegin,
220 const T &ofmEnd,
221 const U &counters,
222 bool enableCycleCounter) :
223 network(network) {
224 std::copy(ifmBegin, ifmEnd, std::back_inserter(ifmBuffers));
225 std::copy(ofmBegin, ofmEnd, std::back_inserter(ofmBuffers));
226 std::vector<uint32_t> counterConfigs = initializeCounterConfig();
227
228 if (counters.size() > counterConfigs.size())
229 throw EthosU::Exception("PMU Counters argument to large.");
230
231 std::copy(counters.begin(), counters.end(), counterConfigs.begin());
232 create(counterConfigs, enableCycleCounter);
233 }
234
Davide Grohmannfc495592022-04-25 15:27:52 +0200235 virtual ~Inference() noexcept(false);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200236
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100237 bool wait(int64_t timeoutNanos = -1) const;
Per Åstrandafb399f2021-11-26 12:50:35 +0100238 const std::vector<uint32_t> getPmuCounters() const;
239 uint64_t getCycleCounter() const;
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100240 bool cancel() const;
Davide Grohmann82d22582022-04-25 12:52:38 +0200241 InferenceStatus status() const;
Per Åstrandafb399f2021-11-26 12:50:35 +0100242 int getFd() const;
243 const std::shared_ptr<Network> getNetwork() const;
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200244 std::vector<std::shared_ptr<Buffer>> &getIfmBuffers();
245 std::vector<std::shared_ptr<Buffer>> &getOfmBuffers();
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200246
Per Åstrand2354d3e2020-10-24 20:17:10 +0200247 static uint32_t getMaxPmuEventCounters();
248
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200249private:
Per Åstrand2354d3e2020-10-24 20:17:10 +0200250 void create(std::vector<uint32_t> &counterConfigs, bool enableCycleCounter);
251 std::vector<uint32_t> initializeCounterConfig();
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200252
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200253 int fd;
Per Åstrandafb399f2021-11-26 12:50:35 +0100254 const std::shared_ptr<Network> network;
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200255 std::vector<std::shared_ptr<Buffer>> ifmBuffers;
256 std::vector<std::shared_ptr<Buffer>> ofmBuffers;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200257};
258
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200259} // namespace EthosU