blob: 491dc281d4cc5f9729df927e02fdf7dc721c0481 [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 Olssone9c3f072023-06-12 15:58:10 +020043constexpr uint32_t DRIVER_LIBRARY_VERSION_MAJOR = 1;
44constexpr uint32_t DRIVER_LIBRARY_VERSION_MINOR = 0;
45constexpr uint32_t DRIVER_LIBRARY_VERSION_PATCH = 0;
46
Mikael Olsson308e7f12023-06-12 15:00:55 +020047constexpr uint32_t MAX_SUPPORTED_KERNEL_DRIVER_MAJOR_VERSION = 1;
48constexpr uint32_t MIN_SUPPORTED_KERNEL_DRIVER_MAJOR_VERSION = 1;
49
Kristofer Jonsson79689c52020-10-16 14:42:19 +020050class Exception : public std::exception {
Kristofer Jonsson116a6352020-08-20 17:25:23 +020051public:
52 Exception(const char *msg);
53 virtual ~Exception() throw();
54 virtual const char *what() const throw();
55
56private:
57 std::string msg;
58};
59
Davide Grohmann35ce6c82021-06-01 15:03:51 +020060/**
61 * Sematic Version : major.minor.patch
62 */
63class SemanticVersion {
64public:
65 SemanticVersion(uint32_t _major = 0, uint32_t _minor = 0, uint32_t _patch = 0) :
66 major(_major), minor(_minor), patch(_patch){};
67
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 bool operator>=(const SemanticVersion &other);
74
75 uint32_t major;
76 uint32_t minor;
77 uint32_t patch;
78};
79
80std::ostream &operator<<(std::ostream &out, const SemanticVersion &v);
81
Mikael Olssone9c3f072023-06-12 15:58:10 +020082const SemanticVersion getLibraryVersion();
83
Davide Grohmann35ce6c82021-06-01 15:03:51 +020084/*
85 * Hardware Identifier
86 * @versionStatus: Version status
87 * @version: Version revision
88 * @product: Product revision
89 * @architecture: Architecture revison
90 */
91struct HardwareId {
92public:
Davide Grohmannf0364232022-06-16 17:42:58 +020093 HardwareId(uint32_t _versionStatus = 0,
94 const SemanticVersion &_version = SemanticVersion(),
95 const SemanticVersion &_product = SemanticVersion(),
96 const SemanticVersion &_architecture = SemanticVersion()) :
Davide Grohmann35ce6c82021-06-01 15:03:51 +020097 versionStatus(_versionStatus),
98 version(_version), product(_product), architecture(_architecture) {}
99
100 uint32_t versionStatus;
101 SemanticVersion version;
102 SemanticVersion product;
103 SemanticVersion architecture;
104};
105
106/*
107 * Hardware Configuration
108 * @macsPerClockCycle: MACs per clock cycle
109 * @cmdStreamVersion: NPU command stream version
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200110 * @customDma: Custom DMA enabled
111 */
112struct HardwareConfiguration {
113public:
Davide Grohmannf0364232022-06-16 17:42:58 +0200114 HardwareConfiguration(uint32_t _macsPerClockCycle = 0, uint32_t _cmdStreamVersion = 0, bool _customDma = false) :
Davide Grohmann40e23d12021-06-17 09:59:40 +0200115 macsPerClockCycle(_macsPerClockCycle), cmdStreamVersion(_cmdStreamVersion), customDma(_customDma) {}
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200116
117 uint32_t macsPerClockCycle;
118 uint32_t cmdStreamVersion;
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200119 bool customDma;
120};
121
122/**
123 * Device capabilities
124 * @hwId: Hardware
125 * @driver: Driver revision
126 * @hwCfg Hardware configuration
127 */
128class Capabilities {
129public:
Davide Grohmannf0364232022-06-16 17:42:58 +0200130 Capabilities() {}
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200131 Capabilities(const HardwareId &_hwId, const HardwareConfiguration &_hwCfg, const SemanticVersion &_driver) :
132 hwId(_hwId), hwCfg(_hwCfg), driver(_driver) {}
133
134 HardwareId hwId;
135 HardwareConfiguration hwCfg;
136 SemanticVersion driver;
137};
138
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200139class Device {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200140public:
141 Device(const char *device = "/dev/ethosu0");
Davide Grohmannfc495592022-04-25 15:27:52 +0200142 virtual ~Device() noexcept(false);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200143
Per Åstrandafb399f2021-11-26 12:50:35 +0100144 int ioctl(unsigned long cmd, void *data = nullptr) const;
145 Capabilities capabilities() const;
Mikael Olsson308e7f12023-06-12 15:00:55 +0200146 const SemanticVersion &getDriverVersion() const;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200147
148private:
149 int fd;
Mikael Olsson308e7f12023-06-12 15:00:55 +0200150 SemanticVersion driverVersion;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200151};
152
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200153class Buffer {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200154public:
Per Åstrandafb399f2021-11-26 12:50:35 +0100155 Buffer(const Device &device, const size_t capacity);
Davide Grohmannfc495592022-04-25 15:27:52 +0200156 virtual ~Buffer() noexcept(false);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200157
158 size_t capacity() const;
Per Åstrandafb399f2021-11-26 12:50:35 +0100159 void clear() const;
160 char *data() const;
161 void resize(size_t size, size_t offset = 0) const;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200162 size_t offset() const;
163 size_t size() const;
164
165 int getFd() const;
166
167private:
168 int fd;
169 char *dataPtr;
170 const size_t dataCapacity;
171};
172
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200173class Network {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200174public:
Per Åstrandafb399f2021-11-26 12:50:35 +0100175 Network(const Device &device, std::shared_ptr<Buffer> &buffer);
Kristofer Jonsson3c6a2602022-03-10 11:17:29 +0100176 Network(const Device &device, const unsigned index);
Davide Grohmannfc495592022-04-25 15:27:52 +0200177 virtual ~Network() noexcept(false);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200178
179 int ioctl(unsigned long cmd, void *data = nullptr);
180 std::shared_ptr<Buffer> getBuffer();
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200181 const std::vector<size_t> &getIfmDims() const;
182 size_t getIfmSize() const;
183 const std::vector<size_t> &getOfmDims() const;
184 size_t getOfmSize() const;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200185
186private:
Davide Grohmann80f8ddf2022-04-07 14:50:50 +0200187 void collectNetworkInfo();
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100188
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200189 int fd;
190 std::shared_ptr<Buffer> buffer;
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200191 std::vector<size_t> ifmDims;
192 std::vector<size_t> ofmDims;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200193};
194
Davide Grohmann82d22582022-04-25 12:52:38 +0200195enum class InferenceStatus {
196 OK,
197 ERROR,
198 RUNNING,
199 REJECTED,
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100200 ABORTED,
201 ABORTING,
Davide Grohmann82d22582022-04-25 12:52:38 +0200202};
203
204std::ostream &operator<<(std::ostream &out, const InferenceStatus &v);
205
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200206class Inference {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200207public:
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200208 template <typename T>
Per Åstrandafb399f2021-11-26 12:50:35 +0100209 Inference(const std::shared_ptr<Network> &network,
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200210 const T &ifmBegin,
211 const T &ifmEnd,
212 const T &ofmBegin,
213 const T &ofmEnd) :
214 network(network) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200215 std::copy(ifmBegin, ifmEnd, std::back_inserter(ifmBuffers));
216 std::copy(ofmBegin, ofmEnd, std::back_inserter(ofmBuffers));
Per Åstrand2354d3e2020-10-24 20:17:10 +0200217 std::vector<uint32_t> counterConfigs = initializeCounterConfig();
218
219 create(counterConfigs, false);
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200220 }
Per Åstrand2354d3e2020-10-24 20:17:10 +0200221 template <typename T, typename U>
Per Åstrandafb399f2021-11-26 12:50:35 +0100222 Inference(const std::shared_ptr<Network> &network,
Per Åstrand2354d3e2020-10-24 20:17:10 +0200223 const T &ifmBegin,
224 const T &ifmEnd,
225 const T &ofmBegin,
226 const T &ofmEnd,
227 const U &counters,
228 bool enableCycleCounter) :
229 network(network) {
230 std::copy(ifmBegin, ifmEnd, std::back_inserter(ifmBuffers));
231 std::copy(ofmBegin, ofmEnd, std::back_inserter(ofmBuffers));
232 std::vector<uint32_t> counterConfigs = initializeCounterConfig();
233
234 if (counters.size() > counterConfigs.size())
235 throw EthosU::Exception("PMU Counters argument to large.");
236
237 std::copy(counters.begin(), counters.end(), counterConfigs.begin());
238 create(counterConfigs, enableCycleCounter);
239 }
240
Davide Grohmannfc495592022-04-25 15:27:52 +0200241 virtual ~Inference() noexcept(false);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200242
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100243 bool wait(int64_t timeoutNanos = -1) const;
Per Åstrandafb399f2021-11-26 12:50:35 +0100244 const std::vector<uint32_t> getPmuCounters() const;
245 uint64_t getCycleCounter() const;
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100246 bool cancel() const;
Davide Grohmann82d22582022-04-25 12:52:38 +0200247 InferenceStatus status() const;
Per Åstrandafb399f2021-11-26 12:50:35 +0100248 int getFd() const;
249 const std::shared_ptr<Network> getNetwork() const;
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200250 std::vector<std::shared_ptr<Buffer>> &getIfmBuffers();
251 std::vector<std::shared_ptr<Buffer>> &getOfmBuffers();
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200252
Per Åstrand2354d3e2020-10-24 20:17:10 +0200253 static uint32_t getMaxPmuEventCounters();
254
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200255private:
Per Åstrand2354d3e2020-10-24 20:17:10 +0200256 void create(std::vector<uint32_t> &counterConfigs, bool enableCycleCounter);
257 std::vector<uint32_t> initializeCounterConfig();
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200258
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200259 int fd;
Per Åstrandafb399f2021-11-26 12:50:35 +0100260 const std::shared_ptr<Network> network;
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200261 std::vector<std::shared_ptr<Buffer>> ifmBuffers;
262 std::vector<std::shared_ptr<Buffer>> ofmBuffers;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200263};
264
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200265} // namespace EthosU