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 = 30; 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 // Assert macro, as Android does not generally support assert. 73 #define nnAssert(v) \ 74 do { \ 75 if (!(v)) { \ 76 LOG(ERROR) << "nnAssert failed at " << __FILE__ << ":" << __LINE__ << " - '" << #v \ 77 << "'\n"; \ 78 abort(); \ 79 } \ 80 } while (0) 81 82 // Returns the amount of space needed to store a value of the specified 83 // dimensions and type. 84 uint32_t sizeOfData(OperandType type, const std::vector<uint32_t>& dimensions); 85 86 // Returns the amount of space needed to store a value of the dimensions and 87 // type of this operand. 88 inline uint32_t sizeOfData(const Operand& operand) { 89 return sizeOfData(operand.type, operand.dimensions); 90 } 91 92 // Returns the name of the operation in ASCII. 93 const char* getOperationName(OperationType opCode); 94 95 // Memory is unmapped. 96 // Memory is reference counted by hidl_memory instances, and is deallocated 97 // once there are no more references. 98 hidl_memory allocateSharedMemory(int64_t size); 99 100 // Returns the number of padding bytes needed to align data of the 101 // specified length. It aligns object of length: 102 // 2, 3 on a 2 byte boundary, 103 // 4+ on a 4 byte boundary. 104 // We may want to have different alignments for tensors. 105 // TODO: This is arbitrary, more a proof of concept. We need 106 // to determine what this should be. 107 uint32_t alignBytesNeeded(uint32_t index, size_t length); 108 109 // Does a detailed LOG(INFO) of the model 110 void logModelToInfo(const Model& model); 111 112 inline void setFromIntList(hidl_vec<uint32_t>* vec, uint32_t count, const uint32_t* data) { 113 vec->resize(count); 114 for (uint32_t i = 0; i < count; i++) { 115 (*vec)[i] = data[i]; 116 } 117 } 118 119 inline void setFromIntList(std::vector<uint32_t>* vec, uint32_t count, const uint32_t* data) { 120 vec->resize(count); 121 for (uint32_t i = 0; i < count; i++) { 122 (*vec)[i] = data[i]; 123 } 124 } 125 126 inline std::string toString(uint32_t obj) { 127 return std::to_string(obj); 128 } 129 130 template <typename Type> 131 std::string toString(const std::vector<Type>& range) { 132 std::string os = "["; 133 for (size_t i = 0; i < range.size(); ++i) { 134 os += (i == 0 ? "" : ", ") + toString(range[i]); 135 } 136 return os += "]"; 137 } 138 139 inline bool validCode(uint32_t codeCount, uint32_t codeCountOEM, uint32_t code) { 140 return (code < codeCount) || (code >= kOEMCodeBase && (code - kOEMCodeBase) < codeCountOEM); 141 } 142 143 int validateOperandType(const ANeuralNetworksOperandType& type, const char* tag, bool allowPartial); 144 int validateOperandList(uint32_t count, const uint32_t* list, uint32_t operandCount, 145 const char* tag); 146 bool validateModel(const Model& model); 147 bool validateRequest(const Request& request, const Model& model); 148 149 inline size_t getSizeFromInts(int lower, int higher) { 150 return (uint32_t)(lower) + ((uint64_t)(uint32_t)(higher) << 32); 151 } 152 153 #ifdef NN_DEBUGGABLE 154 uint32_t getProp(const char* str, uint32_t defaultValue = 0); 155 #endif // NN_DEBUGGABLE 156 157 } // namespace nn 158 } // namespace android 159 160 #endif // ANDROID_ML_NN_COMMON_UTILS_H 161