blob: 74f8abb24dc31f0465d6dde9b12c82eb7ea43068 [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#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
Kristofer Jonsson79689c52020-10-16 14:42:19 +020043class Exception : public std::exception {
Kristofer Jonsson116a6352020-08-20 17:25:23 +020044public:
45 Exception(const char *msg);
46 virtual ~Exception() throw();
47 virtual const char *what() const throw();
48
49private:
50 std::string msg;
51};
52
Davide Grohmann35ce6c82021-06-01 15:03:51 +020053/**
54 * Sematic Version : major.minor.patch
55 */
56class SemanticVersion {
57public:
58 SemanticVersion(uint32_t _major = 0, uint32_t _minor = 0, uint32_t _patch = 0) :
59 major(_major), minor(_minor), patch(_patch){};
60
61 bool operator==(const SemanticVersion &other);
62 bool operator<(const SemanticVersion &other);
63 bool operator<=(const SemanticVersion &other);
64 bool operator!=(const SemanticVersion &other);
65 bool operator>(const SemanticVersion &other);
66 bool operator>=(const SemanticVersion &other);
67
68 uint32_t major;
69 uint32_t minor;
70 uint32_t patch;
71};
72
73std::ostream &operator<<(std::ostream &out, const SemanticVersion &v);
74
75/*
76 * Hardware Identifier
77 * @versionStatus: Version status
78 * @version: Version revision
79 * @product: Product revision
80 * @architecture: Architecture revison
81 */
82struct HardwareId {
83public:
Davide Grohmannf0364232022-06-16 17:42:58 +020084 HardwareId(uint32_t _versionStatus = 0,
85 const SemanticVersion &_version = SemanticVersion(),
86 const SemanticVersion &_product = SemanticVersion(),
87 const SemanticVersion &_architecture = SemanticVersion()) :
Davide Grohmann35ce6c82021-06-01 15:03:51 +020088 versionStatus(_versionStatus),
89 version(_version), product(_product), architecture(_architecture) {}
90
91 uint32_t versionStatus;
92 SemanticVersion version;
93 SemanticVersion product;
94 SemanticVersion architecture;
95};
96
97/*
98 * Hardware Configuration
99 * @macsPerClockCycle: MACs per clock cycle
100 * @cmdStreamVersion: NPU command stream version
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200101 * @customDma: Custom DMA enabled
102 */
103struct HardwareConfiguration {
104public:
Davide Grohmannf0364232022-06-16 17:42:58 +0200105 HardwareConfiguration(uint32_t _macsPerClockCycle = 0, uint32_t _cmdStreamVersion = 0, bool _customDma = false) :
Davide Grohmann40e23d12021-06-17 09:59:40 +0200106 macsPerClockCycle(_macsPerClockCycle), cmdStreamVersion(_cmdStreamVersion), customDma(_customDma) {}
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200107
108 uint32_t macsPerClockCycle;
109 uint32_t cmdStreamVersion;
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200110 bool customDma;
111};
112
113/**
114 * Device capabilities
115 * @hwId: Hardware
116 * @driver: Driver revision
117 * @hwCfg Hardware configuration
118 */
119class Capabilities {
120public:
Davide Grohmannf0364232022-06-16 17:42:58 +0200121 Capabilities() {}
Davide Grohmann35ce6c82021-06-01 15:03:51 +0200122 Capabilities(const HardwareId &_hwId, const HardwareConfiguration &_hwCfg, const SemanticVersion &_driver) :
123 hwId(_hwId), hwCfg(_hwCfg), driver(_driver) {}
124
125 HardwareId hwId;
126 HardwareConfiguration hwCfg;
127 SemanticVersion driver;
128};
129
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200130class Device {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200131public:
132 Device(const char *device = "/dev/ethosu0");
Davide Grohmannfc495592022-04-25 15:27:52 +0200133 virtual ~Device() noexcept(false);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200134
Per Åstrandafb399f2021-11-26 12:50:35 +0100135 int ioctl(unsigned long cmd, void *data = nullptr) const;
136 Capabilities capabilities() const;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200137
138private:
139 int fd;
140};
141
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200142class Buffer {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200143public:
Per Åstrandafb399f2021-11-26 12:50:35 +0100144 Buffer(const Device &device, const size_t capacity);
Davide Grohmannfc495592022-04-25 15:27:52 +0200145 virtual ~Buffer() noexcept(false);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200146
147 size_t capacity() const;
Per Åstrandafb399f2021-11-26 12:50:35 +0100148 void clear() const;
149 char *data() const;
150 void resize(size_t size, size_t offset = 0) const;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200151 size_t offset() const;
152 size_t size() const;
153
154 int getFd() const;
155
156private:
157 int fd;
158 char *dataPtr;
159 const size_t dataCapacity;
160};
161
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200162class Network {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200163public:
Per Åstrandafb399f2021-11-26 12:50:35 +0100164 Network(const Device &device, std::shared_ptr<Buffer> &buffer);
Kristofer Jonsson3c6a2602022-03-10 11:17:29 +0100165 Network(const Device &device, const unsigned index);
Davide Grohmannfc495592022-04-25 15:27:52 +0200166 virtual ~Network() noexcept(false);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200167
168 int ioctl(unsigned long cmd, void *data = nullptr);
169 std::shared_ptr<Buffer> getBuffer();
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200170 const std::vector<size_t> &getIfmDims() const;
171 size_t getIfmSize() const;
172 const std::vector<size_t> &getOfmDims() const;
173 size_t getOfmSize() const;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200174
175private:
Davide Grohmann80f8ddf2022-04-07 14:50:50 +0200176 void collectNetworkInfo();
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100177
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200178 int fd;
179 std::shared_ptr<Buffer> buffer;
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200180 std::vector<size_t> ifmDims;
181 std::vector<size_t> ofmDims;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200182};
183
Davide Grohmann82d22582022-04-25 12:52:38 +0200184enum class InferenceStatus {
185 OK,
186 ERROR,
187 RUNNING,
188 REJECTED,
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100189 ABORTED,
190 ABORTING,
Davide Grohmann82d22582022-04-25 12:52:38 +0200191};
192
193std::ostream &operator<<(std::ostream &out, const InferenceStatus &v);
194
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200195class Inference {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200196public:
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200197 template <typename T>
Per Åstrandafb399f2021-11-26 12:50:35 +0100198 Inference(const std::shared_ptr<Network> &network,
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200199 const T &ifmBegin,
200 const T &ifmEnd,
201 const T &ofmBegin,
202 const T &ofmEnd) :
203 network(network) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200204 std::copy(ifmBegin, ifmEnd, std::back_inserter(ifmBuffers));
205 std::copy(ofmBegin, ofmEnd, std::back_inserter(ofmBuffers));
Per Åstrand2354d3e2020-10-24 20:17:10 +0200206 std::vector<uint32_t> counterConfigs = initializeCounterConfig();
207
208 create(counterConfigs, false);
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200209 }
Per Åstrand2354d3e2020-10-24 20:17:10 +0200210 template <typename T, typename U>
Per Åstrandafb399f2021-11-26 12:50:35 +0100211 Inference(const std::shared_ptr<Network> &network,
Per Åstrand2354d3e2020-10-24 20:17:10 +0200212 const T &ifmBegin,
213 const T &ifmEnd,
214 const T &ofmBegin,
215 const T &ofmEnd,
216 const U &counters,
217 bool enableCycleCounter) :
218 network(network) {
219 std::copy(ifmBegin, ifmEnd, std::back_inserter(ifmBuffers));
220 std::copy(ofmBegin, ofmEnd, std::back_inserter(ofmBuffers));
221 std::vector<uint32_t> counterConfigs = initializeCounterConfig();
222
223 if (counters.size() > counterConfigs.size())
224 throw EthosU::Exception("PMU Counters argument to large.");
225
226 std::copy(counters.begin(), counters.end(), counterConfigs.begin());
227 create(counterConfigs, enableCycleCounter);
228 }
229
Davide Grohmannfc495592022-04-25 15:27:52 +0200230 virtual ~Inference() noexcept(false);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200231
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100232 bool wait(int64_t timeoutNanos = -1) const;
Per Åstrandafb399f2021-11-26 12:50:35 +0100233 const std::vector<uint32_t> getPmuCounters() const;
234 uint64_t getCycleCounter() const;
Davide Grohmann7e8f5082022-03-23 12:48:45 +0100235 bool cancel() const;
Davide Grohmann82d22582022-04-25 12:52:38 +0200236 InferenceStatus status() const;
Per Åstrandafb399f2021-11-26 12:50:35 +0100237 int getFd() const;
238 const std::shared_ptr<Network> getNetwork() const;
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200239 std::vector<std::shared_ptr<Buffer>> &getIfmBuffers();
240 std::vector<std::shared_ptr<Buffer>> &getOfmBuffers();
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200241
Per Åstrand2354d3e2020-10-24 20:17:10 +0200242 static uint32_t getMaxPmuEventCounters();
243
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200244private:
Per Åstrand2354d3e2020-10-24 20:17:10 +0200245 void create(std::vector<uint32_t> &counterConfigs, bool enableCycleCounter);
246 std::vector<uint32_t> initializeCounterConfig();
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200247
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200248 int fd;
Per Åstrandafb399f2021-11-26 12:50:35 +0100249 const std::shared_ptr<Network> network;
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200250 std::vector<std::shared_ptr<Buffer>> ifmBuffers;
251 std::vector<std::shared_ptr<Buffer>> ofmBuffers;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200252};
253
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200254} // namespace EthosU