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_HARDWARE_V1_0_HEXAGON_MODEL_H 18 #define ANDROID_HARDWARE_V1_0_HEXAGON_MODEL_H 19 20 #include <android/hardware/neuralnetworks/1.0/types.h> 21 #include <atomic> 22 #include <string> 23 #include <vector> 24 #include "CpuExecutor.h" 25 #include "HexagonController.h" 26 #include "HexagonOperations.h" 27 #include "HexagonUtils.h" 28 #include "OperationsUtils.h" 29 #include "hexagon_nn_controller/hexagon_nn_controller.h" 30 31 namespace android { 32 namespace hardware { 33 namespace neuralnetworks { 34 namespace V1_0 { 35 namespace implementation { 36 namespace hexagon { 37 38 using ::android::nn::RunTimePoolInfo; 39 using ::android::nn::Shape; 40 41 using NeuralnetworksModel = ::android::hardware::neuralnetworks::V1_0::Model; 42 43 // runtime operand information 44 struct OperandInfo { 45 // tensor information 46 OperandType type; 47 std::vector<uint32_t> dimensions; 48 49 // (optional) quantization paramters 50 float scale; 51 int32_t zeroPoint; 52 53 // lifetime 54 OperandLifeTime lifetime; 55 56 // data location 57 uint8_t* buffer; 58 uint32_t length; 59 60 // Hexagon nnlib identifiers 61 hexagon_nn_input hexagon_input; 62 hexagon_nn_input hexagon_input_min; 63 hexagon_nn_input hexagon_input_max; 64 hexagon_nn_output hexagon_output; 65 }; 66 67 // interface wrapper 68 class Model { 69 public: 70 // methods 71 Model() = delete; 72 Model(const Model&) = delete; 73 Model& operator=(const Model&) = delete; 74 Model(Model&& other); 75 Model& operator=(Model&& other); 76 77 Model(const NeuralnetworksModel& model); 78 ~Model(); 79 80 std::string getLog(); 81 std::string getGraph(); 82 83 // model check 84 const int32_t* getPointer(uint32_t operand); 85 Shape getShape(uint32_t operand); 86 bool setShape(uint32_t operand, const Shape& shape); 87 bool isConstant(uint32_t operand); 88 89 // model prepare types 90 const hexagon_nn_input& getTensor(uint32_t operand); 91 const hexagon_nn_input& getQuantizationMin(uint32_t operand); 92 const hexagon_nn_input& getQuantizationMax(uint32_t operand); 93 hexagon_nn_input createQuantizationValue(uint32_t operand, int32_t quant_value); 94 hexagon_nn_input createConvFilterTensor(uint32_t operand); 95 hexagon_nn_input createDepthwiseFilterTensor(uint32_t operand, int32_t depth_multiplier); 96 hexagon_nn_input createFullyConnectedWeightTensor(uint32_t operand); 97 template <typename Type> 98 Type getScalar(uint32_t operand); 99 op_type getFloatActivation(uint32_t operand); 100 op_type getQuantizedActivation(uint32_t operand); 101 hexagon_nn_padding_type getPadding(uint32_t operand); 102 103 template <typename Type> 104 hexagon_nn_input createTensor(uint32_t B, uint32_t H, uint32_t W, uint32_t D, 105 const std::vector<Type>& values); 106 hexagon_nn_input createShape(uint32_t B, uint32_t H, uint32_t W, uint32_t D); 107 template <typename Type> 108 hexagon_nn_input createValues(const std::vector<Type>& values); 109 template <typename Type> 110 hexagon_nn_input createScalar(Type value); 111 112 // model prepare operations 113 bool addBasicOperation(op_type op, hexagon_nn_padding_type pad, 114 const std::vector<hexagon_nn_input>& inputs, 115 const std::vector<uint32_t>& outputs); 116 bool addFloatOperationWithActivation(op_type op, hexagon_nn_padding_type pad, 117 op_type activation, 118 const std::vector<hexagon_nn_input>& inputs, 119 const std::vector<uint32_t>& outputs); 120 bool addQuant8OperationWithActivation(op_type op, hexagon_nn_padding_type pad, 121 op_type activation, 122 const std::vector<hexagon_nn_input>& inputs, 123 const std::vector<uint32_t>& outputs); 124 bool addFusedFloatOperation(op_type op, hexagon_nn_padding_type pad, 125 const hexagon_nn_input& bias, op_type activation, 126 const std::vector<hexagon_nn_input>& inputs, 127 const std::vector<uint32_t>& outputs); 128 bool addFusedQuant8Operation(op_type op, hexagon_nn_padding_type pad, 129 const std::vector<hexagon_nn_input>& bias, op_type activation, 130 const std::vector<hexagon_nn_input>& inputs, 131 const std::vector<uint32_t>& outputs); 132 133 std::vector<bool> supportedOperations(); 134 bool prepare(); 135 bool execute(const Request& request); 136 137 private: 138 uint32_t getNextNode(); 139 uint32_t addOperationInternal(op_type op, hexagon_nn_padding_type pad, 140 const std::vector<hexagon_nn_input>& inputs, 141 const std::vector<hexagon_nn_output>& outputs); 142 hexagon_nn_input createTensorInternal(uint32_t B, uint32_t H, uint32_t W, uint32_t D, 143 const uint8_t* ptr, size_t size); 144 std::vector<hexagon_nn_input> setupActivationArgs(op_type op); 145 hexagon_nn_input addOperand(uint32_t operand); 146 std::vector<hexagon_nn_output> getHexagonOutputs(const std::vector<uint32_t>& operands); 147 bool registerHexagonInputs(const std::vector<uint32_t>& operands, uint32_t node); 148 149 bool verifyOperations(); 150 bool verifyOperands(); 151 bool addInputs(); 152 bool addOperations(); 153 bool addOutputs(); 154 155 void clearModel(); 156 157 // members 158 hexagon_nn_nn_id mGraphId; 159 uint32_t mNodeCount; 160 bool mCompiled; 161 std::vector<OperandInfo> mOperands; 162 std::vector<Operation> mOperations; 163 std::vector<uint32_t> mInputs; 164 std::vector<uint32_t> mOutputs; 165 std::vector<RunTimePoolInfo> mPools; 166 }; 167 168 // template implementations 169 170 template <typename Type> 171 Type Model::getScalar(uint32_t operand) { 172 return *reinterpret_cast<const Type*>(mOperands[operand].buffer); 173 } 174 175 template <typename Type> 176 hexagon_nn_input Model::createTensor(uint32_t B, uint32_t H, uint32_t W, uint32_t D, 177 const std::vector<Type>& values) { 178 return createTensorInternal(B, H, W, D, reinterpret_cast<const uint8_t*>(values.data()), 179 values.size() * sizeof(Type)); 180 } 181 182 template <typename Type> 183 hexagon_nn_input Model::createValues(const std::vector<Type>& values) { 184 return createTensor(1, 1, 1, values.size(), values); 185 } 186 187 template <typename Type> 188 hexagon_nn_input Model::createScalar(Type value) { 189 return createTensorInternal(1, 1, 1, 1, reinterpret_cast<uint8_t*>(&value), sizeof(Type)); 190 } 191 192 } // namespace hexagon 193 } // namespace implementation 194 } // namespace V1_0 195 } // namespace neuralnetworks 196 } // namespace hardware 197 } // namespace android 198 199 #endif // ANDROID_HARDWARE_V1_0_HEXAGON_MODEL_H 200