Home | History | Annotate | Download | only in include
      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