blob: 47c18685230ffcd86d789b00bec973f8efd9920d [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 Olsson07545152023-10-17 13:05:38 +020042constexpr uint32_t DRIVER_LIBRARY_VERSION_MAJOR = 2;
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 Olsson07545152023-10-17 13:05:38 +020046constexpr uint32_t MAX_SUPPORTED_KERNEL_DRIVER_MAJOR_VERSION = 2;
47constexpr uint32_t MIN_SUPPORTED_KERNEL_DRIVER_MAJOR_VERSION = 2;
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:
Per Åstrandafb399f2021-11-26 12:50:35 +0100171 Network(const Device &device, std::shared_ptr<Buffer> &buffer);
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);
176 std::shared_ptr<Buffer> getBuffer();
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200177 const std::vector<size_t> &getIfmDims() const;
178 size_t getIfmSize() const;
179 const std::vector<size_t> &getOfmDims() const;
180 size_t getOfmSize() const;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200181
182private:
Davide Grohmann80f8ddf2022-04-07 14:50:50 +0200183 void collectNetworkInfo();
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100184
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200185 int fd;
186 std::shared_ptr<Buffer> buffer;
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200187 std::vector<size_t> ifmDims;
188 std::vector<size_t> ofmDims;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200189};
190
Davide Grohmann82d22582022-04-25 12:52:38 +0200191enum class InferenceStatus {
192 OK,
193 ERROR,
194 RUNNING,
195 REJECTED,
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100196 ABORTED,
197 ABORTING,
Davide Grohmann82d22582022-04-25 12:52:38 +0200198};
199
200std::ostream &operator<<(std::ostream &out, const InferenceStatus &v);
201
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200202class Inference {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200203public:
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200204 template <typename T>
Per Åstrandafb399f2021-11-26 12:50:35 +0100205 Inference(const std::shared_ptr<Network> &network,
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200206 const T &ifmBegin,
207 const T &ifmEnd,
208 const T &ofmBegin,
209 const T &ofmEnd) :
210 network(network) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200211 std::copy(ifmBegin, ifmEnd, std::back_inserter(ifmBuffers));
212 std::copy(ofmBegin, ofmEnd, std::back_inserter(ofmBuffers));
Per Åstrand2354d3e2020-10-24 20:17:10 +0200213 std::vector<uint32_t> counterConfigs = initializeCounterConfig();
214
215 create(counterConfigs, false);
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200216 }
Per Åstrand2354d3e2020-10-24 20:17:10 +0200217 template <typename T, typename U>
Per Åstrandafb399f2021-11-26 12:50:35 +0100218 Inference(const std::shared_ptr<Network> &network,
Per Åstrand2354d3e2020-10-24 20:17:10 +0200219 const T &ifmBegin,
220 const T &ifmEnd,
221 const T &ofmBegin,
222 const T &ofmEnd,
223 const U &counters,
224 bool enableCycleCounter) :
225 network(network) {
226 std::copy(ifmBegin, ifmEnd, std::back_inserter(ifmBuffers));
227 std::copy(ofmBegin, ofmEnd, std::back_inserter(ofmBuffers));
228 std::vector<uint32_t> counterConfigs = initializeCounterConfig();
229
230 if (counters.size() > counterConfigs.size())
231 throw EthosU::Exception("PMU Counters argument to large.");
232
233 std::copy(counters.begin(), counters.end(), counterConfigs.begin());
234 create(counterConfigs, enableCycleCounter);
235 }
236
Davide Grohmannfc495592022-04-25 15:27:52 +0200237 virtual ~Inference() noexcept(false);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200238
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100239 bool wait(int64_t timeoutNanos = -1) const;
Per Åstrandafb399f2021-11-26 12:50:35 +0100240 const std::vector<uint32_t> getPmuCounters() const;
241 uint64_t getCycleCounter() const;
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100242 bool cancel() const;
Davide Grohmann82d22582022-04-25 12:52:38 +0200243 InferenceStatus status() const;
Per Åstrandafb399f2021-11-26 12:50:35 +0100244 int getFd() const;
245 const std::shared_ptr<Network> getNetwork() const;
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200246 std::vector<std::shared_ptr<Buffer>> &getIfmBuffers();
247 std::vector<std::shared_ptr<Buffer>> &getOfmBuffers();
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200248
Per Åstrand2354d3e2020-10-24 20:17:10 +0200249 static uint32_t getMaxPmuEventCounters();
250
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200251private:
Per Åstrand2354d3e2020-10-24 20:17:10 +0200252 void create(std::vector<uint32_t> &counterConfigs, bool enableCycleCounter);
253 std::vector<uint32_t> initializeCounterConfig();
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200254
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200255 int fd;
Per Åstrandafb399f2021-11-26 12:50:35 +0100256 const std::shared_ptr<Network> network;
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200257 std::vector<std::shared_ptr<Buffer>> ifmBuffers;
258 std::vector<std::shared_ptr<Buffer>> ofmBuffers;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200259};
260
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200261} // namespace EthosU