blob: 547e3469e1e8a6f846e29b7abc41a4adb6069875 [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:
84 HardwareId(uint32_t _versionStatus,
85 const SemanticVersion &_version,
86 const SemanticVersion &_product,
87 const SemanticVersion &_architecture) :
88 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 Grohmann40e23d12021-06-17 09:59:40 +0200105 HardwareConfiguration(uint32_t _macsPerClockCycle, uint32_t _cmdStreamVersion, bool _customDma) :
106 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:
121 Capabilities(const HardwareId &_hwId, const HardwareConfiguration &_hwCfg, const SemanticVersion &_driver) :
122 hwId(_hwId), hwCfg(_hwCfg), driver(_driver) {}
123
124 HardwareId hwId;
125 HardwareConfiguration hwCfg;
126 SemanticVersion driver;
127};
128
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200129class Device {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200130public:
131 Device(const char *device = "/dev/ethosu0");
132 virtual ~Device();
133
Per Åstrandafb399f2021-11-26 12:50:35 +0100134 int ioctl(unsigned long cmd, void *data = nullptr) const;
135 Capabilities capabilities() const;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200136
137private:
138 int fd;
139};
140
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200141class Buffer {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200142public:
Per Åstrandafb399f2021-11-26 12:50:35 +0100143 Buffer(const Device &device, const size_t capacity);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200144 virtual ~Buffer();
145
146 size_t capacity() const;
Per Åstrandafb399f2021-11-26 12:50:35 +0100147 void clear() const;
148 char *data() const;
149 void resize(size_t size, size_t offset = 0) const;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200150 size_t offset() const;
151 size_t size() const;
152
153 int getFd() const;
154
155private:
156 int fd;
157 char *dataPtr;
158 const size_t dataCapacity;
159};
160
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200161class Network {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200162public:
Per Åstrandafb399f2021-11-26 12:50:35 +0100163 Network(const Device &device, std::shared_ptr<Buffer> &buffer);
Kristofer Jonsson3c6a2602022-03-10 11:17:29 +0100164 Network(const Device &device, const unsigned index);
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200165 virtual ~Network();
166
167 int ioctl(unsigned long cmd, void *data = nullptr);
168 std::shared_ptr<Buffer> getBuffer();
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200169 const std::vector<size_t> &getIfmDims() const;
170 size_t getIfmSize() const;
171 const std::vector<size_t> &getOfmDims() const;
172 size_t getOfmSize() const;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200173
174private:
Davide Grohmann80f8ddf2022-04-07 14:50:50 +0200175 void collectNetworkInfo();
Kristofer Jonsson35de9e62022-03-08 13:25:45 +0100176
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200177 int fd;
178 std::shared_ptr<Buffer> buffer;
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200179 std::vector<size_t> ifmDims;
180 std::vector<size_t> ofmDims;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200181};
182
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200183class Inference {
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200184public:
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200185 template <typename T>
Per Åstrandafb399f2021-11-26 12:50:35 +0100186 Inference(const std::shared_ptr<Network> &network,
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200187 const T &ifmBegin,
188 const T &ifmEnd,
189 const T &ofmBegin,
190 const T &ofmEnd) :
191 network(network) {
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200192 std::copy(ifmBegin, ifmEnd, std::back_inserter(ifmBuffers));
193 std::copy(ofmBegin, ofmEnd, std::back_inserter(ofmBuffers));
Per Åstrand2354d3e2020-10-24 20:17:10 +0200194 std::vector<uint32_t> counterConfigs = initializeCounterConfig();
195
196 create(counterConfigs, false);
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200197 }
Per Åstrand2354d3e2020-10-24 20:17:10 +0200198 template <typename T, typename U>
Per Åstrandafb399f2021-11-26 12:50:35 +0100199 Inference(const std::shared_ptr<Network> &network,
Per Åstrand2354d3e2020-10-24 20:17:10 +0200200 const T &ifmBegin,
201 const T &ifmEnd,
202 const T &ofmBegin,
203 const T &ofmEnd,
204 const U &counters,
205 bool enableCycleCounter) :
206 network(network) {
207 std::copy(ifmBegin, ifmEnd, std::back_inserter(ifmBuffers));
208 std::copy(ofmBegin, ofmEnd, std::back_inserter(ofmBuffers));
209 std::vector<uint32_t> counterConfigs = initializeCounterConfig();
210
211 if (counters.size() > counterConfigs.size())
212 throw EthosU::Exception("PMU Counters argument to large.");
213
214 std::copy(counters.begin(), counters.end(), counterConfigs.begin());
215 create(counterConfigs, enableCycleCounter);
216 }
217
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200218 virtual ~Inference();
219
Per Åstrandafb399f2021-11-26 12:50:35 +0100220 int wait(int64_t timeoutNanos = -1) const;
221 const std::vector<uint32_t> getPmuCounters() const;
222 uint64_t getCycleCounter() const;
223 bool failed() const;
224 int getFd() const;
225 const std::shared_ptr<Network> getNetwork() const;
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200226 std::vector<std::shared_ptr<Buffer>> &getIfmBuffers();
227 std::vector<std::shared_ptr<Buffer>> &getOfmBuffers();
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200228
Per Åstrand2354d3e2020-10-24 20:17:10 +0200229 static uint32_t getMaxPmuEventCounters();
230
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200231private:
Per Åstrand2354d3e2020-10-24 20:17:10 +0200232 void create(std::vector<uint32_t> &counterConfigs, bool enableCycleCounter);
233 std::vector<uint32_t> initializeCounterConfig();
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200234
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200235 int fd;
Per Åstrandafb399f2021-11-26 12:50:35 +0100236 const std::shared_ptr<Network> network;
Kristofer Jonssonb74492c2020-09-10 13:26:01 +0200237 std::vector<std::shared_ptr<Buffer>> ifmBuffers;
238 std::vector<std::shared_ptr<Buffer>> ofmBuffers;
Kristofer Jonsson116a6352020-08-20 17:25:23 +0200239};
240
Kristofer Jonsson79689c52020-10-16 14:42:19 +0200241} // namespace EthosU