1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #ifndef ANDROID_ML_NN_COMMON_UTILS_H
18 #define ANDROID_ML_NN_COMMON_UTILS_H
19
20 #include "HalInterfaces.h"
21 #include "NeuralNetworks.h"
22
23 #include <android-base/logging.h>
24 #include <vector>
25
26 namespace android {
27 namespace nn {
28
29 // The number of data types (OperandCode) defined in NeuralNetworks.h.
30 const int kNumberOfDataTypes = 6;
31
32 // The number of operation types (OperationCode) defined in NeuralNetworks.h.
33 const int kNumberOfOperationTypes = 38;
34
35 // The number of execution preferences defined in NeuralNetworks.h.
36 const int kNumberOfPreferences = 3;
37
38 // The number of data types (OperandCode) defined in NeuralNetworksOEM.h.
39 const int kNumberOfDataTypesOEM = 2;
40
41 // The number of operation types (OperationCode) defined in NeuralNetworksOEM.h.
42 const int kNumberOfOperationTypesOEM = 1;
43
44 // The lowest number assigned to any OEM Code in NeuralNetworksOEM.h.
45 const int kOEMCodeBase = 10000;
46
47 /* IMPORTANT: if you change the following list, don't
48 * forget to update the corresponding 'tags' table in
49 * the initVlogMask() function implemented in Utils.cpp.
50 */
51 enum VLogFlags {
52 MODEL = 0,
53 COMPILATION,
54 EXECUTION,
55 CPUEXE,
56 MANAGER,
57 DRIVER
58 };
59
60 #define VLOG_IS_ON(TAG) \
61 ((vLogMask & (1 << (TAG))) != 0)
62
63 #define VLOG(TAG) \
64 if (LIKELY(!VLOG_IS_ON(TAG))) \
65 ; \
66 else \
67 LOG(INFO)
68
69 extern int vLogMask;
70 void initVLogMask();
71
72 #ifdef NN_DEBUGGABLE
73 #define SHOW_IF_DEBUG(msg) msg
74 #else
75 #define SHOW_IF_DEBUG(msg) ""
76 #endif
77
78 // Assert macro, as Android does not generally support assert.
79 #define nnAssert(v) \
80 do { \
81 if (!(v)) { \
82 LOG(ERROR) << "nnAssert failed at " << __FILE__ << ":" << __LINE__ << " - '" << #v \
83 << "'\n"; \
84 abort(); \
85 } \
86 } while (0)
87
88 // Returns the amount of space needed to store a value of the specified
89 // dimensions and type.
90 uint32_t sizeOfData(OperandType type, const std::vector<uint32_t>& dimensions);
91
92 // Returns the amount of space needed to store a value of the dimensions and
93 // type of this operand.
sizeOfData(const Operand & operand)94 inline uint32_t sizeOfData(const Operand& operand) {
95 return sizeOfData(operand.type, operand.dimensions);
96 }
97
98 // Returns the name of the operation type in ASCII.
99 const char* getOperationName(OperationType opCode);
100
101 // Returns the name of the operand type in ASCII.
102 const char* getOperandTypeName(OperandType type);
103
104 // Memory is unmapped.
105 // Memory is reference counted by hidl_memory instances, and is deallocated
106 // once there are no more references.
107 hidl_memory allocateSharedMemory(int64_t size);
108
109 // Returns the number of padding bytes needed to align data of the
110 // specified length. It aligns object of length:
111 // 2, 3 on a 2 byte boundary,
112 // 4+ on a 4 byte boundary.
113 // We may want to have different alignments for tensors.
114 // TODO: This is arbitrary, more a proof of concept. We need
115 // to determine what this should be.
116 uint32_t alignBytesNeeded(uint32_t index, size_t length);
117
118 // Does a detailed LOG(INFO) of the model
119 void logModelToInfo(const V1_0::Model& model);
120 void logModelToInfo(const V1_1::Model& model);
121
toString(uint32_t obj)122 inline std::string toString(uint32_t obj) {
123 return std::to_string(obj);
124 }
125
126 template <typename Type>
toString(const std::vector<Type> & range)127 std::string toString(const std::vector<Type>& range) {
128 std::string os = "[";
129 for (size_t i = 0; i < range.size(); ++i) {
130 os += (i == 0 ? "" : ", ") + toString(range[i]);
131 }
132 return os += "]";
133 }
134
validCode(uint32_t codeCount,uint32_t codeCountOEM,uint32_t code)135 inline bool validCode(uint32_t codeCount, uint32_t codeCountOEM, uint32_t code) {
136 return (code < codeCount) || (code >= kOEMCodeBase && (code - kOEMCodeBase) < codeCountOEM);
137 }
138
139 int validateOperandType(const ANeuralNetworksOperandType& type, const char* tag, bool allowPartial);
140 int validateOperandList(uint32_t count, const uint32_t* list, uint32_t operandCount,
141 const char* tag);
142 int validateOperation(ANeuralNetworksOperationType opType,
143 uint32_t inputCount, const uint32_t* inputIndexes,
144 uint32_t outputCount, const uint32_t* outputIndexes,
145 const std::vector<Operand>& operands);
146
getSizeFromInts(int lower,int higher)147 inline size_t getSizeFromInts(int lower, int higher) {
148 return (uint32_t)(lower) + ((uint64_t)(uint32_t)(higher) << 32);
149 }
150
151 // Convert ANEURALNETWORKS_* result code to ErrorStatus.
152 // Not guaranteed to be a 1-to-1 mapping.
153 ErrorStatus convertResultCodeToErrorStatus(int resultCode);
154
155 // Convert ErrorStatus to ANEURALNETWORKS_* result code.
156 // Not guaranteed to be a 1-to-1 mapping.
157 int convertErrorStatusToResultCode(ErrorStatus status);
158
159 // Versioning
160
161 bool compliantWithV1_0(V1_0::OperationType type);
162 bool compliantWithV1_0(V1_1::OperationType type);
163 bool compliantWithV1_1(V1_0::OperationType type);
164 bool compliantWithV1_1(V1_1::OperationType type);
165
166 bool compliantWithV1_0(const V1_0::Capabilities& capabilities);
167 bool compliantWithV1_0(const V1_1::Capabilities& capabilities);
168 bool compliantWithV1_1(const V1_0::Capabilities& capabilities);
169 bool compliantWithV1_1(const V1_1::Capabilities& capabilities);
170
171 bool compliantWithV1_0(const V1_0::Operation& operation);
172 bool compliantWithV1_0(const V1_1::Operation& operation);
173 bool compliantWithV1_1(const V1_0::Operation& operation);
174 bool compliantWithV1_1(const V1_1::Operation& operation);
175
176 bool compliantWithV1_0(const V1_0::Model& model);
177 bool compliantWithV1_0(const V1_1::Model& model);
178 bool compliantWithV1_1(const V1_0::Model& model);
179 bool compliantWithV1_1(const V1_1::Model& model);
180
181 V1_0::OperationType convertToV1_0(V1_0::OperationType type);
182 V1_0::OperationType convertToV1_0(V1_1::OperationType type);
183 V1_1::OperationType convertToV1_1(V1_0::OperationType type);
184 V1_1::OperationType convertToV1_1(V1_1::OperationType type);
185
186 V1_0::Capabilities convertToV1_0(const V1_0::Capabilities& capabilities);
187 V1_0::Capabilities convertToV1_0(const V1_1::Capabilities& capabilities);
188 V1_1::Capabilities convertToV1_1(const V1_0::Capabilities& capabilities);
189 V1_1::Capabilities convertToV1_1(const V1_1::Capabilities& capabilities);
190
191 V1_0::Operation convertToV1_0(const V1_0::Operation& operation);
192 V1_0::Operation convertToV1_0(const V1_1::Operation& operation);
193 V1_1::Operation convertToV1_1(const V1_0::Operation& operation);
194 V1_1::Operation convertToV1_1(const V1_1::Operation& operation);
195
196 V1_0::Model convertToV1_0(const V1_0::Model& model);
197 V1_0::Model convertToV1_0(const V1_1::Model& model);
198 V1_1::Model convertToV1_1(const V1_0::Model& model);
199 V1_1::Model convertToV1_1(const V1_1::Model& model);
200
201
202 #ifdef NN_DEBUGGABLE
203 uint32_t getProp(const char* str, uint32_t defaultValue = 0);
204 #endif // NN_DEBUGGABLE
205
206 } // namespace nn
207 } // namespace android
208
209 #endif // ANDROID_ML_NN_COMMON_UTILS_H
210