1%% template file for generating Types.h.
2%% see README.md.
3/*
4 * Copyright (C) 2020 The Android Open Source Project
5 *
6 * Licensed under the Apache License, Version 2.0 (the "License");
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
9 *
10 *      http://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,
14 * WITHOUT 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#ifndef ANDROID_PACKAGES_MODULES_NEURALNETWORKS_COMMON_TYPES_NNAPI_TYPES_H
20#define ANDROID_PACKAGES_MODULES_NEURALNETWORKS_COMMON_TYPES_NNAPI_TYPES_H
21
22#include <android-base/chrono_utils.h>
23#include <android-base/expected.h>
24#include <android-base/unique_fd.h>
25
26#include <array>
27#include <chrono>
28#include <functional>
29#include <limits>
30#include <memory>
31#include <optional>
32#include <string>
33#include <type_traits>
34#include <utility>
35#include <variant>
36#include <vector>
37
38#include "nnapi/OperandTypes.h"
39#include "nnapi/OperationTypes.h"
40#include "nnapi/Result.h"
41
42// Forward declare AHardwareBuffer
43extern "C" typedef struct AHardwareBuffer AHardwareBuffer;
44
45namespace android::nn {
46
47// Forward declarations
48
49class IBuffer;
50class IBurst;
51class IDevice;
52class IExecution;
53class IPreparedModel;
54struct Memory;
55
56// Constants
57
58constexpr float kDefaultExecTime = std::numeric_limits<float>::max();
59constexpr float kDefaultPowerUsage = std::numeric_limits<float>::max();
60constexpr uint32_t kByteSizeOfCacheToken = 32;
61constexpr uint32_t kMaxNumberOfCacheFiles = 32;
62
63%insert ExtensionTypeEncoding
64
65constexpr uint32_t kDefaultRequestMemoryAlignment = 64;
66constexpr uint32_t kDefaultRequestMemoryPadding = 64;
67constexpr uint32_t kMinMemoryAlignment = alignof(std::max_align_t);
68constexpr uint32_t kMinMemoryPadding = 1;
69constexpr auto kLoopTimeoutDefault = std::chrono::seconds{2};
70constexpr auto kLoopTimeoutMaximum = std::chrono::seconds{15};
71
72// Aliases
73
74using SharedBuffer = std::shared_ptr<const IBuffer>;
75using SharedBurst = std::shared_ptr<const IBurst>;
76using SharedDevice = std::shared_ptr<const IDevice>;
77using SharedExecution = std::shared_ptr<const IExecution>;
78using SharedMemory = std::shared_ptr<const Memory>;
79using SharedPreparedModel = std::shared_ptr<const IPreparedModel>;
80
81// Canonical types
82
83%insert DeviceStatus
84
85%insert ExecutionPreference
86
87%insert DeviceType
88
89%insert MeasureTiming
90
91%insert Priority
92
93// TODO: Should more errors from NeuralNetworks.h be incorporated? The left name shows errors that
94// appear in NeuralNetworks.h but not in the HAL, and the right column shows what these values could
95// map to:
96// * OUT_OF_MEMORY ==> GENERAL_FAILURE / RESOURCE_EXHAUSTED_*
97// * INCOMPLETE ==> GENERAL_FAILURE
98// * UNEXPECTED_NULL ==> INVALID_ARGUMENT
99// * UNMAPPABLE ==> GENERAL_FAILURE
100// * BAD_STATE ==> INVALID_ARGUMENT
101enum class ErrorStatus {
102    NONE = 0,
103    DEVICE_UNAVAILABLE = 1,
104    GENERAL_FAILURE = 2,
105    OUTPUT_INSUFFICIENT_SIZE = 3,
106    INVALID_ARGUMENT = 4,
107    MISSED_DEADLINE_TRANSIENT = 5,
108    MISSED_DEADLINE_PERSISTENT = 6,
109    RESOURCE_EXHAUSTED_TRANSIENT = 7,
110    RESOURCE_EXHAUSTED_PERSISTENT = 8,
111    DEAD_OBJECT = 10000,
112};
113
114struct GeneralError {
115    // NOLINTNEXTLINE(google-explicit-constructor)
116    /*implicit*/ GeneralError(std::string message = {},
117                              ErrorStatus code = ErrorStatus::GENERAL_FAILURE);
118
119    std::string message;
120    ErrorStatus code;
121};
122
123template <typename Type>
124using GeneralResult = base::expected<Type, GeneralError>;
125
126%insert FusedActivationFunc
127
128using Dimension = uint32_t;
129using Dimensions = std::vector<Dimension>;
130
131using CacheToken = std::array<uint8_t, kByteSizeOfCacheToken>;
132
133%insert OutputShape
134
135struct ExecutionError {
136    // NOLINTNEXTLINE(google-explicit-constructor)
137    /*implicit*/ ExecutionError(std::string message = {},
138                                ErrorStatus code = ErrorStatus::GENERAL_FAILURE,
139                                std::vector<OutputShape> outputShapes = {});
140
141    // NOLINTNEXTLINE(google-explicit-constructor)
142    /*implicit*/ ExecutionError(GeneralError error);
143
144    std::string message;
145    ErrorStatus code;
146    // OutputShapes for code == OUTPUT_INSUFFICIENT_SIZE
147    std::vector<OutputShape> outputShapes;
148};
149
150template <typename Type>
151using ExecutionResult = base::expected<Type, ExecutionError>;
152
153%insert Capabilities
154
155%insert Extension
156
157%insert Operation
158
159%insert DataLocation
160
161%insert Operand
162
163using Handle = base::unique_fd;
164using SharedHandle = std::shared_ptr<const Handle>;
165
166struct Memory {
167    struct Ashmem {
168        base::unique_fd fd;
169        size_t size;
170    };
171
172    struct Fd {
173        size_t size;
174        int prot;
175        base::unique_fd fd;
176        size_t offset;
177    };
178
179    // RAII wrapper for AHardwareBuffer
180    struct HardwareBuffer {
181        using Deleter = std::add_pointer_t<void(AHardwareBuffer*)>;
182        using Handle = std::unique_ptr<AHardwareBuffer, Deleter>;
183        Handle handle;
184    };
185
186    struct Unknown {
187        struct Handle {
188            std::vector<base::unique_fd> fds;
189            std::vector<int> ints;
190        };
191        Handle handle;
192        size_t size;
193        std::string name;
194    };
195
196    std::variant<Ashmem, Fd, HardwareBuffer, Unknown> handle;
197};
198
199%insert ExtensionNameAndPrefix
200
201%insert Model
202
203%insert BufferDesc
204
205%insert BufferRole
206
207%insert Request
208
209// Representation of sync_fence.
210class SyncFence {
211   public:
212    static SyncFence createAsSignaled();
213    static SyncFence create(base::unique_fd fd);
214    static Result<SyncFence> create(SharedHandle syncFence);
215
216    // The function syncWait() has the same semantics as the system function
217    // ::sync_wait(), except that the syncWait() return value is semantically
218    // richer.
219    enum class FenceState {
220        ACTIVE,    // fence has not been signaled
221        SIGNALED,  // fence has been signaled
222        ERROR,     // fence has been placed in the error state
223        UNKNOWN,   // either bad argument passed to syncWait(), or internal error
224    };
225    using Timeout = std::chrono::duration<int, std::milli>;
226    using OptionalTimeout = std::optional<Timeout>;
227
228    FenceState syncWait(OptionalTimeout optionalTimeout) const;
229
230    SharedHandle getSharedHandle() const;
231    bool hasFd() const;
232    int getFd() const;
233
234   private:
235    explicit SyncFence(SharedHandle syncFence);
236
237    SharedHandle mSyncFence;
238};
239
240using Clock = base::boot_clock;
241
242using Duration = std::chrono::nanoseconds;
243using OptionalDuration = std::optional<Duration>;
244
245using TimePoint = std::chrono::time_point<Clock, Duration>;
246using OptionalTimePoint = std::optional<TimePoint>;
247
248%insert Timing
249
250// Returns status, timingLaunched, timingFenced
251using ExecuteFencedInfoCallback = std::function<GeneralResult<std::pair<Timing, Timing>>()>;
252
253// Version is a tuple that contains what NNAPI feature level is supported/required and whether
254// runtime-only features are supported/required.
255struct Version {
256    enum class Level : uint8_t {
257        FEATURE_LEVEL_1,
258        FEATURE_LEVEL_2,
259        FEATURE_LEVEL_3,
260        FEATURE_LEVEL_4,
261        FEATURE_LEVEL_5,
262        FEATURE_LEVEL_6,
263        FEATURE_LEVEL_7,
264        FEATURE_LEVEL_8,
265#ifdef NN_EXPERIMENTAL_FEATURE
266        FEATURE_LEVEL_EXPERIMENTAL,
267#endif  // NN_EXPERIMENTAL_FEATURE
268    };
269
270    Level level;
271    bool runtimeOnlyFeatures = false;
272};
273
274constexpr auto kVersionFeatureLevel1 = Version{.level = Version::Level::FEATURE_LEVEL_1};
275constexpr auto kVersionFeatureLevel2 = Version{.level = Version::Level::FEATURE_LEVEL_2};
276constexpr auto kVersionFeatureLevel3 = Version{.level = Version::Level::FEATURE_LEVEL_3};
277constexpr auto kVersionFeatureLevel4 = Version{.level = Version::Level::FEATURE_LEVEL_4};
278constexpr auto kVersionFeatureLevel5 = Version{.level = Version::Level::FEATURE_LEVEL_5};
279constexpr auto kVersionFeatureLevel6 = Version{.level = Version::Level::FEATURE_LEVEL_6};
280constexpr auto kVersionFeatureLevel7 = Version{.level = Version::Level::FEATURE_LEVEL_7};
281constexpr auto kVersionFeatureLevel8 = Version{.level = Version::Level::FEATURE_LEVEL_8};
282#ifdef NN_EXPERIMENTAL_FEATURE
283constexpr auto kVersionFeatureLevelExperimental =
284        Version{.level = Version::Level::FEATURE_LEVEL_EXPERIMENTAL};
285#endif  // NN_EXPERIMENTAL_FEATURE
286
287// Describes the memory preference of an operand.
288struct MemoryPreference {
289    // Must be a power of 2.
290    // For pointer buffers, the alignment is satisfied if the address of the pointer is a multiple
291    // of the "alignment" value. For memory pools, the alignment is satisfied if the offset of the
292    // sub-region specified by DataLocation is a multiple of the "alignment" value.
293    uint32_t alignment;
294    // Must be a power of 2.
295    // For both pointer buffers and memory pools, the padding is satisfied if the padded length is
296    // greater than or equal to the raw size of the operand (i.e. the size of an element multiplied
297    // by the number of elements) rounding up to a multiple of the "padding" value. In DataLocation,
298    // the padded length equals to the sum of the length and padding fields.
299    uint32_t padding;
300};
301
302/**
303 * A type that is used to represent a token / byte array data pair.
304 */
305struct TokenValuePair {
306    /**
307     * A 32bit integer token. The token is created by combining the
308     * extension prefix and enum defined within the extension. Of the 32 bits in the token, the high
309     * kExtensionPrefixBits bits is the extension prefix and the low kExtensionTypeBits bits
310     * represents the enum within the extension.
311     *
312     * For example, if a token value is 0x7AAA000B and corresponding {@link ExtensionNameAndPrefix}
313     * contains an entry with prefix=0x7AAA and name="vendor.test.test_extension", then the token
314     * should be interpreted as the enum value 0x000B of the extension named
315     * vendor.test.test_extension.
316     */
317    int32_t token;
318    /**
319     * A byte array containing the raw data.
320     */
321    std::vector<uint8_t> value;
322};
323
324}  // namespace android::nn
325
326#endif  // ANDROID_PACKAGES_MODULES_NEURALNETWORKS_COMMON_TYPES_NNAPI_TYPES_H
327