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. 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 122 inline std::string toString(uint32_t obj) { 123 return std::to_string(obj); 124 } 125 126 template <typename Type> 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 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 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