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.
sizeOfData(const Operand & 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
setFromIntList(hidl_vec<uint32_t> * vec,uint32_t count,const uint32_t * data)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
setFromIntList(std::vector<uint32_t> * vec,uint32_t count,const uint32_t * data)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
toString(uint32_t obj)126 inline std::string toString(uint32_t obj) {
127 return std::to_string(obj);
128 }
129
130 template <typename Type>
toString(const std::vector<Type> & range)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
validCode(uint32_t codeCount,uint32_t codeCountOEM,uint32_t code)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
getSizeFromInts(int lower,int higher)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