blob: 27f68284dee6a6cab1b9b9c20e4327d09adb3cc0 [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 * SPDX-License-Identifier: Apache-2.0
4 *
5 * Licensed under the Apache License, Version 2.0 (the License); you may
6 * not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an AS IS BASIS, WITHOUT
13 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18#pragma once
19
Kristofer Jonssonb74492c2020-09-10 13:26:01 +020020#include <algorithm>
Davide Grohmann35ce6c82021-06-01 15:03:51 +020021#include <iostream>
Kristofer Jonsson116a6352020-08-20 17:25:23 +020022#include <memory>
23#include <string>
Kristofer Jonssonb74492c2020-09-10 13:26:01 +020024#include <vector>
Kristofer Jonsson116a6352020-08-20 17:25:23 +020025
Davide Grohmann35ce6c82021-06-01 15:03:51 +020026/*
27 *The following undef are necessary to avoid clash with macros in GNU C Library
28 * if removed the following warning/error are produced:
29 *
30 * In the GNU C Library, "major" ("minor") is defined
31 * by <sys/sysmacros.h>. For historical compatibility, it is
32 * currently defined by <sys/types.h> as well, but we plan to
33 * remove this soon. To use "major" ("minor"), include <sys/sysmacros.h>
34 * directly. If you did not intend to use a system-defined macro
35 * "major" ("minor"), you should undefine it after including <sys/types.h>.
36 */
37#undef major
38#undef minor
39
Kristofer Jonsson79689c52020-10-16 14:42:19 +020040namespace EthosU {
Kristofer Jonsson116a6352020-08-20 17:25:23 +020041
Mikael Olssonc081e592023-10-30 11:10:56 +010042constexpr uint32_t DRIVER_LIBRARY_VERSION_MAJOR = 3;
Mikael Olssone9c3f072023-06-12 15:58:10 +020043constexpr uint32_t DRIVER_LIBRARY_VERSION_MINOR = 0;
44constexpr uint32_t DRIVER_LIBRARY_VERSION_PATCH = 0;
45
Mikael Olssonc081e592023-10-30 11:10:56 +010046constexpr uint32_t MAX_SUPPORTED_KERNEL_DRIVER_MAJOR_VERSION = 3;
47constexpr uint32_t MIN_SUPPORTED_KERNEL_DRIVER_MAJOR_VERSION = 3;
Mikael Olsson308e7f12023-06-12 15:00:55 +020048
Kristofer Jonsson79689c52020-10-16 14:42:19 +020049class Exception : public std::exception {
Kristofer Jonsson116a6352020-08-20 17:25:23 +020050public:
51 Exception(const char *msg);
52 virtual ~Exception() throw();
53 virtual const char *what() const throw();
54
55private:
56 std::string msg;
57};
58
Davide Grohmann35ce6c82021-06-01 15:03:51 +020059/**
60 * Sematic Version : major.minor.patch
61 */
62class SemanticVersion {
63public:
64 SemanticVersion(uint32_t _major = 0, uint32_t _minor = 0, uint32_t _patch = 0) :
65 major(_major), minor(_minor), patch(_patch){};
66
67 bool operator==(const SemanticVersion &other);
68 bool operator<(const SemanticVersion &other);
69 bool operator<=(const SemanticVersion &other);
70 bool operator!=(const SemanticVersion &other);
71 bool operator>(const SemanticVersion &other);
72 bool operator>=(const SemanticVersion &other);
73
74 uint32_t major;
75 uint32_t minor;
76 uint32_t patch;
77};
78
79std::ostream &operator<<(std::ostream &out, const SemanticVersion &v);
80
Mikael Olssone9c3f072023-06-12 15:58:10 +020081const SemanticVersion getLibraryVersion();
82
Davide Grohmann35ce6c82021-06-01 15:03:51 +020083/*
84 * Hardware Identifier
85 * @versionStatus: Version status
86 * @version: Version revision
87 * @product: Product revision
88 * @architecture: Architecture revison
89 */
90struct HardwareId {
91public:
Davide Grohmannf0364232022-06-16 17:42:58 +020092 HardwareId(uint32_t _versionStatus = 0,
93 const SemanticVersion &_version = SemanticVersion(),
94 const SemanticVersion &_product = SemanticVersion(),
95 const SemanticVersion &_architecture = SemanticVersion()) :
Davide Grohmann35ce6c82021-06-01 15:03:51 +020096 versionStatus(_versionStatus),
97 version(_version), product(_product), architecture(_architecture) {}
98
99 uint32_t versionStatus;
100 SemanticVersion version;
101 SemanticVersion product;
102 SemanticVersion architecture;
103};
104
105/*
106 * Hardware Configuration
107 * @macsPerClockCycle: MACs per clock cycle
108 * @cmdStreamVersion: NPU command stream version
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200109 * @customDma: Custom DMA enabled
110 */
111struct HardwareConfiguration {
112public:
Davide Grohmannf0364232022-06-16 17:42:58 +0200113 HardwareConfiguration(uint32_t _macsPerClockCycle = 0, uint32_t _cmdStreamVersion = 0, bool _customDma = false) :
Davide Grohmann40e23d12021-06-17 09:59:40 +0200114 macsPerClockCycle(_macsPerClockCycle), cmdStreamVersion(_cmdStreamVersion), customDma(_customDma) {}
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200115
116 uint32_t macsPerClockCycle;
117 uint32_t cmdStreamVersion;
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200118 bool customDma;
119};
120
121/**
122 * Device capabilities
123 * @hwId: Hardware
124 * @driver: Driver revision
125 * @hwCfg Hardware configuration
126 */
127class Capabilities {
128public:
Davide Grohmannf0364232022-06-16 17:42:58 +0200129 Capabilities() {}
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200130 Capabilities(const HardwareId &_hwId, const HardwareConfiguration &_hwCfg, const SemanticVersion &_driver) :
131 hwId(_hwId), hwCfg(_hwCfg), driver(_driver) {}
132
133 HardwareId hwId;
134 HardwareConfiguration hwCfg;
135 SemanticVersion driver;
136};
137
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200138class Device {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200139public:
140 Device(const char *device = "/dev/ethosu0");
Davide Grohmannfc495592022-04-25 15:27:52 +0200141 virtual ~Device() noexcept(false);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200142
Per Åstrandafb399f2021-11-26 12:50:35 +0100143 int ioctl(unsigned long cmd, void *data = nullptr) const;
144 Capabilities capabilities() const;
Mikael Olsson308e7f12023-06-12 15:00:55 +0200145 const SemanticVersion &getDriverVersion() const;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200146
147private:
148 int fd;
Mikael Olsson308e7f12023-06-12 15:00:55 +0200149 SemanticVersion driverVersion;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200150};
151
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200152class Buffer {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200153public:
Mikael Olsson07545152023-10-17 13:05:38 +0200154 Buffer(const Device &device, const size_t size);
Davide Grohmannfc495592022-04-25 15:27:52 +0200155 virtual ~Buffer() noexcept(false);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200156
Per Åstrandafb399f2021-11-26 12:50:35 +0100157 void clear() const;
158 char *data() const;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200159 size_t size() const;
160
161 int getFd() const;
162
163private:
164 int fd;
165 char *dataPtr;
Mikael Olsson07545152023-10-17 13:05:38 +0200166 const size_t dataSize;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200167};
168
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200169class Network {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200170public:
Mikael Olssonc081e592023-10-30 11:10:56 +0100171 Network(const Device &device, const unsigned char *networkData, size_t networkSize);
Kristofer Jonsson3c6a2602022-03-10 11:17:29 +0100172 Network(const Device &device, const unsigned index);
Davide Grohmannfc495592022-04-25 15:27:52 +0200173 virtual ~Network() noexcept(false);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200174
175 int ioctl(unsigned long cmd, void *data = nullptr);
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200176 const std::vector<size_t> &getIfmDims() const;
177 size_t getIfmSize() const;
178 const std::vector<size_t> &getOfmDims() const;
179 size_t getOfmSize() const;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200180
181private:
Davide Grohmann80f8ddf2022-04-07 14:50:50 +0200182 void collectNetworkInfo();
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100183
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200184 int fd;
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;
Mikael Olssone87446c2023-12-15 17:17:06 +0100238 const std::vector<uint64_t> getPmuCounters() const;
Per Åstrandafb399f2021-11-26 12:50:35 +0100239 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