├── .gitignore ├── .gitignore.license ├── 1.0 ├── ArmnnDriver.hpp ├── ArmnnDriverImpl.cpp ├── ArmnnDriverImpl.hpp ├── FullyConnected.hpp ├── HalPolicy.cpp └── HalPolicy.hpp ├── 1.1 ├── ArmnnDriver.hpp ├── ArmnnDriverImpl.cpp ├── ArmnnDriverImpl.hpp ├── HalPolicy.cpp └── HalPolicy.hpp ├── 1.2 ├── ArmnnDriver.hpp ├── ArmnnDriverImpl.cpp ├── ArmnnDriverImpl.hpp ├── HalPolicy.cpp └── HalPolicy.hpp ├── 1.3 ├── ArmnnDriver.hpp ├── ArmnnDriverImpl.cpp ├── ArmnnDriverImpl.hpp ├── HalPolicy.cpp └── HalPolicy.hpp ├── Android.bp ├── Android.mk ├── ArmnnDevice.cpp ├── ArmnnDevice.hpp ├── ArmnnDriver.hpp ├── ArmnnDriverImpl.cpp ├── ArmnnDriverImpl.hpp ├── ArmnnPreparedModel.cpp ├── ArmnnPreparedModel.hpp ├── ArmnnPreparedModel_1_2.cpp ├── ArmnnPreparedModel_1_2.hpp ├── ArmnnPreparedModel_1_3.cpp ├── ArmnnPreparedModel_1_3.hpp ├── CacheDataHandler.cpp ├── CacheDataHandler.hpp ├── ConversionUtils.cpp ├── ConversionUtils.hpp ├── ConversionUtils_1_2.hpp ├── ConversionUtils_1_3.hpp ├── DriverOptions.cpp ├── DriverOptions.hpp ├── LICENSE ├── LICENSE.spdx ├── LICENSES └── MIT.txt ├── ModelToINetworkConverter.cpp ├── ModelToINetworkConverter.hpp ├── NnapiSupport.txt ├── NnapiSupport.txt.license ├── README.md ├── README.md.license ├── RequestThread.cpp ├── RequestThread.hpp ├── RequestThread_1_3.cpp ├── RequestThread_1_3.hpp ├── SECURITY.md ├── SECURITY.md.license ├── SystemPropertiesUtils.hpp ├── Utils.cpp ├── Utils.hpp ├── android.hardware.neuralnetworks@1.0-service-armnn.rc ├── android.hardware.neuralnetworks@1.0-service-armnn.rc.license ├── android.hardware.neuralnetworks@1.1-service-armnn.rc ├── android.hardware.neuralnetworks@1.1-service-armnn.rc.license ├── android.hardware.neuralnetworks@1.2-service-armnn.rc ├── android.hardware.neuralnetworks@1.2-service-armnn.rc.license ├── android.hardware.neuralnetworks@1.3-service-armnn.rc ├── android.hardware.neuralnetworks@1.3-service-armnn.rc.license ├── docs ├── FAQ.md ├── FAQ.md.license ├── IntegratorGuide.md └── IntegratorGuide.md.license ├── service.cpp ├── setup.sh └── test ├── 1.0 ├── Convolution2D.cpp ├── FullyConnectedReshape.cpp └── Lstm.cpp ├── 1.1 ├── Convolution2D.cpp ├── Lstm.cpp ├── Mean.cpp └── Transpose.cpp ├── 1.2 ├── Capabilities.cpp ├── Dilation.cpp ├── Lstm.cpp ├── Mean.cpp └── UnidirectionalSequenceLstm.cpp ├── 1.3 ├── QLstm.cpp └── QosTests.cpp ├── Android.mk ├── Concat.cpp ├── Concurrent.cpp ├── Convolution2D.hpp ├── Dilation.hpp ├── DriverTestHelpers.cpp ├── DriverTestHelpers.hpp ├── FullyConnected.cpp ├── GenericLayerTests.cpp ├── Lstm.hpp ├── SystemProperties.cpp ├── TestHalfTensor.cpp ├── TestHalfTensor.hpp ├── TestTensor.cpp ├── TestTensor.hpp ├── Tests.cpp ├── UnidirectionalSequenceLstm.hpp └── UtilsTests.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | armnn 2 | boost_1_64_0 3 | clframework 4 | flatbuffers-1.12.0 5 | prebuilt 6 | .vscode/settings.json 7 | .gitignore 8 | -------------------------------------------------------------------------------- /.gitignore.license: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright © 2018, 2022 Arm Ltd and Contributors. All rights reserved. 3 | # SPDX-License-Identifier: MIT 4 | # 5 | -------------------------------------------------------------------------------- /1.0/ArmnnDriver.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Arm Ltd. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #include "../ArmnnDevice.hpp" 11 | #include "ArmnnDriverImpl.hpp" 12 | #include "HalPolicy.hpp" 13 | 14 | #include "../ArmnnDriverImpl.hpp" 15 | 16 | #include 17 | 18 | namespace armnn_driver 19 | { 20 | namespace hal_1_0 21 | { 22 | 23 | class ArmnnDriver : public ArmnnDevice, public V1_0::IDevice 24 | { 25 | public: 26 | ArmnnDriver(DriverOptions options) 27 | : ArmnnDevice(std::move(options)) 28 | { 29 | ALOGV("hal_1_0::ArmnnDriver::ArmnnDriver()"); 30 | } 31 | ~ArmnnDriver() {} 32 | 33 | public: 34 | Return getCapabilities(V1_0::IDevice::getCapabilities_cb cb) override 35 | { 36 | ALOGV("hal_1_0::ArmnnDriver::getCapabilities()"); 37 | 38 | return hal_1_0::ArmnnDriverImpl::getCapabilities(m_Runtime, cb); 39 | } 40 | 41 | Return getSupportedOperations(const V1_0::Model& model, 42 | V1_0::IDevice::getSupportedOperations_cb cb) override 43 | { 44 | ALOGV("hal_1_0::ArmnnDriver::getSupportedOperations()"); 45 | 46 | return armnn_driver::ArmnnDriverImpl::getSupportedOperations(m_Runtime, m_Options, model, cb); 47 | } 48 | 49 | Return prepareModel(const V1_0::Model& model, 50 | const android::sp& cb) override 51 | { 52 | ALOGV("hal_1_0::ArmnnDriver::prepareModel()"); 53 | 54 | return armnn_driver::ArmnnDriverImpl::prepareModel(m_Runtime, 55 | m_ClTunedParameters, 56 | m_Options, 57 | model, 58 | cb); 59 | } 60 | 61 | Return getStatus() override 62 | { 63 | ALOGV("hal_1_0::ArmnnDriver::getStatus()"); 64 | 65 | return armnn_driver::ArmnnDriverImpl::getStatus(); 66 | } 67 | }; 68 | 69 | } // namespace hal_1_0 70 | } // namespace armnn_driver 71 | -------------------------------------------------------------------------------- /1.0/ArmnnDriverImpl.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Arm Ltd. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #include "ArmnnDriverImpl.hpp" 7 | #include "../SystemPropertiesUtils.hpp" 8 | 9 | #include 10 | 11 | namespace 12 | { 13 | 14 | const char *g_Float32PerformanceExecTimeName = "ArmNN.float32Performance.execTime"; 15 | const char *g_Float32PerformancePowerUsageName = "ArmNN.float32Performance.powerUsage"; 16 | const char *g_Quantized8PerformanceExecTimeName = "ArmNN.quantized8Performance.execTime"; 17 | const char *g_Quantized8PerformancePowerUsageName = "ArmNN.quantized8Performance.powerUsage"; 18 | 19 | } // anonymous namespace 20 | 21 | namespace armnn_driver 22 | { 23 | namespace hal_1_0 24 | { 25 | 26 | Return ArmnnDriverImpl::getCapabilities(const armnn::IRuntimePtr& runtime, 27 | V1_0::IDevice::getCapabilities_cb cb) 28 | { 29 | ALOGV("hal_1_0::ArmnnDriverImpl::getCapabilities()"); 30 | 31 | V1_0::Capabilities capabilities; 32 | if (runtime) 33 | { 34 | capabilities.float32Performance.execTime = 35 | ParseSystemProperty(g_Float32PerformanceExecTimeName, .1f); 36 | 37 | capabilities.float32Performance.powerUsage = 38 | ParseSystemProperty(g_Float32PerformancePowerUsageName, .1f); 39 | 40 | capabilities.quantized8Performance.execTime = 41 | ParseSystemProperty(g_Quantized8PerformanceExecTimeName, .1f); 42 | 43 | capabilities.quantized8Performance.powerUsage = 44 | ParseSystemProperty(g_Quantized8PerformancePowerUsageName, .1f); 45 | 46 | cb(V1_0::ErrorStatus::NONE, capabilities); 47 | } 48 | else 49 | { 50 | capabilities.float32Performance.execTime = 0; 51 | capabilities.float32Performance.powerUsage = 0; 52 | capabilities.quantized8Performance.execTime = 0; 53 | capabilities.quantized8Performance.powerUsage = 0; 54 | 55 | cb(V1_0::ErrorStatus::DEVICE_UNAVAILABLE, capabilities); 56 | } 57 | 58 | return Void(); 59 | } 60 | 61 | } // namespace hal_1_0 62 | } // namespace armnn_driver -------------------------------------------------------------------------------- /1.0/ArmnnDriverImpl.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Arm Ltd. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #include "../DriverOptions.hpp" 11 | 12 | #include 13 | 14 | #ifdef ARMNN_ANDROID_R 15 | using namespace android::nn::hal; 16 | #endif 17 | 18 | #ifdef ARMNN_ANDROID_S 19 | using namespace android::hardware; 20 | #endif 21 | 22 | namespace V1_0 = ::android::hardware::neuralnetworks::V1_0; 23 | 24 | namespace armnn_driver 25 | { 26 | namespace hal_1_0 27 | { 28 | 29 | class ArmnnDriverImpl 30 | { 31 | public: 32 | static Return getCapabilities(const armnn::IRuntimePtr& runtime, V1_0::IDevice::getCapabilities_cb cb); 33 | }; 34 | 35 | } // namespace hal_1_0 36 | } // namespace armnn_driver 37 | -------------------------------------------------------------------------------- /1.0/FullyConnected.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Arm Ltd. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #include "../ConversionUtils.hpp" 11 | 12 | namespace armnn_driver 13 | { 14 | 15 | inline armnn::TensorShape FlattenFullyConnectedInput(const armnn::TensorShape& inputShape, 16 | const armnn::TensorShape& weightsShape) 17 | { 18 | if (inputShape.GetNumDimensions() > 2U) 19 | { 20 | unsigned int totalInputElements = inputShape.GetNumElements(); 21 | unsigned int inputSize = weightsShape[1]; 22 | 23 | unsigned int batchSize = totalInputElements / inputSize; 24 | 25 | if(totalInputElements % batchSize != 0) 26 | { 27 | throw std::runtime_error("Failed to deduce tensor shape"); 28 | } 29 | 30 | return armnn::TensorShape({batchSize, inputSize}); 31 | } 32 | else 33 | { 34 | return inputShape; 35 | } 36 | } 37 | 38 | inline bool VerifyFullyConnectedShapes(const armnn::TensorShape& inputShape, 39 | const armnn::TensorShape& weightsShape, 40 | const armnn::TensorShape& outputShape, 41 | bool transposeWeightMatrix) 42 | { 43 | unsigned int dimIdx = transposeWeightMatrix ? 0 : 1; 44 | return (inputShape[0] == outputShape[0] && weightsShape[dimIdx] == outputShape[1]); 45 | } 46 | 47 | } -------------------------------------------------------------------------------- /1.0/HalPolicy.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017-2021,2023 Arm Ltd and Contributors. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #pragma once 7 | 8 | #include "../ConversionUtils.hpp" 9 | 10 | #include 11 | 12 | namespace V1_0 = ::android::hardware::neuralnetworks::V1_0; 13 | 14 | namespace armnn_driver 15 | { 16 | namespace hal_1_0 17 | { 18 | 19 | class HalPolicy 20 | { 21 | public: 22 | using Model = V1_0::Model; 23 | using Operand = V1_0::Operand; 24 | using OperandLifeTime = V1_0::OperandLifeTime; 25 | using OperandType = V1_0::OperandType; 26 | using Operation = V1_0::Operation; 27 | using OperationType = V1_0::OperationType; 28 | using getSupportedOperations_cb = V1_0::IDevice::getSupportedOperations_cb; 29 | using ErrorStatus = V1_0::ErrorStatus; 30 | 31 | static bool ConvertOperation(const Operation& operation, const Model& model, ConversionData& data); 32 | 33 | private: 34 | static bool ConvertAveragePool2d(const Operation& operation, const Model& model, ConversionData& data); 35 | 36 | static bool ConvertConcatenation(const Operation& operation, const Model& model, ConversionData& data); 37 | 38 | static bool ConvertConv2d(const Operation& operation, const Model& model, ConversionData& data); 39 | 40 | static bool ConvertDepthToSpace(const Operation& operation, const Model& model, ConversionData& data); 41 | 42 | static bool ConvertDepthwiseConv2d(const Operation& operation, const Model& model, ConversionData& data); 43 | 44 | static bool ConvertDequantize(const Operation& operation, const Model& model, ConversionData& data); 45 | 46 | static bool ConvertElementwiseBinary(const Operation& operation, 47 | const Model& model, 48 | ConversionData& data, 49 | armnn::BinaryOperation binaryOperation); 50 | 51 | static bool ConvertFloor(const Operation& operation, const Model& model, ConversionData& data); 52 | 53 | static bool ConvertFullyConnected(const Operation& operation, const Model& model, ConversionData& data); 54 | 55 | static bool ConvertLocalResponseNormalization(const Operation& operation, 56 | const Model& model, 57 | ConversionData& data); 58 | 59 | static bool ConvertLogistic(const Operation& operation, const Model& model, ConversionData& data); 60 | 61 | static bool ConvertLstm(const Operation& operation, const Model& model, ConversionData& data); 62 | 63 | static bool ConvertL2Normalization(const Operation& operation, const Model& model, ConversionData& data); 64 | 65 | static bool ConvertL2Pool2d(const Operation& operation, const Model& model, ConversionData& data); 66 | 67 | static bool ConvertMaxPool2d(const Operation& operation, const Model& model, ConversionData& data); 68 | 69 | static bool ConvertReLu(const Operation& operation, const Model& model, ConversionData& data); 70 | 71 | static bool ConvertReLu1(const Operation& operation, const Model& model, ConversionData& data); 72 | 73 | static bool ConvertReLu6(const Operation& operation, const Model& model, ConversionData& data); 74 | 75 | static bool ConvertSoftmax(const Operation& operation, const Model& model, ConversionData& data); 76 | 77 | static bool ConvertReshape(const Operation& operation, const Model& model, ConversionData& data); 78 | 79 | static bool ConvertResizeBilinear(const Operation& operation, const Model& model, ConversionData& data); 80 | 81 | static bool ConvertSpaceToDepth(const Operation& operation, const Model& model, ConversionData& data); 82 | 83 | static bool ConvertTanH(const Operation& operation, const Model& model, ConversionData& data); 84 | 85 | static bool ValidateConv2dParameters(const Operation& operation); 86 | 87 | static bool ValidateDepthwiseConv2dParameters(const Operation& operation); 88 | }; 89 | 90 | } // namespace hal_1_0 91 | } // namespace armnn_driver 92 | -------------------------------------------------------------------------------- /1.1/ArmnnDriver.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Arm Ltd. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #include "../ArmnnDevice.hpp" 11 | #include "ArmnnDriverImpl.hpp" 12 | #include "HalPolicy.hpp" 13 | 14 | #include "../ArmnnDriverImpl.hpp" 15 | #include "../1.0/ArmnnDriverImpl.hpp" 16 | #include "../1.0/HalPolicy.hpp" 17 | 18 | #include 19 | 20 | namespace armnn_driver 21 | { 22 | namespace hal_1_1 23 | { 24 | 25 | class ArmnnDriver : public ArmnnDevice, public V1_1::IDevice 26 | { 27 | public: 28 | ArmnnDriver(DriverOptions options) 29 | : ArmnnDevice(std::move(options)) 30 | { 31 | ALOGV("hal_1_1::ArmnnDriver::ArmnnDriver()"); 32 | } 33 | ~ArmnnDriver() {} 34 | 35 | public: 36 | 37 | Return getCapabilities(V1_0::IDevice::getCapabilities_cb cb) override 38 | { 39 | ALOGV("hal_1_1::ArmnnDriver::getCapabilities()"); 40 | 41 | return hal_1_0::ArmnnDriverImpl::getCapabilities(m_Runtime, cb); 42 | } 43 | 44 | Return getSupportedOperations(const V1_0::Model& model, 45 | V1_0::IDevice::getSupportedOperations_cb cb) override 46 | { 47 | ALOGV("hal_1_1::ArmnnDriver::getSupportedOperations()"); 48 | 49 | return armnn_driver::ArmnnDriverImpl::getSupportedOperations(m_Runtime, 50 | m_Options, 51 | model, 52 | cb); 53 | } 54 | 55 | Return prepareModel(const V1_0::Model& model, 56 | const android::sp& cb) override 57 | { 58 | ALOGV("hal_1_1::ArmnnDriver::prepareModel()"); 59 | 60 | return armnn_driver::ArmnnDriverImpl::prepareModel(m_Runtime, 61 | m_ClTunedParameters, 62 | m_Options, 63 | model, 64 | cb); 65 | } 66 | 67 | Return getCapabilities_1_1(V1_1::IDevice::getCapabilities_1_1_cb cb) override 68 | { 69 | ALOGV("hal_1_1::ArmnnDriver::getCapabilities_1_1()"); 70 | 71 | return hal_1_1::ArmnnDriverImpl::getCapabilities_1_1(m_Runtime, cb); 72 | } 73 | 74 | Return getSupportedOperations_1_1(const V1_1::Model& model, 75 | V1_1::IDevice::getSupportedOperations_1_1_cb cb) override 76 | { 77 | ALOGV("hal_1_1::ArmnnDriver::getSupportedOperations_1_1()"); 78 | 79 | return armnn_driver::ArmnnDriverImpl::getSupportedOperations(m_Runtime, 80 | m_Options, 81 | model, 82 | cb); 83 | } 84 | 85 | Return prepareModel_1_1(const V1_1::Model& model, 86 | V1_1::ExecutionPreference preference, 87 | const android::sp& cb) override 88 | { 89 | ALOGV("hal_1_1::ArmnnDriver::prepareModel_1_1()"); 90 | 91 | if (!(preference == V1_1::ExecutionPreference::LOW_POWER || 92 | preference == V1_1::ExecutionPreference::FAST_SINGLE_ANSWER || 93 | preference == V1_1::ExecutionPreference::SUSTAINED_SPEED)) 94 | { 95 | ALOGV("hal_1_1::ArmnnDriver::prepareModel_1_1: Invalid execution preference"); 96 | cb->notify(V1_0::ErrorStatus::INVALID_ARGUMENT, nullptr); 97 | return V1_0::ErrorStatus::INVALID_ARGUMENT; 98 | } 99 | 100 | return armnn_driver::ArmnnDriverImpl::prepareModel(m_Runtime, 101 | m_ClTunedParameters, 102 | m_Options, 103 | model, 104 | cb, 105 | model.relaxComputationFloat32toFloat16 106 | && m_Options.GetFp16Enabled()); 107 | } 108 | 109 | Return getStatus() override 110 | { 111 | ALOGV("hal_1_1::ArmnnDriver::getStatus()"); 112 | 113 | return armnn_driver::ArmnnDriverImpl::getStatus(); 114 | } 115 | }; 116 | 117 | } // namespace hal_1_1 118 | } // namespace armnn_driver 119 | -------------------------------------------------------------------------------- /1.1/ArmnnDriverImpl.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Arm Ltd. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #include "ArmnnDriverImpl.hpp" 7 | #include "../SystemPropertiesUtils.hpp" 8 | 9 | #include 10 | 11 | namespace 12 | { 13 | 14 | const char *g_Float32PerformanceExecTimeName = "ArmNN.float32Performance.execTime"; 15 | const char *g_Float32PerformancePowerUsageName = "ArmNN.float32Performance.powerUsage"; 16 | const char *g_Quantized8PerformanceExecTimeName = "ArmNN.quantized8Performance.execTime"; 17 | const char *g_Quantized8PerformancePowerUsageName = "ArmNN.quantized8Performance.powerUsage"; 18 | const char *g_RelaxedFloat32toFloat16PerformanceExecTime = "ArmNN.relaxedFloat32toFloat16Performance.execTime"; 19 | const char *g_RelaxedFloat32toFloat16PerformancePowerUsageName = "ArmNN.relaxedFloat32toFloat16Performance.powerUsage"; 20 | 21 | } // anonymous namespace 22 | 23 | namespace armnn_driver 24 | { 25 | namespace hal_1_1 26 | { 27 | 28 | Return ArmnnDriverImpl::getCapabilities_1_1(const armnn::IRuntimePtr& runtime, 29 | V1_1::IDevice::getCapabilities_1_1_cb cb) 30 | { 31 | ALOGV("hal_1_1::ArmnnDriverImpl::getCapabilities()"); 32 | 33 | V1_1::Capabilities capabilities; 34 | if (runtime) 35 | { 36 | capabilities.float32Performance.execTime = 37 | ParseSystemProperty(g_Float32PerformanceExecTimeName, .1f); 38 | 39 | capabilities.float32Performance.powerUsage = 40 | ParseSystemProperty(g_Float32PerformancePowerUsageName, .1f); 41 | 42 | capabilities.quantized8Performance.execTime = 43 | ParseSystemProperty(g_Quantized8PerformanceExecTimeName, .1f); 44 | 45 | capabilities.quantized8Performance.powerUsage = 46 | ParseSystemProperty(g_Quantized8PerformancePowerUsageName, .1f); 47 | 48 | capabilities.relaxedFloat32toFloat16Performance.execTime = 49 | ParseSystemProperty(g_RelaxedFloat32toFloat16PerformanceExecTime, .1f); 50 | 51 | capabilities.relaxedFloat32toFloat16Performance.powerUsage = 52 | ParseSystemProperty(g_RelaxedFloat32toFloat16PerformancePowerUsageName, .1f); 53 | 54 | cb(V1_0::ErrorStatus::NONE, capabilities); 55 | } 56 | else 57 | { 58 | capabilities.float32Performance.execTime = 0; 59 | capabilities.float32Performance.powerUsage = 0; 60 | capabilities.quantized8Performance.execTime = 0; 61 | capabilities.quantized8Performance.powerUsage = 0; 62 | capabilities.relaxedFloat32toFloat16Performance.execTime = 0; 63 | capabilities.relaxedFloat32toFloat16Performance.powerUsage = 0; 64 | 65 | cb(V1_0::ErrorStatus::DEVICE_UNAVAILABLE, capabilities); 66 | } 67 | 68 | return Void(); 69 | } 70 | 71 | } // namespace hal_1_1 72 | } // namespace armnn_driver -------------------------------------------------------------------------------- /1.1/ArmnnDriverImpl.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Arm Ltd. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #include "../DriverOptions.hpp" 11 | 12 | #include 13 | 14 | #ifdef ARMNN_ANDROID_R 15 | using namespace android::nn::hal; 16 | #endif 17 | 18 | #ifdef ARMNN_ANDROID_S 19 | using namespace android::hardware; 20 | #endif 21 | 22 | 23 | namespace V1_0 = ::android::hardware::neuralnetworks::V1_0; 24 | namespace V1_1 = ::android::hardware::neuralnetworks::V1_1; 25 | 26 | namespace armnn_driver 27 | { 28 | namespace hal_1_1 29 | { 30 | 31 | class ArmnnDriverImpl 32 | { 33 | public: 34 | static Return getCapabilities_1_1(const armnn::IRuntimePtr& runtime, 35 | V1_1::IDevice::getCapabilities_1_1_cb cb); 36 | }; 37 | 38 | } // namespace hal_1_1 39 | } // namespace armnn_driver 40 | -------------------------------------------------------------------------------- /1.1/HalPolicy.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017-2019,2023 Arm Ltd and Contributors. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #include "HalPolicy.hpp" 7 | 8 | #include "Utils.hpp" 9 | 10 | #include "../1.0/HalPolicy.hpp" 11 | 12 | namespace 13 | { 14 | static std::vector opsEquivalentInV10({ 15 | V1_0::OperationType::ADD, 16 | V1_0::OperationType::AVERAGE_POOL_2D, 17 | V1_0::OperationType::CONCATENATION, 18 | V1_0::OperationType::CONV_2D, 19 | V1_0::OperationType::DEPTH_TO_SPACE, 20 | V1_0::OperationType::DEPTHWISE_CONV_2D, 21 | V1_0::OperationType::DEQUANTIZE, 22 | V1_0::OperationType::FLOOR, 23 | V1_0::OperationType::FULLY_CONNECTED, 24 | V1_0::OperationType::LOCAL_RESPONSE_NORMALIZATION, 25 | V1_0::OperationType::LOGISTIC, 26 | V1_0::OperationType::LSTM, 27 | V1_0::OperationType::L2_NORMALIZATION, 28 | V1_0::OperationType::L2_POOL_2D, 29 | V1_0::OperationType::MAX_POOL_2D, 30 | V1_0::OperationType::MUL, 31 | V1_0::OperationType::RELU, 32 | V1_0::OperationType::RELU1, 33 | V1_0::OperationType::RELU6, 34 | V1_0::OperationType::SOFTMAX, 35 | V1_0::OperationType::SPACE_TO_DEPTH, 36 | V1_0::OperationType::TANH, 37 | V1_0::OperationType::RESHAPE, 38 | V1_0::OperationType::RESIZE_BILINEAR, 39 | }); 40 | 41 | bool CompliantWithVersion10(const V1_1::Operation & operation) 42 | { 43 | std::vector::iterator it; 44 | it = std::find(opsEquivalentInV10.begin(), opsEquivalentInV10.end(), 45 | static_cast(operation.type)); 46 | 47 | if(it != opsEquivalentInV10.end()) 48 | { 49 | return true; 50 | } 51 | return false; 52 | } 53 | 54 | V1_0::Operation ConvertOperationToVersion10(const V1_1::Operation & operation) 55 | { 56 | V1_0::Operation v10Operation; 57 | v10Operation.type = static_cast(operation.type); 58 | v10Operation.inputs = operation.inputs; 59 | v10Operation.outputs = operation.outputs; 60 | return v10Operation; 61 | } 62 | } 63 | 64 | namespace armnn_driver 65 | { 66 | namespace hal_1_1 67 | { 68 | 69 | bool HalPolicy::ConvertOperation(const Operation& operation, const Model& model, ConversionData& data) 70 | { 71 | if (CompliantWithVersion10(operation)) 72 | { 73 | hal_1_0::HalPolicy::Operation v10Operation = ConvertOperationToVersion10(operation); 74 | hal_1_0::HalPolicy::Model v10Model = convertToV1_0(model); 75 | 76 | return hal_1_0::HalPolicy::ConvertOperation(v10Operation, v10Model, data); 77 | } 78 | else 79 | { 80 | switch (operation.type) 81 | { 82 | case V1_1::OperationType::DIV: 83 | return ConvertElementwiseBinary(operation, model, data, armnn::BinaryOperation::Div); 84 | case V1_1::OperationType::SUB: 85 | return ConvertElementwiseBinary(operation, model, data, armnn::BinaryOperation::Sub); 86 | case V1_1::OperationType::MEAN: 87 | return ConvertMean(operation, model, data); 88 | case V1_1::OperationType::PAD: 89 | return ConvertPad(operation, model, data); 90 | case V1_1::OperationType::SPACE_TO_BATCH_ND: 91 | return ConvertSpaceToBatchNd(operation, model, data); 92 | case V1_1::OperationType::SQUEEZE: 93 | return ConvertSqueeze(operation, model, data); 94 | case V1_1::OperationType::STRIDED_SLICE: 95 | return ConvertStridedSlice(operation, model, data); 96 | case V1_1::OperationType::TRANSPOSE: 97 | return ConvertTranspose(operation, model, data); 98 | case V1_1::OperationType::BATCH_TO_SPACE_ND: 99 | return ConvertBatchToSpaceNd(operation, model, data); 100 | default: 101 | return Fail("%s: Operation type %s not supported in ArmnnDriver", 102 | __func__, toString(operation.type).c_str()); 103 | } 104 | } 105 | } 106 | 107 | bool HalPolicy::ConvertElementwiseBinary(const Operation& operation, 108 | const Model& model, 109 | ConversionData& data, 110 | armnn::BinaryOperation binaryOperation) 111 | { 112 | ALOGV("hal_1_1::HalPolicy::ConvertElementwiseBinary()"); 113 | return ::ConvertElementwiseBinary(operation, model, data, binaryOperation); 114 | } 115 | 116 | bool HalPolicy::ConvertMean(const Operation& operation, const Model& model, ConversionData& data) 117 | { 118 | ALOGV("hal_1_1::HalPolicy::ConvertMean()"); 119 | return ::ConvertMean(operation, model, data); 120 | } 121 | 122 | bool HalPolicy::ConvertPad(const Operation& operation, const Model& model, ConversionData& data) 123 | { 124 | ALOGV("hal_1_1::HalPolicy::ConvertPad()"); 125 | return ::ConvertPad(operation, model, data); 126 | } 127 | 128 | bool HalPolicy::ConvertSpaceToBatchNd(const Operation& operation, const Model& model, ConversionData& data) 129 | { 130 | ALOGV("hal_1_1::HalPolicy::ConvertSpaceToBatchNd()"); 131 | return ::ConvertSpaceToBatchNd(operation, model, data); 132 | } 133 | 134 | bool HalPolicy::ConvertSqueeze(const Operation& operation, const Model& model, ConversionData& data) 135 | { 136 | ALOGV("hal_1_1::HalPolicy::ConvertSqueeze()"); 137 | return ::ConvertSqueeze(operation, model, data); 138 | } 139 | 140 | bool HalPolicy::ConvertStridedSlice(const Operation& operation, const Model& model, ConversionData& data) 141 | { 142 | ALOGV("hal_1_1::HalPolicy::ConvertStridedSlice()"); 143 | return ::ConvertStridedSlice(operation, model, data); 144 | } 145 | 146 | bool HalPolicy::ConvertTranspose(const Operation& operation, const Model& model, ConversionData& data) 147 | { 148 | ALOGV("hal_1_1::HalPolicy::ConvertTranspose()"); 149 | return ::ConvertTranspose(operation, model, data); 150 | } 151 | 152 | bool HalPolicy::ConvertBatchToSpaceNd(const Operation& operation, const Model& model, ConversionData& data) 153 | { 154 | ALOGV("hal_1_1::HalPolicy::ConvertBatchToSpaceNd()"); 155 | return ::ConvertBatchToSpaceNd(operation, model, data); 156 | } 157 | 158 | } // namespace hal_1_1 159 | } // namespace armnn_driver 160 | -------------------------------------------------------------------------------- /1.1/HalPolicy.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017-2021,2023 Arm Ltd and Contributors. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #pragma once 7 | 8 | #include "../ConversionUtils.hpp" 9 | 10 | #include 11 | 12 | namespace V1_1 = ::android::hardware::neuralnetworks::V1_1; 13 | 14 | namespace armnn_driver 15 | { 16 | namespace hal_1_1 17 | { 18 | 19 | class HalPolicy 20 | { 21 | public: 22 | using Model = V1_1::Model; 23 | using Operand = V1_0::Operand; 24 | using OperandLifeTime = V1_0::OperandLifeTime; 25 | using OperandType = V1_0::OperandType; 26 | using Operation = V1_1::Operation; 27 | using OperationType = V1_1::OperationType; 28 | using getSupportedOperations_cb = V1_1::IDevice::getSupportedOperations_1_1_cb; 29 | using ErrorStatus = V1_0::ErrorStatus; 30 | 31 | static bool ConvertOperation(const Operation& operation, const Model& model, ConversionData& data); 32 | 33 | private: 34 | static bool ConvertElementwiseBinary(const Operation& operation, 35 | const Model& model, 36 | ConversionData& data, 37 | armnn::BinaryOperation binaryOperation); 38 | 39 | static bool ConvertMean(const Operation& operation, const Model& model, ConversionData& data); 40 | static bool ConvertPad(const Operation& operation, const Model& model, ConversionData& data); 41 | static bool ConvertSpaceToBatchNd(const Operation& operation, const Model& model, ConversionData& data); 42 | static bool ConvertSqueeze(const Operation& operation, const Model& model, ConversionData& data); 43 | static bool ConvertStridedSlice(const Operation& operation, const Model& model, ConversionData& data); 44 | static bool ConvertTranspose(const Operation& operation, const Model& model, ConversionData& data); 45 | static bool ConvertBatchToSpaceNd(const Operation& operation, const Model& model, ConversionData& data); 46 | }; 47 | 48 | } // namespace hal_1_1 49 | } // namespace armnn_driver 50 | -------------------------------------------------------------------------------- /1.2/ArmnnDriverImpl.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Arm Ltd. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #include "../CacheDataHandler.hpp" 11 | #include "../DriverOptions.hpp" 12 | 13 | #include 14 | 15 | #include 16 | 17 | #ifdef ARMNN_ANDROID_R 18 | using namespace android::nn::hal; 19 | #endif 20 | 21 | #ifdef ARMNN_ANDROID_S 22 | using namespace android::hardware; 23 | #endif 24 | 25 | namespace V1_0 = ::android::hardware::neuralnetworks::V1_0; 26 | namespace V1_2 = ::android::hardware::neuralnetworks::V1_2; 27 | 28 | namespace armnn_driver 29 | { 30 | namespace hal_1_2 31 | { 32 | 33 | class ArmnnDriverImpl 34 | { 35 | public: 36 | using HidlToken = android::hardware::hidl_array; 37 | 38 | static Return prepareArmnnModel_1_2( 39 | const armnn::IRuntimePtr& runtime, 40 | const armnn::IGpuAccTunedParametersPtr& clTunedParameters, 41 | const DriverOptions& options, 42 | const V1_2::Model& model, 43 | const android::hardware::hidl_vec& modelCacheHandle, 44 | const android::hardware::hidl_vec& dataCacheHandle, 45 | const HidlToken& token, 46 | const android::sp& cb, 47 | bool float32ToFloat16 = false); 48 | 49 | static Return prepareModelFromCache( 50 | const armnn::IRuntimePtr& runtime, 51 | const DriverOptions& options, 52 | const android::hardware::hidl_vec& modelCacheHandle, 53 | const android::hardware::hidl_vec& dataCacheHandle, 54 | const HidlToken& token, 55 | const android::sp& cb, 56 | bool float32ToFloat16 = false); 57 | 58 | static Return getCapabilities_1_2(const armnn::IRuntimePtr& runtime, 59 | V1_2::IDevice::getCapabilities_1_2_cb cb); 60 | }; 61 | 62 | } // namespace hal_1_2 63 | } // namespace armnn_driver -------------------------------------------------------------------------------- /1.2/HalPolicy.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2019-2023 Arm Ltd and Contributors. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #pragma once 7 | 8 | #include "../ConversionUtils.hpp" 9 | #include "../ConversionUtils_1_2.hpp" 10 | 11 | #include 12 | 13 | #include 14 | 15 | namespace V1_2 = ::android::hardware::neuralnetworks::V1_2; 16 | 17 | namespace armnn_driver 18 | { 19 | class DriverOptions; 20 | namespace hal_1_2 21 | { 22 | 23 | class HalPolicy 24 | { 25 | public: 26 | using Model = V1_2::Model; 27 | using Operand = V1_2::Operand; 28 | using OperandLifeTime = V1_0::OperandLifeTime; 29 | using OperandType = V1_2::OperandType; 30 | using Operation = V1_2::Operation; 31 | using OperationType = V1_2::OperationType; 32 | using ExecutionCallback = V1_2::IExecutionCallback; 33 | using getSupportedOperations_cb = V1_2::IDevice::getSupportedOperations_1_2_cb; 34 | using ErrorStatus = V1_0::ErrorStatus; 35 | using DeviceType = V1_2::DeviceType; 36 | 37 | static DeviceType GetDeviceTypeFromOptions(const DriverOptions& options); 38 | 39 | static bool ConvertOperation(const Operation& operation, const Model& model, ConversionData& data); 40 | 41 | private: 42 | static bool ConvertArgMinMax(const Operation& operation, 43 | const Model& model, 44 | ConversionData& data, 45 | armnn::ArgMinMaxFunction argMinMaxFunction); 46 | 47 | static bool ConvertAveragePool2d(const Operation& operation, const Model& model, ConversionData& data); 48 | 49 | static bool ConvertBatchToSpaceNd(const Operation& operation, const Model& model, ConversionData& data); 50 | 51 | static bool ConvertCast(const Operation& operation, const Model& model, ConversionData& data); 52 | 53 | static bool ConvertChannelShuffle(const Operation& operation, const Model& model, ConversionData& data); 54 | 55 | static bool ConvertComparison(const Operation& operation, 56 | const Model& model, 57 | ConversionData& data, 58 | armnn::ComparisonOperation comparisonOperation); 59 | 60 | static bool ConvertConcatenation(const Operation& operation, const Model& model, ConversionData& data); 61 | 62 | static bool ConvertConv2d(const Operation& operation, const Model& model, ConversionData& data); 63 | 64 | static bool ConvertDepthToSpace(const Operation& operation, const Model& model, ConversionData& data); 65 | 66 | static bool ConvertDepthwiseConv2d(const Operation& operation, const Model& model, ConversionData& data); 67 | 68 | static bool ConvertDequantize(const Operation& operation, const Model& model, ConversionData& data); 69 | 70 | static bool ConvertExpandDims(const Operation& operation, const Model& model, ConversionData& data); 71 | 72 | static bool ConvertElementwiseBinary(const Operation& operation, 73 | const Model& model, 74 | ConversionData& data, 75 | armnn::BinaryOperation binaryOperation); 76 | 77 | static bool ConvertElementwiseUnary(const Operation& operation, 78 | const Model& model, 79 | ConversionData& data, 80 | armnn::UnaryOperation unaryOperation); 81 | 82 | static bool ConvertFloor(const Operation& operation, const Model& model, ConversionData& data); 83 | 84 | static bool ConvertFullyConnected(const Operation& operation, const Model& model, ConversionData& data); 85 | 86 | static bool ConvertGather(const Operation& operation, const Model& model, ConversionData& data); 87 | 88 | static bool ConvertGroupedConv2d(const Operation& operation, const Model& model, ConversionData& data); 89 | 90 | static bool ConvertInstanceNormalization(const Operation& operation, const Model& model, ConversionData& data); 91 | 92 | static bool ConvertL2Normalization(const Operation& operation, const Model& model, ConversionData& data); 93 | 94 | static bool ConvertL2Pool2d(const Operation& operation, const Model& model, ConversionData& data); 95 | 96 | static bool ConvertLocalResponseNormalization(const Operation& operation, 97 | const Model& model, 98 | ConversionData& data); 99 | 100 | static bool ConvertLogistic(const Operation& operation, const Model& model, ConversionData& data); 101 | 102 | static bool ConvertLogSoftmax(const Operation& operation, const Model& model, ConversionData& data); 103 | 104 | static bool ConvertLstm(const Operation& operation, const Model& model, ConversionData& data); 105 | 106 | static bool ConvertMaxPool2d(const Operation& operation, const Model& model, ConversionData& data); 107 | 108 | static bool ConvertMean(const Operation& operation, const Model& model, ConversionData& data); 109 | 110 | static bool ConvertPad(const Operation& operation, const Model& model, ConversionData& data); 111 | 112 | static bool ConvertPadV2(const Operation& operation, const Model& model, ConversionData& data); 113 | 114 | static bool ConvertPrelu(const Operation& operation, const Model& model, ConversionData& data); 115 | 116 | static bool ConvertQuantize(const Operation& operation, const Model& model, ConversionData& data); 117 | 118 | static bool ConvertQuantized16BitLstm(const Operation& operation, const Model& model, ConversionData& data); 119 | 120 | static bool ConvertReduce(const Operation& operation, 121 | const Model& model, 122 | ConversionData& data, 123 | ReduceOperation reduce_operation); 124 | 125 | static bool ConvertReLu(const Operation& operation, const Model& model, ConversionData& data); 126 | 127 | static bool ConvertReLu1(const Operation& operation, const Model& model, ConversionData& data); 128 | 129 | static bool ConvertReLu6(const Operation& operation, const Model& model, ConversionData& data); 130 | 131 | static bool ConvertReshape(const Operation& operation, const Model& model, ConversionData& data); 132 | 133 | static bool ConvertResize(const Operation& operation, 134 | const Model& model, 135 | ConversionData& data, 136 | armnn::ResizeMethod resizeMethod); 137 | 138 | static bool ConvertSoftmax(const Operation& operation, const Model& model, ConversionData& data); 139 | 140 | static bool ConvertSpaceToBatchNd(const Operation& operation, const Model& model, ConversionData& data); 141 | 142 | static bool ConvertSpaceToDepth(const Operation& operation, const Model& model, ConversionData& data); 143 | 144 | static bool ConvertSplit(const Operation& operation, const Model& model, ConversionData& data); 145 | 146 | static bool ConvertSqrt(const Operation& operation, const Model& model, ConversionData& data); 147 | 148 | static bool ConvertSqueeze(const Operation& operation, const Model& model, ConversionData& data); 149 | 150 | static bool ConvertStridedSlice(const Operation& operation, const Model& model, ConversionData& data); 151 | 152 | static bool ConvertTanH(const Operation& operation, const Model& model, ConversionData& data); 153 | 154 | static bool ConvertTranspose(const Operation& operation, const Model& model, ConversionData& data); 155 | 156 | static bool ConvertTransposeConv2d(const Operation& operation, const Model& model, ConversionData& data); 157 | 158 | static bool ConvertTile(const Operation& operation, const Model& model, ConversionData& data); 159 | 160 | static bool ConvertUnidirectionalSequenceLstm(const Operation& operation, 161 | const Model& model, 162 | ConversionData& data); 163 | }; 164 | 165 | } // namespace hal_1_2 166 | } // namespace armnn_driver 167 | -------------------------------------------------------------------------------- /1.3/ArmnnDriverImpl.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2020 Arm Ltd. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #include "../CacheDataHandler.hpp" 11 | #include "../DriverOptions.hpp" 12 | 13 | #include 14 | 15 | #if !defined(ARMNN_ANDROID_S) 16 | using namespace android::nn::hal; 17 | #endif 18 | 19 | #ifdef ARMNN_ANDROID_S 20 | using namespace android::hardware; 21 | #endif 22 | 23 | namespace V1_0 = ::android::hardware::neuralnetworks::V1_0; 24 | namespace V1_2 = ::android::hardware::neuralnetworks::V1_2; 25 | namespace V1_3 = ::android::hardware::neuralnetworks::V1_3; 26 | 27 | namespace armnn_driver 28 | { 29 | namespace hal_1_3 30 | { 31 | 32 | class ArmnnDriverImpl 33 | { 34 | public: 35 | using HidlToken = android::hardware::hidl_array; 36 | 37 | static Return prepareArmnnModel_1_3( 38 | const armnn::IRuntimePtr& runtime, 39 | const armnn::IGpuAccTunedParametersPtr& clTunedParameters, 40 | const DriverOptions& options, 41 | const V1_3::Model& model, 42 | const android::hardware::hidl_vec& modelCacheHandle, 43 | const android::hardware::hidl_vec& dataCacheHandle, 44 | const HidlToken& token, 45 | const android::sp& cb, 46 | bool float32ToFloat16 = false, 47 | V1_3::Priority priority = V1_3::Priority::MEDIUM); 48 | 49 | static Return prepareModelFromCache_1_3( 50 | const armnn::IRuntimePtr& runtime, 51 | const DriverOptions& options, 52 | const android::hardware::hidl_vec& modelCacheHandle, 53 | const android::hardware::hidl_vec& dataCacheHandle, 54 | const HidlToken& token, 55 | const android::sp& cb); 56 | 57 | static Return getCapabilities_1_3(const armnn::IRuntimePtr& runtime, 58 | V1_3::IDevice::getCapabilities_1_3_cb cb); 59 | }; 60 | 61 | } // namespace hal_1_3 62 | } // namespace armnn_driver -------------------------------------------------------------------------------- /1.3/HalPolicy.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2020-2023 Arm Ltd and Contributors. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #pragma once 7 | 8 | #include "../ConversionUtils.hpp" 9 | #include "../ConversionUtils_1_2.hpp" 10 | #include "../ConversionUtils_1_3.hpp" 11 | 12 | #include 13 | 14 | #include 15 | 16 | namespace V1_3 = ::android::hardware::neuralnetworks::V1_3; 17 | 18 | namespace armnn_driver 19 | { 20 | namespace hal_1_3 21 | { 22 | 23 | class HalPolicy 24 | { 25 | public: 26 | using Model = V1_3::Model; 27 | using Operand = V1_3::Operand; 28 | using OperandLifeTime = V1_3::OperandLifeTime; 29 | using OperandType = V1_3::OperandType; 30 | using Operation = V1_3::Operation; 31 | using OperationType = V1_3::OperationType; 32 | using ExecutionCallback = V1_3::IExecutionCallback; 33 | using getSupportedOperations_cb = V1_3::IDevice::getSupportedOperations_1_3_cb; 34 | using ErrorStatus = V1_3::ErrorStatus; 35 | 36 | static bool ConvertOperation(const Operation& operation, const Model& model, ConversionData& data); 37 | 38 | private: 39 | static bool ConvertArgMinMax(const Operation& operation, 40 | const Model& model, 41 | ConversionData& data, 42 | armnn::ArgMinMaxFunction argMinMaxFunction); 43 | 44 | static bool ConvertAveragePool2d(const Operation& operation, const Model& model, ConversionData& data); 45 | 46 | static bool ConvertBatchToSpaceNd(const Operation& operation, const Model& model, ConversionData& data); 47 | 48 | static bool ConvertCast(const Operation& operation, const Model& model, ConversionData& data); 49 | 50 | static bool ConvertChannelShuffle(const Operation& operation, const Model& model, ConversionData& data); 51 | 52 | static bool ConvertComparison(const Operation& operation, 53 | const Model& model, 54 | ConversionData& data, 55 | armnn::ComparisonOperation comparisonOperation); 56 | 57 | static bool ConvertConcatenation(const Operation& operation, const Model& model, ConversionData& data); 58 | 59 | static bool ConvertConv2d(const Operation& operation, const Model& model, ConversionData& data); 60 | 61 | static bool ConvertDepthToSpace(const Operation& operation, const Model& model, ConversionData& data); 62 | 63 | static bool ConvertDepthwiseConv2d(const Operation& operation, const Model& model, ConversionData& data); 64 | 65 | static bool ConvertDequantize(const Operation& operation, const Model& model, ConversionData& data); 66 | 67 | static bool ConvertElementwiseBinary(const Operation& operation, 68 | const Model& model, 69 | ConversionData& data, 70 | armnn::BinaryOperation binaryOperation); 71 | 72 | static bool ConvertElementwiseUnary(const Operation& operation, 73 | const Model& model, 74 | ConversionData& data, 75 | armnn::UnaryOperation unaryOperation); 76 | 77 | static bool ConvertElu(const Operation& operation, const Model& model, ConversionData& data); 78 | 79 | static bool ConvertExpandDims(const Operation& operation, const Model& model, ConversionData& data); 80 | 81 | static bool ConvertFill(const Operation& operation, const Model& model, ConversionData& data); 82 | 83 | static bool ConvertFloor(const Operation& operation, const Model& model, ConversionData& data); 84 | 85 | static bool ConvertFullyConnected(const Operation& operation, const Model& model, ConversionData& data); 86 | 87 | static bool ConvertGather(const Operation& operation, const Model& model, ConversionData& data); 88 | 89 | static bool ConvertGroupedConv2d(const Operation& operation, const Model& model, ConversionData& data); 90 | 91 | static bool ConvertHardSwish(const Operation& operation, const Model& model, ConversionData& data); 92 | 93 | static bool ConvertInstanceNormalization(const Operation& operation, const Model& model, ConversionData& data); 94 | 95 | static bool ConvertL2Normalization(const Operation& operation, const Model& model, ConversionData& data); 96 | 97 | static bool ConvertL2Pool2d(const Operation& operation, const Model& model, ConversionData& data); 98 | 99 | static bool ConvertLocalResponseNormalization(const Operation& operation, 100 | const Model& model, 101 | ConversionData& data); 102 | 103 | static bool ConvertLogicalBinary(const Operation& operation, 104 | const Model& model, 105 | ConversionData& data, 106 | armnn::LogicalBinaryOperation logicalOperation); 107 | 108 | static bool ConvertLogistic(const Operation& operation, const Model& model, ConversionData& data); 109 | 110 | static bool ConvertLogSoftmax(const Operation& operation, const Model& model, ConversionData& data); 111 | 112 | static bool ConvertLstm(const Operation& operation, const Model& model, ConversionData& data); 113 | 114 | static bool ConvertMaxPool2d(const Operation& operation, const Model& model, ConversionData& data); 115 | 116 | static bool ConvertMean(const Operation& operation, const Model& model, ConversionData& data); 117 | 118 | static bool ConvertPad(const Operation& operation, const Model& model, ConversionData& data); 119 | 120 | static bool ConvertPadV2(const Operation& operation, const Model& model, ConversionData& data); 121 | 122 | static bool ConvertPrelu(const Operation& operation, const Model& model, ConversionData& data); 123 | 124 | static bool ConvertQuantize(const Operation& operation, const Model& model, ConversionData& data); 125 | 126 | static bool ConvertQuantizedLstm(const Operation& operation, const Model& model, ConversionData& data); 127 | 128 | static bool ConvertQuantized16BitLstm(const Operation& operation, const Model& model, ConversionData& data); 129 | 130 | static bool ConvertRank(const Operation& operation, const Model& model, ConversionData& data); 131 | 132 | static bool ConvertReduce(const Operation& operation, 133 | const Model& model, 134 | ConversionData& data, 135 | ReduceOperation reduceOperation); 136 | 137 | static bool ConvertReLu(const Operation& operation, const Model& model, ConversionData& data); 138 | 139 | static bool ConvertReLu1(const Operation& operation, const Model& model, ConversionData& data); 140 | 141 | static bool ConvertReLu6(const Operation& operation, const Model& model, ConversionData& data); 142 | 143 | static bool ConvertReshape(const Operation& operation, const Model& model, ConversionData& data); 144 | 145 | static bool ConvertResize(const Operation& operation, 146 | const Model& model, 147 | ConversionData& data, 148 | armnn::ResizeMethod resizeMethod); 149 | 150 | static bool ConvertSoftmax(const Operation& operation, const Model& model, ConversionData& data); 151 | 152 | static bool ConvertSpaceToBatchNd(const Operation& operation, const Model& model, ConversionData& data); 153 | 154 | static bool ConvertSpaceToDepth(const Operation& operation, const Model& model, ConversionData& data); 155 | 156 | static bool ConvertSplit(const Operation& operation, const Model& model, ConversionData& data); 157 | 158 | static bool ConvertSqrt(const Operation& operation, const Model& model, ConversionData& data); 159 | 160 | static bool ConvertSqueeze(const Operation& operation, const Model& model, ConversionData& data); 161 | 162 | static bool ConvertStridedSlice(const Operation& operation, const Model& model, ConversionData& data); 163 | 164 | static bool ConvertTanH(const Operation& operation, const Model& model, ConversionData& data); 165 | 166 | static bool ConvertTranspose(const Operation& operation, const Model& model, ConversionData& data); 167 | 168 | static bool ConvertTransposeConv2d(const Operation& operation, const Model& model, ConversionData& data); 169 | 170 | static bool ConvertTile(const Operation& operation, const Model& model, ConversionData& data); 171 | 172 | static bool ConvertUnidirectionalSequenceLstm(const Operation& operation, 173 | const Model& model, 174 | ConversionData& data); 175 | }; 176 | 177 | } // namespace hal_1_3 178 | } // namespace armnn_driver 179 | -------------------------------------------------------------------------------- /Android.bp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 ARM Ltd. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | //////////////////////////////////////////// 7 | // // 8 | // flatbuffers libs // 9 | // // 10 | //////////////////////////////////////////// 11 | cc_defaults { 12 | name: "libflatbuffers-defaults", 13 | proprietary: true, 14 | export_include_dirs: [ "flatbuffers/", 15 | "flatbuffers/include", 16 | ], 17 | local_include_dirs: ["flatbuffers/include",], 18 | cflags: [ 19 | "-O3", 20 | "-fexceptions", 21 | "-Wno-unused-parameter", 22 | "-DFLATBUFFERS_BUILD_FLATC=1" 23 | ], 24 | cppflags: [ 25 | "-std=c++14" 26 | ], 27 | rtti: true, 28 | } 29 | 30 | cc_library_static { 31 | name: "libflatbuffers-framework", 32 | defaults: ["libflatbuffers-defaults"], 33 | srcs: [ 34 | "flatbuffers/src/flatc.cpp", 35 | "flatbuffers/src/flatc_main.cpp", 36 | ], 37 | } 38 | 39 | subdirs = [ 40 | "armnn", 41 | ] 42 | -------------------------------------------------------------------------------- /ArmnnDevice.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017, 2023 Arm Ltd. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #define LOG_TAG "ArmnnDriver" 7 | 8 | #include "ArmnnDevice.hpp" 9 | 10 | #include 11 | 12 | #include 13 | 14 | #include 15 | #include 16 | 17 | using namespace android; 18 | 19 | namespace 20 | { 21 | 22 | std::string GetBackendString(const armnn_driver::DriverOptions& options) 23 | { 24 | std::stringstream backends; 25 | for (auto&& b : options.GetBackends()) 26 | { 27 | backends << b << " "; 28 | } 29 | return backends.str(); 30 | } 31 | 32 | } // anonymous namespace 33 | 34 | namespace armnn_driver 35 | { 36 | 37 | ArmnnDevice::ArmnnDevice(DriverOptions options) 38 | : m_Runtime(nullptr, nullptr) 39 | , m_ClTunedParameters(nullptr) 40 | , m_Options(std::move(options)) 41 | { 42 | ALOGV("ArmnnDevice::ArmnnDevice()"); 43 | 44 | armnn::ConfigureLogging(false, m_Options.IsVerboseLoggingEnabled(), armnn::LogSeverity::Trace); 45 | if (m_Options.IsVerboseLoggingEnabled()) 46 | { 47 | SetMinimumLogSeverity(base::VERBOSE); 48 | } 49 | else 50 | { 51 | SetMinimumLogSeverity(base::INFO); 52 | } 53 | 54 | armnn::IRuntime::CreationOptions runtimeOptions; 55 | 56 | #if defined(ARMCOMPUTECL_ENABLED) 57 | try 58 | { 59 | if (!m_Options.GetClTunedParametersFile().empty()) 60 | { 61 | m_ClTunedParameters = armnn::IGpuAccTunedParameters::Create(m_Options.GetClTunedParametersMode(), 62 | m_Options.GetClTuningLevel()); 63 | try 64 | { 65 | m_ClTunedParameters->Load(m_Options.GetClTunedParametersFile().c_str()); 66 | } 67 | catch (std::exception& error) 68 | { 69 | // This is only a warning because the file won't exist the first time you are generating it. 70 | ALOGW("ArmnnDevice: Failed to load CL tuned parameters file '%s': %s", 71 | m_Options.GetClTunedParametersFile().c_str(), error.what()); 72 | } 73 | runtimeOptions.m_GpuAccTunedParameters = m_ClTunedParameters; 74 | } 75 | } 76 | catch (const armnn::ClRuntimeUnavailableException& error) 77 | { 78 | ALOGE("ArmnnDevice: Failed to setup CL runtime: %s. Device will be unavailable.", error.what()); 79 | } 80 | catch (std::exception& error) 81 | { 82 | ALOGE("ArmnnDevice: Unknown exception: %s. Device will be unavailable.", error.what()); 83 | } 84 | #endif 85 | runtimeOptions.m_EnableGpuProfiling = m_Options.IsGpuProfilingEnabled(); 86 | m_Runtime = armnn::IRuntime::Create(runtimeOptions); 87 | 88 | std::vector backends; 89 | 90 | if (m_Runtime) 91 | { 92 | const armnn::BackendIdSet supportedDevices = m_Runtime->GetDeviceSpec().GetSupportedBackends(); 93 | for (auto &backend : m_Options.GetBackends()) 94 | { 95 | if (std::find(supportedDevices.cbegin(), supportedDevices.cend(), backend) == supportedDevices.cend()) 96 | { 97 | ALOGW("ArmnnDevice: Requested unknown backend %s", backend.Get().c_str()); 98 | } 99 | else 100 | { 101 | backends.push_back(backend); 102 | } 103 | } 104 | } 105 | 106 | if (backends.empty()) 107 | { 108 | // No known backend specified 109 | throw armnn::InvalidArgumentException("ArmnnDevice: No known backend specified."); 110 | } 111 | 112 | m_Options.SetBackends(backends); 113 | ALOGV("ArmnnDevice: Created device with the following backends: %s", 114 | GetBackendString(m_Options).c_str()); 115 | } 116 | 117 | } // namespace armnn_driver 118 | -------------------------------------------------------------------------------- /ArmnnDevice.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Arm Ltd. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #pragma once 7 | 8 | #include "DriverOptions.hpp" 9 | 10 | #include 11 | 12 | namespace armnn_driver 13 | { 14 | 15 | class ArmnnDevice 16 | { 17 | protected: 18 | ArmnnDevice(DriverOptions options); 19 | virtual ~ArmnnDevice() {} 20 | 21 | protected: 22 | armnn::IRuntimePtr m_Runtime; 23 | armnn::IGpuAccTunedParametersPtr m_ClTunedParameters; 24 | DriverOptions m_Options; 25 | }; 26 | 27 | } // namespace armnn_driver 28 | -------------------------------------------------------------------------------- /ArmnnDriver.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Arm Ltd. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #include 11 | 12 | #ifdef ARMNN_ANDROID_NN_V1_3 // Using ::android::hardware::neuralnetworks::V1_3 13 | 14 | #include "1.1/ArmnnDriver.hpp" 15 | #include "1.2/ArmnnDriver.hpp" 16 | #include "1.3/ArmnnDriver.hpp" 17 | 18 | namespace armnn_driver 19 | { 20 | 21 | class ArmnnDriver : public hal_1_3::ArmnnDriver 22 | { 23 | public: 24 | ArmnnDriver(DriverOptions options) 25 | : hal_1_3::ArmnnDriver(std::move(options)) 26 | { 27 | ALOGV("ArmnnDriver::ArmnnDriver()"); 28 | } 29 | ~ArmnnDriver() {} 30 | }; 31 | 32 | } // namespace armnn_driver 33 | #elif ARMNN_ANDROID_NN_V1_2 // Using ::android::hardware::neuralnetworks::V1_2 34 | 35 | #include "1.1/ArmnnDriver.hpp" 36 | #include "1.2/ArmnnDriver.hpp" 37 | 38 | namespace armnn_driver 39 | { 40 | 41 | class ArmnnDriver : public hal_1_2::ArmnnDriver 42 | { 43 | public: 44 | ArmnnDriver(DriverOptions options) 45 | : hal_1_2::ArmnnDriver(std::move(options)) 46 | { 47 | ALOGV("ArmnnDriver::ArmnnDriver()"); 48 | } 49 | ~ArmnnDriver() {} 50 | }; 51 | 52 | } // namespace armnn_driver 53 | #elif ARMNN_ANDROID_NN_V1_1 // Using ::android::hardware::neuralnetworks::V1_1 54 | 55 | #include "1.1/ArmnnDriver.hpp" 56 | 57 | namespace armnn_driver 58 | { 59 | 60 | class ArmnnDriver : public hal_1_1::ArmnnDriver 61 | { 62 | public: 63 | ArmnnDriver(DriverOptions options) 64 | : hal_1_1::ArmnnDriver(std::move(options)) 65 | { 66 | ALOGV("ArmnnDriver::ArmnnDriver()"); 67 | } 68 | ~ArmnnDriver() {} 69 | }; 70 | 71 | } // namespace armnn_driver 72 | 73 | #else // Fallback to ::android::hardware::neuralnetworks::V1_0 74 | 75 | #include "1.0/ArmnnDriver.hpp" 76 | 77 | namespace armnn_driver 78 | { 79 | 80 | class ArmnnDriver : public hal_1_0::ArmnnDriver 81 | { 82 | public: 83 | ArmnnDriver(DriverOptions options) 84 | : hal_1_0::ArmnnDriver(std::move(options)) 85 | { 86 | ALOGV("ArmnnDriver::ArmnnDriver()"); 87 | } 88 | ~ArmnnDriver() {} 89 | }; 90 | 91 | } // namespace armnn_driver 92 | 93 | #endif 94 | -------------------------------------------------------------------------------- /ArmnnDriverImpl.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Arm Ltd. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #pragma once 7 | 8 | #include "DriverOptions.hpp" 9 | 10 | #include 11 | 12 | #ifdef ARMNN_ANDROID_R 13 | using namespace android::nn::hal; 14 | #endif 15 | 16 | #ifdef ARMNN_ANDROID_S 17 | using namespace android::hardware; 18 | #endif 19 | 20 | namespace V1_0 = ::android::hardware::neuralnetworks::V1_0; 21 | namespace V1_1 = ::android::hardware::neuralnetworks::V1_1; 22 | 23 | #ifdef ARMNN_ANDROID_NN_V1_2 // Using ::android::hardware::neuralnetworks::V1_2 24 | namespace V1_2 = ::android::hardware::neuralnetworks::V1_2; 25 | #endif 26 | 27 | #ifdef ARMNN_ANDROID_NN_V1_3 // Using ::android::hardware::neuralnetworks::V1_3 28 | namespace V1_2 = ::android::hardware::neuralnetworks::V1_2; 29 | namespace V1_3 = ::android::hardware::neuralnetworks::V1_3; 30 | #endif 31 | 32 | namespace armnn_driver 33 | { 34 | 35 | template 36 | struct CallbackContext 37 | { 38 | Callback callback; 39 | Context ctx; 40 | }; 41 | 42 | template 43 | class ArmnnDriverImpl 44 | { 45 | public: 46 | using HalModel = typename HalPolicy::Model; 47 | using HalGetSupportedOperations_cb = typename HalPolicy::getSupportedOperations_cb; 48 | using HalErrorStatus = typename HalPolicy::ErrorStatus; 49 | 50 | static Return getSupportedOperations( 51 | const armnn::IRuntimePtr& runtime, 52 | const DriverOptions& options, 53 | const HalModel& model, 54 | HalGetSupportedOperations_cb); 55 | 56 | static Return prepareModel( 57 | const armnn::IRuntimePtr& runtime, 58 | const armnn::IGpuAccTunedParametersPtr& clTunedParameters, 59 | const DriverOptions& options, 60 | const HalModel& model, 61 | const android::sp& cb, 62 | bool float32ToFloat16 = false); 63 | 64 | static Return getStatus(); 65 | 66 | }; 67 | 68 | } // namespace armnn_driver 69 | -------------------------------------------------------------------------------- /ArmnnPreparedModel.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Arm Ltd. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #pragma once 7 | 8 | #include "ArmnnDriver.hpp" 9 | #include "ArmnnDriverImpl.hpp" 10 | #include "RequestThread.hpp" 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | namespace armnn_driver 19 | { 20 | using armnnExecuteCallback_1_0 = std::function; 21 | 22 | struct ArmnnCallback_1_0 23 | { 24 | armnnExecuteCallback_1_0 callback; 25 | }; 26 | 27 | struct ExecutionContext_1_0 {}; 28 | 29 | using CallbackContext_1_0 = CallbackContext; 30 | 31 | template 32 | class ArmnnPreparedModel : public V1_0::IPreparedModel 33 | { 34 | public: 35 | using HalModel = typename HalVersion::Model; 36 | 37 | ArmnnPreparedModel(armnn::NetworkId networkId, 38 | armnn::IRuntime* runtime, 39 | const HalModel& model, 40 | const std::string& requestInputsAndOutputsDumpDir, 41 | const bool gpuProfilingEnabled, 42 | const bool importEnabled = false, 43 | const bool exportEnabled = false); 44 | 45 | virtual ~ArmnnPreparedModel(); 46 | 47 | virtual Return execute(const V1_0::Request& request, 48 | const ::android::sp& callback) override; 49 | 50 | /// execute the graph prepared from the request 51 | void ExecuteGraph(std::shared_ptr>& pMemPools, 52 | armnn::InputTensors& inputTensors, 53 | armnn::OutputTensors& outputTensors, 54 | CallbackContext_1_0 callback); 55 | 56 | /// Executes this model with dummy inputs (e.g. all zeroes). 57 | /// \return false on failure, otherwise true 58 | bool ExecuteWithDummyInputs(); 59 | 60 | private: 61 | 62 | template 63 | void DumpTensorsIfRequired(char const* tensorNamePrefix, const TensorBindingCollection& tensorBindings); 64 | 65 | armnn::NetworkId m_NetworkId; 66 | armnn::IRuntime* m_Runtime; 67 | HalModel m_Model; 68 | // There must be a single RequestThread for all ArmnnPreparedModel objects to ensure serial execution of workloads 69 | // It is specific to this class, so it is declared as static here 70 | static RequestThread m_RequestThread; 73 | uint32_t m_RequestCount; 74 | const std::string& m_RequestInputsAndOutputsDumpDir; 75 | const bool m_GpuProfilingEnabled; 76 | const bool m_EnableImport; 77 | const bool m_EnableExport; 78 | }; 79 | 80 | } 81 | -------------------------------------------------------------------------------- /ArmnnPreparedModel_1_2.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Arm Ltd. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #pragma once 7 | 8 | #include "ArmnnDriver.hpp" 9 | #include "ArmnnDriverImpl.hpp" 10 | #include "RequestThread.hpp" 11 | #include "ModelToINetworkConverter.hpp" 12 | 13 | #include 14 | #include 15 | 16 | #include 17 | #include 18 | 19 | namespace armnn_driver 20 | { 21 | 22 | using CallbackAsync_1_2 = std::function< 23 | void(V1_0::ErrorStatus errorStatus, 24 | std::vector<::android::hardware::neuralnetworks::V1_2::OutputShape> outputShapes, 25 | const ::android::hardware::neuralnetworks::V1_2::Timing& timing, 26 | std::string callingFunction)>; 27 | 28 | struct ExecutionContext_1_2 29 | { 30 | ::android::hardware::neuralnetworks::V1_2::MeasureTiming measureTimings = 31 | ::android::hardware::neuralnetworks::V1_2::MeasureTiming::NO; 32 | TimePoint driverStart; 33 | }; 34 | 35 | using CallbackContext_1_2 = CallbackContext; 36 | 37 | template 38 | class ArmnnPreparedModel_1_2 : public V1_2::IPreparedModel 39 | { 40 | public: 41 | using HalModel = typename V1_2::Model; 42 | 43 | ArmnnPreparedModel_1_2(armnn::NetworkId networkId, 44 | armnn::IRuntime* runtime, 45 | const HalModel& model, 46 | const std::string& requestInputsAndOutputsDumpDir, 47 | const bool gpuProfilingEnabled, 48 | const bool importEnabled = false, 49 | const bool exportEnabled = false); 50 | 51 | ArmnnPreparedModel_1_2(armnn::NetworkId networkId, 52 | armnn::IRuntime* runtime, 53 | const std::string& requestInputsAndOutputsDumpDir, 54 | const bool gpuProfilingEnabled, 55 | const bool importEnabled = false, 56 | const bool exportEnabled = false, 57 | const bool preparedFromCache = false); 58 | 59 | virtual ~ArmnnPreparedModel_1_2(); 60 | 61 | virtual Return execute(const V1_0::Request& request, 62 | const ::android::sp& callback) override; 63 | 64 | virtual Return execute_1_2(const V1_0::Request& request, V1_2::MeasureTiming measure, 65 | const ::android::sp& callback) override; 66 | 67 | virtual Return executeSynchronously(const V1_0::Request &request, 68 | V1_2::MeasureTiming measure, 69 | V1_2::IPreparedModel::executeSynchronously_cb cb) override; 70 | 71 | virtual Return configureExecutionBurst( 72 | const ::android::sp& callback, 73 | const android::hardware::MQDescriptorSync& requestChannel, 74 | const android::hardware::MQDescriptorSync& resultChannel, 75 | configureExecutionBurst_cb cb) override; 76 | 77 | /// execute the graph prepared from the request 78 | template 79 | bool ExecuteGraph(std::shared_ptr>& pMemPools, 80 | armnn::InputTensors& inputTensors, 81 | armnn::OutputTensors& outputTensors, 82 | CallbackContext callback); 83 | 84 | /// Executes this model with dummy inputs (e.g. all zeroes). 85 | /// \return false on failure, otherwise true 86 | bool ExecuteWithDummyInputs(unsigned int numInputs, unsigned int numOutputs); 87 | 88 | private: 89 | 90 | Return Execute(const V1_0::Request& request, 91 | V1_2::MeasureTiming measureTiming, 92 | CallbackAsync_1_2 callback); 93 | 94 | Return PrepareMemoryForInputs( 95 | armnn::InputTensors& inputs, 96 | const V1_0::Request& request, 97 | const std::vector& memPools); 98 | 99 | Return PrepareMemoryForOutputs( 100 | armnn::OutputTensors& outputs, 101 | std::vector &outputShapes, 102 | const V1_0::Request& request, 103 | const std::vector& memPools); 104 | 105 | Return PrepareMemoryForIO( 106 | armnn::InputTensors& inputs, 107 | armnn::OutputTensors& outputs, 108 | std::vector& memPools, 109 | const V1_0::Request& request, 110 | CallbackAsync_1_2 callback); 111 | 112 | template 113 | void DumpTensorsIfRequired(char const* tensorNamePrefix, const TensorBindingCollection& tensorBindings); 114 | 115 | armnn::NetworkId m_NetworkId; 116 | armnn::IRuntime* m_Runtime; 117 | V1_2::Model m_Model; 118 | // There must be a single RequestThread for all ArmnnPreparedModel objects to ensure serial execution of workloads 119 | // It is specific to this class, so it is declared as static here 120 | static RequestThread m_RequestThread; 123 | uint32_t m_RequestCount; 124 | const std::string& m_RequestInputsAndOutputsDumpDir; 125 | const bool m_GpuProfilingEnabled; 126 | const bool m_EnableImport; 127 | const bool m_EnableExport; 128 | const bool m_PreparedFromCache; 129 | }; 130 | 131 | } 132 | -------------------------------------------------------------------------------- /ArmnnPreparedModel_1_3.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2020 Arm Ltd. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #pragma once 7 | 8 | #include "ArmnnDriver.hpp" 9 | #include "ArmnnDriverImpl.hpp" 10 | #include "RequestThread_1_3.hpp" 11 | #include "ModelToINetworkConverter.hpp" 12 | 13 | #include 14 | #include 15 | 16 | 17 | #include 18 | #include 19 | 20 | namespace armnn_driver 21 | { 22 | using CallbackAsync_1_3 = std::function< 23 | void(V1_3::ErrorStatus errorStatus, 24 | std::vector<::android::hardware::neuralnetworks::V1_2::OutputShape> outputShapes, 25 | const ::android::hardware::neuralnetworks::V1_2::Timing& timing, 26 | std::string callingFunction)>; 27 | 28 | struct ExecutionContext_1_3 29 | { 30 | ::android::hardware::neuralnetworks::V1_2::MeasureTiming measureTimings = 31 | ::android::hardware::neuralnetworks::V1_2::MeasureTiming::NO; 32 | TimePoint driverStart; 33 | TimePoint driverEnd; 34 | TimePoint deviceStart; 35 | TimePoint deviceEnd; 36 | }; 37 | 38 | using CallbackContext_1_3 = CallbackContext; 39 | 40 | using executeFenced_cb = std::function& callback)>; 43 | 44 | template 45 | class ArmnnPreparedModel_1_3 : public V1_3::IPreparedModel 46 | { 47 | public: 48 | using HalModel = typename V1_3::Model; 49 | 50 | ArmnnPreparedModel_1_3(armnn::NetworkId networkId, 51 | armnn::IRuntime* runtime, 52 | const HalModel& model, 53 | const std::string& requestInputsAndOutputsDumpDir, 54 | const bool gpuProfilingEnabled, 55 | V1_3::Priority priority = V1_3::Priority::MEDIUM, 56 | const bool importEnabled = false, 57 | const bool exportEnabled = false); 58 | 59 | ArmnnPreparedModel_1_3(armnn::NetworkId networkId, 60 | armnn::IRuntime* runtime, 61 | const std::string& requestInputsAndOutputsDumpDir, 62 | const bool gpuProfilingEnabled, 63 | V1_3::Priority priority = V1_3::Priority::MEDIUM, 64 | const bool importEnabled = false, 65 | const bool exportEnabled = false, 66 | const bool preparedFromCache = false); 67 | 68 | virtual ~ArmnnPreparedModel_1_3(); 69 | 70 | Return execute(const V1_0::Request& request, 71 | const ::android::sp& callback) override; 72 | 73 | Return execute_1_2(const V1_0::Request& request, V1_2::MeasureTiming measure, 74 | const ::android::sp& callback) override; 75 | 76 | Return execute_1_3(const V1_3::Request& request, 77 | V1_2::MeasureTiming measure, 78 | const V1_3::OptionalTimePoint&, 79 | const V1_3::OptionalTimeoutDuration&, 80 | const ::android::sp& callback) override; 81 | 82 | Return executeSynchronously(const V1_0::Request &request, 83 | V1_2::MeasureTiming measure, 84 | V1_3::IPreparedModel::executeSynchronously_cb cb) override; 85 | 86 | Return executeSynchronously_1_3(const V1_3::Request &request, 87 | V1_2::MeasureTiming measure, 88 | const V1_3::OptionalTimePoint& deadline, 89 | const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, 90 | V1_3::IPreparedModel::executeSynchronously_1_3_cb cb) override; 91 | 92 | Return executeFenced(const V1_3::Request& request, 93 | const android::hardware::hidl_vec& fenceWaitFor, 94 | V1_2::MeasureTiming measure, 95 | const V1_3::OptionalTimePoint& deadline, 96 | const V1_3::OptionalTimeoutDuration& loopTimeoutDuration, 97 | const V1_3::OptionalTimeoutDuration& duration, 98 | executeFenced_cb callback) override; 99 | 100 | Return configureExecutionBurst( 101 | const ::android::sp& callback, 102 | const android::hardware::MQDescriptorSync& requestChannel, 103 | const android::hardware::MQDescriptorSync& resultChannel, 104 | configureExecutionBurst_cb cb) override; 105 | 106 | template 107 | Return ExecuteSynchronously(const V1_3::Request& request, CallbackContext cbCtx); 108 | 109 | /// execute the graph prepared from the request 110 | template 111 | Return ExecuteGraph( 112 | std::shared_ptr>& pMemPools, 113 | armnn::InputTensors& inputTensors, 114 | armnn::OutputTensors& outputTensors, 115 | CallbackContext callback); 116 | 117 | /// Executes this model with dummy inputs (e.g. all zeroes). 118 | /// \return false on failure, otherwise true 119 | bool ExecuteWithDummyInputs(unsigned int numInputs, unsigned int numOutputs); 120 | 121 | V1_3::Priority GetModelPriority(); 122 | 123 | private: 124 | 125 | Return Execute(const V1_3::Request& request, 126 | V1_2::MeasureTiming measureTiming, 127 | CallbackAsync_1_3 callback); 128 | 129 | Return PrepareMemoryForInputs( 130 | armnn::InputTensors& inputs, 131 | const V1_3::Request& request, 132 | const std::vector& memPools); 133 | 134 | Return PrepareMemoryForOutputs( 135 | armnn::OutputTensors& outputs, 136 | std::vector &outputShapes, 137 | const V1_3::Request& request, 138 | const std::vector& memPools); 139 | 140 | std::tuple, V1_2::Timing, std::string> PrepareMemoryForIO( 141 | armnn::InputTensors& inputs, 142 | armnn::OutputTensors& outputs, 143 | std::vector& memPools, 144 | const V1_3::Request& request); 145 | 146 | template 147 | void DumpTensorsIfRequired(char const* tensorNamePrefix, const TensorBindingCollection& tensorBindings); 148 | 149 | armnn::NetworkId m_NetworkId; 150 | armnn::IRuntime* m_Runtime; 151 | V1_3::Model m_Model; 152 | // There must be a single RequestThread for all ArmnnPreparedModel objects to ensure serial execution of workloads 153 | // It is specific to this class, so it is declared as static here 154 | static RequestThread_1_3 m_RequestThread; 157 | uint32_t m_RequestCount; 158 | const std::string& m_RequestInputsAndOutputsDumpDir; 159 | const bool m_GpuProfilingEnabled; 160 | V1_3::Priority m_ModelPriority; 161 | 162 | const bool m_EnableImport; 163 | const bool m_EnableExport; 164 | const bool m_PreparedFromCache; 165 | }; 166 | 167 | } 168 | -------------------------------------------------------------------------------- /CacheDataHandler.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2021 Arm Ltd and Contributors. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #include "CacheDataHandler.hpp" 7 | 8 | #include 9 | 10 | namespace armnn_driver 11 | { 12 | 13 | CacheDataHandler& CacheDataHandlerInstance() 14 | { 15 | static CacheDataHandler instance; 16 | return instance; 17 | } 18 | 19 | void CacheDataHandler::Register(const HidlToken token, const size_t hashValue, const size_t cacheSize) 20 | { 21 | if (m_CacheDataMap.find(hashValue) != m_CacheDataMap.end() 22 | && m_CacheDataMap.at(hashValue).GetToken() == token 23 | && m_CacheDataMap.at(hashValue).GetCacheSize() == cacheSize) 24 | { 25 | ALOGV("CacheHandler::Register() Hash value has already registered."); 26 | return; 27 | } 28 | CacheHandle cacheHandle(token, cacheSize); 29 | m_CacheDataMap.insert({hashValue, cacheHandle}); 30 | } 31 | 32 | bool CacheDataHandler::Validate(const HidlToken token, const size_t hashValue, const size_t cacheSize) const 33 | { 34 | return (m_CacheDataMap.find(hashValue) != m_CacheDataMap.end() 35 | && m_CacheDataMap.at(hashValue).GetToken() == token 36 | && m_CacheDataMap.at(hashValue).GetCacheSize() == cacheSize); 37 | } 38 | 39 | size_t CacheDataHandler::Hash(std::vector& cacheData) 40 | { 41 | std::size_t hash = cacheData.size(); 42 | for (auto& i : cacheData) 43 | { 44 | hash = ((hash << 5) - hash) + i; 45 | } 46 | return hash; 47 | } 48 | 49 | size_t CacheDataHandler::GetCacheSize(HidlToken token) 50 | { 51 | for (auto i = m_CacheDataMap.begin(); i != m_CacheDataMap.end(); ++i) 52 | { 53 | if (i->second.GetToken() == token) 54 | { 55 | return i->second.GetCacheSize(); 56 | } 57 | } 58 | return 0; 59 | } 60 | 61 | void CacheDataHandler::Clear() 62 | { 63 | m_CacheDataMap.clear(); 64 | } 65 | 66 | } // armnn_driver 67 | -------------------------------------------------------------------------------- /CacheDataHandler.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2021 Arm Ltd and Contributors. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | namespace armnn_driver 16 | { 17 | 18 | using HidlToken = android::hardware::hidl_array; 19 | 20 | class CacheHandle 21 | { 22 | public: 23 | CacheHandle(const HidlToken token, const size_t cacheSize) 24 | : m_HidlToken(token), m_CacheSize(cacheSize) {} 25 | 26 | ~CacheHandle() {}; 27 | 28 | HidlToken GetToken() const 29 | { 30 | return m_HidlToken; 31 | } 32 | 33 | size_t GetCacheSize() const 34 | { 35 | return m_CacheSize; 36 | } 37 | 38 | private: 39 | const HidlToken m_HidlToken; 40 | const size_t m_CacheSize; 41 | }; 42 | 43 | class CacheDataHandler 44 | { 45 | public: 46 | CacheDataHandler() {} 47 | ~CacheDataHandler() {} 48 | 49 | void Register(const HidlToken token, const size_t hashValue, const size_t cacheSize); 50 | 51 | bool Validate(const HidlToken token, const size_t hashValue, const size_t cacheSize) const; 52 | 53 | size_t Hash(std::vector& cacheData); 54 | 55 | size_t GetCacheSize(HidlToken token); 56 | 57 | void Clear(); 58 | 59 | private: 60 | CacheDataHandler(const CacheDataHandler&) = delete; 61 | CacheDataHandler& operator=(const CacheDataHandler&) = delete; 62 | 63 | std::unordered_map m_CacheDataMap; 64 | }; 65 | 66 | CacheDataHandler& CacheDataHandlerInstance(); 67 | 68 | } // armnn_driver 69 | -------------------------------------------------------------------------------- /ConversionUtils.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017,2022 Arm Ltd and Contributors. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #include "ConversionUtils.hpp" 7 | #include 8 | 9 | /// 10 | /// Helper classes 11 | /// 12 | 13 | namespace armnn_driver 14 | { 15 | 16 | LayerInputHandle::LayerInputHandle() 17 | : m_OutputSlot(nullptr) 18 | , m_Valid(false) 19 | {} 20 | 21 | LayerInputHandle::LayerInputHandle(bool valid, armnn::IOutputSlot* outputSlot, armnn::TensorInfo tensorInfo) 22 | : m_OutputSlot(outputSlot) 23 | , m_Valid(valid) 24 | , m_TensorInfo(tensorInfo) 25 | {} 26 | 27 | bool LayerInputHandle::IsValid() const 28 | { 29 | return m_Valid; 30 | } 31 | 32 | void LayerInputHandle::Connect(armnn::IInputSlot& inputSlot) 33 | { 34 | if (!IsValid()) 35 | { 36 | throw armnn::RuntimeException("LayerInputHandle is invalid"); 37 | } 38 | 39 | if (m_OutputSlot) 40 | { 41 | m_OutputSlot->Connect(inputSlot); 42 | } 43 | } 44 | 45 | void LayerInputHandle::Disconnect(armnn::IInputSlot& inputSlot) 46 | { 47 | if (!IsValid()) 48 | { 49 | throw armnn::RuntimeException("LayerInputHandle is invalid"); 50 | } 51 | if (m_OutputSlot) 52 | { 53 | m_OutputSlot->Disconnect(inputSlot); 54 | } 55 | } 56 | 57 | const armnn::TensorInfo& LayerInputHandle::GetTensorInfo() const 58 | { 59 | return m_TensorInfo; 60 | } 61 | 62 | void LayerInputHandle::SanitizeQuantizationScale(LayerInputHandle& weight, 63 | LayerInputHandle& input) 64 | { 65 | if (m_OutputSlot) 66 | { 67 | armnn::TensorInfo weightInfo = weight.GetTensorInfo(); 68 | armnn::TensorInfo inputInfo = input.GetTensorInfo(); 69 | armnn::TensorInfo biasInfo = GetTensorInfo(); 70 | 71 | SanitizeBiasQuantizationScale(biasInfo, weightInfo, inputInfo); 72 | 73 | m_TensorInfo = biasInfo; 74 | m_OutputSlot->SetTensorInfo(biasInfo); 75 | } 76 | } 77 | 78 | ConstTensorPin::ConstTensorPin(bool optional) 79 | : m_Optional(optional) 80 | {} 81 | 82 | ConstTensorPin::ConstTensorPin(armnn::TensorInfo& tensorInfo, 83 | const void* valueStart, 84 | uint32_t numBytes, 85 | const armnn::PermutationVector& mappings) 86 | : m_Optional(false) 87 | { 88 | armnn::IgnoreUnused(numBytes); 89 | if (tensorInfo.GetNumBytes() != numBytes) 90 | { 91 | ALOGW("The size of ConstTensor does not match its TensorInfo."); 92 | } 93 | 94 | const bool needsSwizzling = (mappings.GetSize() > 0); 95 | if (needsSwizzling) 96 | { 97 | m_SwizzledTensorData.resize(tensorInfo.GetNumBytes()); 98 | SwizzleAndroidNn4dTensorToArmNn(tensorInfo, valueStart, m_SwizzledTensorData.data(), mappings); 99 | 100 | m_ConstTensor = armnn::ConstTensor(tensorInfo, m_SwizzledTensorData.data()); 101 | } 102 | else 103 | { 104 | m_ConstTensor = armnn::ConstTensor(tensorInfo, valueStart); 105 | } 106 | } 107 | 108 | bool ConstTensorPin::IsValid() const 109 | { 110 | return m_ConstTensor.GetMemoryArea() != nullptr; 111 | } 112 | 113 | bool ConstTensorPin::IsOptional() const 114 | { 115 | return m_Optional; 116 | } 117 | 118 | const armnn::ConstTensor& ConstTensorPin::GetConstTensor() const 119 | { 120 | return m_ConstTensor; 121 | } 122 | 123 | const armnn::ConstTensor* ConstTensorPin::GetConstTensorPtr() const 124 | { 125 | if (IsValid() && m_ConstTensor.GetNumElements() > 0) 126 | { 127 | return &m_ConstTensor; 128 | } 129 | // tensor is either invalid, or has no elements (indicating an optional tensor that was not provided) 130 | return nullptr; 131 | } 132 | 133 | /// 134 | /// Utility functions 135 | /// 136 | 137 | armnn::IConnectableLayer* ProcessActivation(const armnn::TensorInfo& tensorInfo, 138 | ActivationFn activation, 139 | armnn::IConnectableLayer* prevLayer, 140 | ConversionData& data) 141 | { 142 | if (prevLayer->GetNumOutputSlots() != 1) 143 | { 144 | Fail("%s: Incorrect Number of OutputSlots expected 1 was %i", __func__, prevLayer->GetNumOutputSlots()); 145 | return nullptr; 146 | } 147 | prevLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo); 148 | 149 | armnn::IConnectableLayer* activationLayer = prevLayer; 150 | 151 | if (activation != ActivationFn::kActivationNone) 152 | { 153 | armnn::ActivationDescriptor activationDesc; 154 | switch (activation) 155 | { 156 | case ActivationFn::kActivationRelu: 157 | { 158 | activationDesc.m_Function = armnn::ActivationFunction::ReLu; 159 | break; 160 | } 161 | case ActivationFn::kActivationRelu1: 162 | { 163 | activationDesc.m_Function = armnn::ActivationFunction::BoundedReLu; 164 | activationDesc.m_A = 1.0f; 165 | activationDesc.m_B = -1.0f; 166 | break; 167 | } 168 | case ActivationFn::kActivationRelu6: 169 | { 170 | activationDesc.m_Function = armnn::ActivationFunction::BoundedReLu; 171 | activationDesc.m_A = 6.0f; 172 | break; 173 | } 174 | case ActivationFn::kActivationSigmoid: 175 | { 176 | activationDesc.m_Function = armnn::ActivationFunction::Sigmoid; 177 | break; 178 | } 179 | case ActivationFn::kActivationTanh: 180 | { 181 | activationDesc.m_Function = armnn::ActivationFunction::TanH; 182 | activationDesc.m_A = 1.0f; 183 | activationDesc.m_B = 1.0f; 184 | break; 185 | } 186 | default: 187 | { 188 | Fail("%s: Invalid activation enum value %i", __func__, activation); 189 | return nullptr; 190 | } 191 | } 192 | 193 | bool isSupported = false; 194 | armnn::BackendId setBackend; 195 | FORWARD_LAYER_SUPPORT_FUNC(__func__, 196 | IsActivationSupported, 197 | data.m_Backends, 198 | isSupported, 199 | setBackend, 200 | prevLayer->GetOutputSlot(0).GetTensorInfo(), 201 | tensorInfo, 202 | activationDesc); 203 | if (!isSupported) 204 | { 205 | return nullptr; 206 | } 207 | 208 | activationLayer = data.m_Network->AddActivationLayer(activationDesc); 209 | activationLayer->SetBackendId(setBackend); 210 | 211 | prevLayer->GetOutputSlot(0).Connect(activationLayer->GetInputSlot(0)); 212 | activationLayer->GetOutputSlot(0).SetTensorInfo(tensorInfo); 213 | } 214 | 215 | return activationLayer; 216 | } 217 | 218 | } // namespace armnn_driver 219 | -------------------------------------------------------------------------------- /DriverOptions.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Arm Ltd. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #pragma once 7 | 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | namespace armnn_driver 15 | { 16 | 17 | class DriverOptions 18 | { 19 | public: 20 | DriverOptions(armnn::Compute computeDevice, bool fp16Enabled = false); 21 | DriverOptions(const std::vector& backends, bool fp16Enabled); 22 | DriverOptions(int argc, char** argv); 23 | DriverOptions(DriverOptions&& other) = default; 24 | 25 | const std::vector& GetBackends() const { return m_Backends; } 26 | bool IsVerboseLoggingEnabled() const { return m_VerboseLogging; } 27 | const std::string& GetRequestInputsAndOutputsDumpDir() const { return m_RequestInputsAndOutputsDumpDir; } 28 | const std::string& GetServiceName() const { return m_ServiceName; } 29 | const std::set& GetForcedUnsupportedOperations() const { return m_ForcedUnsupportedOperations; } 30 | const std::string& GetClTunedParametersFile() const { return m_ClTunedParametersFile; } 31 | const std::string& GetClMLGOTunedParametersFile() const { return m_ClMLGOTunedParametersFile; } 32 | armnn::IGpuAccTunedParameters::Mode GetClTunedParametersMode() const { return m_ClTunedParametersMode; } 33 | armnn::IGpuAccTunedParameters::TuningLevel GetClTuningLevel() const { return m_ClTuningLevel; } 34 | bool IsGpuProfilingEnabled() const { return m_EnableGpuProfiling; } 35 | bool IsFastMathEnabled() const { return m_FastMathEnabled; } 36 | bool GetFp16Enabled() const { return m_fp16Enabled; } 37 | void SetBackends(const std::vector& backends) { m_Backends = backends; } 38 | bool ShouldExit() const { return m_ShouldExit; } 39 | int GetExitCode() const { return m_ExitCode; } 40 | const std::string& GetCachedNetworkFilePath() const { return m_CachedNetworkFilePath; } 41 | bool SaveCachedNetwork() const { return m_SaveCachedNetwork; } 42 | unsigned int GetNumberOfThreads() const { return m_NumberOfThreads; } 43 | bool isImportEnabled() const { return m_EnableImport; }; 44 | bool isExportEnabled() const { return m_EnableExport; }; 45 | 46 | private: 47 | std::vector m_Backends; 48 | bool m_VerboseLogging; 49 | std::string m_RequestInputsAndOutputsDumpDir; 50 | std::string m_ServiceName; 51 | std::set m_ForcedUnsupportedOperations; 52 | std::string m_ClTunedParametersFile; 53 | std::string m_ClMLGOTunedParametersFile; 54 | armnn::IGpuAccTunedParameters::Mode m_ClTunedParametersMode; 55 | armnn::IGpuAccTunedParameters::TuningLevel m_ClTuningLevel; 56 | bool m_EnableGpuProfiling; 57 | bool m_fp16Enabled; 58 | bool m_FastMathEnabled; 59 | bool m_ShouldExit; 60 | int m_ExitCode; 61 | std::string m_CachedNetworkFilePath; 62 | bool m_SaveCachedNetwork; 63 | unsigned int m_NumberOfThreads; 64 | bool m_EnableImport; 65 | bool m_EnableExport; 66 | }; 67 | 68 | } // namespace armnn_driver 69 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 ARM Limited. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /LICENSES/MIT.txt: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 6 | 7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 8 | 9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 10 | -------------------------------------------------------------------------------- /ModelToINetworkConverter.hpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Arm Ltd. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #pragma once 7 | 8 | #include "ArmnnDriver.hpp" 9 | #include "ConversionUtils.hpp" 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | 16 | namespace armnn_driver 17 | { 18 | 19 | enum class ConversionResult 20 | { 21 | Success, 22 | ErrorMappingPools, 23 | UnsupportedFeature 24 | }; 25 | 26 | // A helper template class performing the conversion from an AndroidNN driver Model representation, 27 | // to an armnn::INetwork object 28 | template 29 | class ModelToINetworkConverter 30 | { 31 | public: 32 | using HalModel = typename HalPolicy::Model; 33 | 34 | ModelToINetworkConverter(const std::vector& backends, 35 | const HalModel& model, 36 | const std::set& forcedUnsupportedOperations); 37 | 38 | ConversionResult GetConversionResult() const { return m_ConversionResult; } 39 | 40 | // Returns the ArmNN INetwork corresponding to the input model, if preparation went smoothly, nullptr otherwise. 41 | armnn::INetwork* GetINetwork() const { return m_Data.m_Network.get(); } 42 | 43 | bool IsOperationSupported(uint32_t operationIndex) const; 44 | 45 | private: 46 | void Convert(); 47 | 48 | // Shared aggregate input/output/internal data 49 | ConversionData m_Data; 50 | 51 | // Input data 52 | const HalModel& m_Model; 53 | const std::set& m_ForcedUnsupportedOperations; 54 | 55 | // Output data 56 | ConversionResult m_ConversionResult; 57 | std::map m_OperationSupported; 58 | }; 59 | 60 | } // armnn_driver 61 | -------------------------------------------------------------------------------- /NnapiSupport.txt: -------------------------------------------------------------------------------- 1 | ------ ArmNN for Android NNAPI supported operations ------ 2 | 3 | This release of ArmNN for Android supports use as a driver for the Android Neural Networks API. It implements the 4 | android.hardware.neuralnetworks@1.0, android.hardware.neuralnetworks@1.1, android.hardware.neuralnetworks@1.2 and 5 | android.hardware.neuralnetworks@1.3 6 | HAL interfaces. 7 | 8 | For more information on the Android Neural Networks API, see https://developer.android.com/ndk/guides/neuralnetworks/index.html 9 | 10 | For integration and usage documentation, please see README.md. 11 | 12 | --- Support for Android Neural Networks HAL operations --- 13 | 14 | The following AndroidNN HAL 1.0, 1.1, 1.2 and 1.3 operations are currently supported: 15 | 16 | AndroidNN operator Tensor type supported 17 | ABS (FLOAT32, FLOAT16, INT32) 18 | ADD (FLOAT32, FLOAT16, INT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 19 | ARGMAX (FLOAT32, FLOAT16, INT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 20 | ARGMIN (FLOAT32, FLOAT16, INT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 21 | AVERAGE_POOL_2D (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 22 | BATCH_TO_SPACE_ND (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 23 | CAST (FLOAT32, FLOAT16, INT32, QUANT8_ASYMM) 24 | CHANNEL_SHUFFLE (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 25 | CONCATENATION (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 26 | CONV_2D (FLOAT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 27 | DEPTH_TO_SPACE (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 28 | DEPTHWISE_CONV_2D (FLOAT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 29 | DEQUANTIZE (FLOAT32 (output only), QUANT8_ASYMM and QUANT8_ASYMM_SIGNED (input only)) 30 | DIV (FLOAT32, FLOAT16, INT32) 31 | ELU (FLOAT32, FLOAT16, QUANT8_ASYMM) 32 | EQUAL (BOOL8, FLOAT32, FLOAT16, INT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 33 | EXP (FLOAT32, FLOAT16) 34 | EXPAND_DIMS (FLOAT32, FLOAT16, INT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 35 | FILL (FLOAT32, FLOAT16, INT32) 36 | FLOOR (FLOAT32, FLOAT16) 37 | FULLY_CONNECTED (FLOAT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 38 | GATHER (FLOAT32, FLOAT16, INT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 39 | GREATER (BOOL8, FLOAT32, FLOAT16, INT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 40 | GREATER_EQUAL (BOOL8, FLOAT32, FLOAT16, INT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 41 | GROUPED_CONV_2D (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 42 | HARD_SWISH (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 43 | INSTANCE_NORMALIZATION (FLOAT32, FLOAT16) 44 | L2_NORMALIZATION (FLOAT32) 45 | L2_POOL_2D (FLOAT32, FLOAT16) 46 | LESS (BOOL8, FLOAT32, FLOAT16, INT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 47 | LESS_EQUAL (BOOL8, FLOAT32, FLOAT16, INT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 48 | LOCAL_RESPONSE_NORMALIZATION (FLOAT32) 49 | LOG (FLOAT32, FLOAT16) 50 | LOGICAL_AND (BOOL8) 51 | LOGICAL_NOT (BOOL8) 52 | LOGICAL_OR (BOOL8) 53 | LOGISTIC (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 54 | LOG_SOFTMAX (FLOAT32, FLOAT16) 55 | LSTM (FLOAT32) 56 | MAXIMUM (FLOAT32, FLOAT16, INT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 57 | MAX_POOL_2D (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 58 | MEAN (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 59 | MINIMUM (FLOAT32, FLOAT16, INT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 60 | MUL (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 61 | NEG (FLOAT32, FLOAT16) 62 | NOT_EQUAL (BOOL8, FLOAT32, FLOAT16, INT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 63 | PAD (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 64 | PAD_V2 (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 65 | POW (FLOAT32, FLOAT16) 66 | PRELU (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 67 | QUANTIZE (FLOAT32 (input only), QUANT8_ASYMM and QUANT8_ASYMM_SIGNED (output only)) 68 | QUANTIZED_16BIT_LSTM (QUANT8_ASYMM) 69 | QUANTIZED_LSTM (QUANT8_ASYMM) 70 | RANK (FLOAT32, FLOAT16, INT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 71 | REDUCE_MAX (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 72 | REDUCE_MIN (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 73 | REDUCE_PROD (FLOAT32, FLOAT16) 74 | REDUCE_SUM (FLOAT32, FLOAT16) 75 | RELU (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 76 | RELU1 (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 77 | RELU6 (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 78 | RESHAPE (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 79 | RESIZE_BILINEAR (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 80 | RESIZE_NEAREST_NEIGHBOR (FLOAT32, FLOAT16, QUANT8_ASYMM) 81 | RSQRT (FLOAT32, FLOAT16) 82 | SIN (FLOAT32, FLOAT16) 83 | SOFTMAX (FLOAT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 84 | SPACE_TO_BATCH_ND (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 85 | SPACE_TO_DEPTH (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 86 | SPLIT (FLOAT32, FLOAT16, INT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 87 | SQRT (FLOAT32, FLOAT16) 88 | SQUEEZE (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 89 | STRIDED_SLICE (FLOAT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 90 | SUB (FLOAT32, FLOAT16, INT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 91 | TANH (FLOAT32, FLOAT16, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 92 | TILE (All data types) 93 | TRANSPOSE (FLOAT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 94 | TRANSPOSE_CONV_2D (FLOAT32, QUANT8_ASYMM, QUANT8_ASYMM_SIGNED) 95 | UNIDIRECTIONAL_SEQUENCE_LSTM (FLOAT32, FLOAT16) 96 | 97 | Where operations are not supported by the ArmNN Android NN Driver, the driver indicates this to the framework 98 | appropriately and the framework implements those operations using a CPU implementation. 99 | 100 | NOTE: By convention, only those tensor types have been listed above, which are fully supported across all 101 | ArmNN backends. 102 | - FLOAT16 input tensors are partially supported on most HAL 1.2 and 1.3 operators on the GpuAcc and 103 | CpuRef backends, however not on CpuAcc. 104 | -------------------------------------------------------------------------------- /NnapiSupport.txt.license: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright © 2018-2022 Arm Ltd and Contributors. All rights reserved. 3 | # SPDX-License-Identifier: MIT 4 | # 5 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Arm NN Android Neural Networks driver 2 | 3 | This directory contains the Arm NN driver for the Android Neural Networks API, implementing the HIDL based android.hardware.neuralnetworks@1.0, android.hardware.neuralnetworks@1.1, android.hardware.neuralnetworks@1.2 and android.hardware.neuralnetworks@1.3 HALs. 4 | 5 | For Android 11 and lower, the NNAPI uses HIDL based HALs. 6 | 7 | For Android 12 and Android 13, the NNAPI HAL revision uses AIDL instead of HIDL, and HIDL is deprecated. 8 | 9 | For Android 14 the compatibility matrix no longer includes support for HIDL HAL revisions: 10 | https://android.googlesource.com/platform/hardware/interfaces/+/refs/heads/android14-qpr1-release/compatibility_matrices/compatibility_matrix.8.xml 11 | 12 | For more information about supported operations and configurations, see [NnapiSupport.txt](NnapiSupport.txt) 13 | 14 | For documentation about integrating this driver into an Android tree, see [Integrator Guide](docs/IntegratorGuide.md) 15 | 16 | For FAQs and troubleshooting advice, see [FAQ.md](docs/FAQ.md) 17 | 18 | ### License 19 | 20 | The android-nn-driver is provided under the [MIT](https://spdx.org/licenses/MIT.html) license. 21 | See [LICENSE](LICENSE) for more information. Contributions to this project are accepted under the same license. 22 | 23 | Individual files contain the following tag instead of the full license text. 24 | 25 | SPDX-License-Identifier: MIT 26 | 27 | This enables machine processing of license information based on the SPDX License Identifiers that are available here: http://spdx.org/licenses/ 28 | -------------------------------------------------------------------------------- /README.md.license: -------------------------------------------------------------------------------- 1 | # 2 | # Copyright © 2018-2021 Arm Ltd and Contributors. All rights reserved. 3 | # SPDX-License-Identifier: MIT 4 | # 5 | -------------------------------------------------------------------------------- /RequestThread.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright © 2017 Arm Ltd and Contributors. All rights reserved. 3 | // SPDX-License-Identifier: MIT 4 | // 5 | 6 | #define LOG_TAG "ArmnnDriver" 7 | 8 | #include "RequestThread.hpp" 9 | #include "ArmnnPreparedModel.hpp" 10 | 11 | #ifdef ARMNN_ANDROID_NN_V1_2 12 | #include "ArmnnPreparedModel_1_2.hpp" 13 | #endif 14 | 15 | #ifdef ARMNN_ANDROID_NN_V1_3 16 | #include "ArmnnPreparedModel_1_2.hpp" 17 | #include "ArmnnPreparedModel_1_3.hpp" 18 | #endif 19 | 20 | #include 21 | 22 | using namespace android; 23 | 24 | namespace armnn_driver 25 | { 26 | 27 | template