aboutsummaryrefslogtreecommitdiff
path: root/delegate/common
diff options
context:
space:
mode:
authorMatthew Sloyan <matthew.sloyan@arm.com>2023-03-16 10:17:51 +0000
committerMatthew Sloyan <matthew.sloyan@arm.com>2023-04-03 09:20:43 +0000
commit1157232551c23c9a553aed37972b8119d37c4543 (patch)
treeb1e55023c0f7b7d0f65a012f700c91fbf659a3d1 /delegate/common
parent1a05aad6d5adf3b25848ffd873a0e0e82756aa06 (diff)
downloadarmnn-1157232551c23c9a553aed37972b8119d37c4543.tar.gz
IVGCVSW-7558 Implement Delegate Utils
* Implement OpaqueDelegateUtils.hpp using new accessors. * Moved classic delegate utils to ClassicDelegateUtils.hpp. * DelegateUtils.hpp now contains common utils. * Removed unused ConnectConstant function. Signed-off-by: Matthew Sloyan <matthew.sloyan@arm.com> Change-Id: I0fa611c82f5c06b0b7e0c37bfc343e09fb6a96c9
Diffstat (limited to 'delegate/common')
-rw-r--r--delegate/common/src/DelegateUtils.hpp531
1 files changed, 2 insertions, 529 deletions
diff --git a/delegate/common/src/DelegateUtils.hpp b/delegate/common/src/DelegateUtils.hpp
index 1aa9029271..b953699016 100644
--- a/delegate/common/src/DelegateUtils.hpp
+++ b/delegate/common/src/DelegateUtils.hpp
@@ -19,134 +19,17 @@
#include <tensorflow/lite/c/builtin_op_data.h>
#include <tensorflow/lite/c/common.h>
#include <tensorflow/lite/minimal_logging.h>
-
-#include "tensorflow/lite/kernels/kernel_util.h"
+#include <tensorflow/lite/kernels/kernel_util.h>
namespace
{
-// Macro to call an Is<layer_name>Supported function and log caller name together with reason for lack of support
-#define FORWARD_LAYER_SUPPORT_FUNC(opName, tfLiteContext, func, backends, supported, setBackend, ...) \
-try \
-{ \
- for (auto&& backendId : backends) \
- { \
- auto layerSupportObject = armnn::GetILayerSupportByBackendId(backendId); \
- if (layerSupportObject.IsBackendRegistered()) \
- { \
- std::string reasonIfUnsupported; \
- supported = \
- layerSupportObject.func(__VA_ARGS__, armnn::Optional<std::string&>(reasonIfUnsupported)); \
- if (supported) \
- { \
- setBackend = backendId; \
- break; \
- } \
- else \
- { \
- if (reasonIfUnsupported.size() > 0) \
- { \
- TFLITE_LOG_PROD(tflite::TFLITE_LOG_WARNING, \
- "%s: not supported by armnn: %s", opName, reasonIfUnsupported.c_str()); \
- } \
- else \
- { \
- TFLITE_LOG_PROD(tflite::TFLITE_LOG_WARNING, \
- "%s: not supported by armnn", opName); \
- } \
- } \
- } \
- else \
- { \
- TF_LITE_KERNEL_LOG(tfLiteContext, "%s: backend not registered: %s", opName, backendId.Get().c_str()); \
- } \
- } \
- if (!supported) \
- { \
- TF_LITE_KERNEL_LOG(tfLiteContext, "%s: not supported by any specified backend", opName); \
- } \
-} \
-catch (const armnn::InvalidArgumentException &e) \
-{ \
- throw armnn::InvalidArgumentException(e, "Failed to check layer support", CHECK_LOCATION()); \
-}
-
-TfLiteStatus ValidateNumInputs(TfLiteContext* tfLiteContext,
- TfLiteNode* tfLiteNode,
- const unsigned int expectedSize,
- int nodeIndex)
-{
- auto numInputs = tfLiteNode->inputs->size;
- if (static_cast<unsigned int >(numInputs) != expectedSize)
- {
- TF_LITE_MAYBE_KERNEL_LOG(
- tfLiteContext, "TfLiteArmnnDelegate: Unexpected number of inputs (%d != %d) in node #%d",
- numInputs, expectedSize, nodeIndex);
- return kTfLiteError;
- }
- return kTfLiteOk;
-}
-
-TfLiteStatus ValidateNumOutputs(TfLiteContext* tfLiteContext,
- TfLiteNode* tfLiteNode,
- const unsigned int expectedSize,
- int nodeIndex)
-{
- auto numOutputs = tfLiteNode->outputs->size;
- if (static_cast<unsigned int >(numOutputs) != expectedSize)
- {
- TF_LITE_MAYBE_KERNEL_LOG(
- tfLiteContext, "TfLiteArmnnDelegate: Unexpected number of outputs (%d != %d) in node #%d",
- numOutputs, expectedSize, nodeIndex);
- return kTfLiteError;
- }
- return kTfLiteOk;
-}
-
-bool IsDynamicTensor(const TfLiteTensor& tfLiteTensor)
-{
- auto tensorAllocationType = tfLiteTensor.allocation_type;
- if (tensorAllocationType == kTfLiteDynamic)
- {
- return true;
- }
- return false;
-}
-
-bool IsValid(const TfLiteTensor* tfLiteTensor)
-{
- return tfLiteTensor == nullptr ? false : true;
-}
-
-bool IsValid(TfLiteContext* tfLiteContext, const TfLiteTensor& tfLiteTensor, int32_t operatorCode, int32_t nodeIndex)
-{
- if(!IsValid(&tfLiteTensor))
- {
- std::cout << "..Is Not Valid" << std::endl;
- TF_LITE_MAYBE_KERNEL_LOG(
- tfLiteContext,
- "TfLiteArmnnDelegate: Invalid TfLite tensor in operator #%d node #%d: ",
- operatorCode, nodeIndex);
- return false;
- }
- if (IsDynamicTensor(tfLiteTensor))
- {
- std::cout << "..IsDynamicTensor" << std::endl;
- TF_LITE_MAYBE_KERNEL_LOG(
- tfLiteContext,
- "TfLiteArmnnDelegate: Dynamic tensors are not supported in operator #%d node #%d: ",
- operatorCode, nodeIndex);
- return false;
- }
- return true;
-}
-
uint32_t NonNegative(int32_t value, int nodeIndex)
{
if (value < 0)
{
throw armnn::Exception(
- "TfLiteArmnnDelegate: Non-negative value in node " + std::to_string(static_cast<int>(nodeIndex)));
+ "TfLiteArmnnDelegate: Non-negative value in node " + std::to_string(static_cast<int>(nodeIndex)));
}
else
{
@@ -154,41 +37,6 @@ uint32_t NonNegative(int32_t value, int nodeIndex)
}
}
-bool IsAffineQuantization(const TfLiteTensor& tfLiteTensor)
-{
- auto quantizationInfo = tfLiteTensor.quantization;
- if (quantizationInfo.type == kTfLiteAffineQuantization)
- {
- return true;
- }
- return false;
-}
-
-TfLiteStatus Connect(armnn::IConnectableLayer* layer,
- TfLiteNode* tfLiteNode,
- armnnDelegate::DelegateData& data)
-{
- ARMNN_ASSERT(static_cast<unsigned int>(tfLiteNode->outputs->size) == layer->GetNumOutputSlots());
-
- // Connect the input slots
- for (unsigned int inputIndex = 0; inputIndex < layer->GetNumInputSlots(); ++inputIndex)
- {
- if (data.m_OutputSlotForNode[tfLiteNode->inputs->data[inputIndex]] != nullptr)
- {
- data.m_OutputSlotForNode[tfLiteNode->inputs->data[inputIndex]]->Connect(layer->GetInputSlot(inputIndex));
- }
- }
-
- // Prepare output slots
- for (unsigned int outputIndex = 0; outputIndex < layer->GetNumOutputSlots(); ++outputIndex)
- {
- armnn::IOutputSlot& outputSlot = layer->GetOutputSlot(outputIndex);
- data.m_OutputSlotForNode[static_cast<unsigned long>(tfLiteNode->outputs->data[outputIndex])] = &outputSlot;
- }
-
- return kTfLiteOk;
-}
-
void ExpandTensorRankToEqual(armnn::TensorInfo& inputInfo0,
armnn::TensorInfo& inputInfo1)
{
@@ -207,295 +55,6 @@ void ExpandTensorRankToEqual(armnn::TensorInfo& inputInfo0,
const armnn::TensorShape& newShape = armnnUtils::ExpandDimsToRank(smallInfo.GetShape(), biggerInputDimensions);
smallInfo.SetShape(newShape);
-
-}
-
-TfLiteStatus FusedActivation(TfLiteContext* tfLiteContext,
- TfLiteNode* tfLiteNode,
- TfLiteFusedActivation activationType,
- armnn::IConnectableLayer* prevLayer,
- unsigned int outputSlotIndex,
- armnnDelegate::DelegateData& data)
-{
-
- const armnn::TensorInfo& activationOutputInfo = prevLayer->GetOutputSlot(outputSlotIndex).GetTensorInfo();
-
- armnn::ActivationDescriptor activationDesc;
-
- switch (activationType)
- {
- case kTfLiteActNone:
- {
- // No Activation
- return kTfLiteOk;
- }
- case kTfLiteActRelu:
- {
- activationDesc.m_Function = armnn::ActivationFunction::ReLu;
- break;
- }
-// The name of kTfLiteActRelu1 changed after TF Lite v2.3
-#if defined(ARMNN_POST_TFLITE_2_3)
- case kTfLiteActReluN1To1:
-#else
- case kTfLiteActRelu1:
-#endif
- {
- activationDesc.m_Function = armnn::ActivationFunction::BoundedReLu;
- activationDesc.m_A = 1.0f;
- activationDesc.m_B = -1.0f;
- break;
- }
- case kTfLiteActRelu6:
- {
- activationDesc.m_Function = armnn::ActivationFunction::BoundedReLu;
- activationDesc.m_A = 6.0f;
- activationDesc.m_B = 0.0f;
- break;
- }
- case kTfLiteActSigmoid:
- {
- activationDesc.m_Function = armnn::ActivationFunction::Sigmoid;
- break;
- }
- case kTfLiteActTanh:
- {
- activationDesc.m_Function = armnn::ActivationFunction::TanH;
- activationDesc.m_A = 1.0f;
- activationDesc.m_B = 1.0f;
- break;
- }
- default:
- return kTfLiteError;
- }
-
- bool isSupported = false;
- armnn::BackendId setBackend;
- FORWARD_LAYER_SUPPORT_FUNC("ACTIVATION",
- tfLiteContext,
- IsActivationSupported,
- data.m_Backends,
- isSupported,
- setBackend,
- activationOutputInfo,
- activationOutputInfo,
- activationDesc);
- if (!isSupported)
- {
- return kTfLiteError;
- }
- armnn::IConnectableLayer* activationLayer = data.m_Network->AddActivationLayer(activationDesc);
- activationLayer->SetBackendId(setBackend);
-
- ARMNN_ASSERT(activationLayer != nullptr);
- activationLayer->GetOutputSlot(0).SetTensorInfo(activationOutputInfo);
-
- // Connect and prepare output slots
- for (unsigned int outputIndex = 0; outputIndex < activationLayer->GetNumOutputSlots(); ++outputIndex)
- {
- data.m_OutputSlotForNode[static_cast<unsigned long>(
- tfLiteNode->outputs->data[outputIndex])]->Connect(activationLayer->GetInputSlot(0));
- armnn::IOutputSlot& outputSlot = activationLayer->GetOutputSlot(outputIndex);
- data.m_OutputSlotForNode[static_cast<unsigned long>(
- tfLiteNode->outputs->data[outputIndex])] = &outputSlot;
- }
- return kTfLiteOk;
-}
-
-armnn::IConnectableLayer* AddReshapeLayer(TfLiteContext* tfLiteContext,
- TfLiteNode* tfLiteNode,
- armnn::IConnectableLayer* prevLayer,
- armnn::TensorInfo reshapedOutputTensorInfo,
- armnn::TensorInfo outputTensorInfo,
- armnnDelegate::DelegateData& data)
-{
- armnn::ReshapeDescriptor desc;
- desc.m_TargetShape = outputTensorInfo.GetShape();
-
- bool isSupported = false;
- armnn::BackendId setBackend;
- FORWARD_LAYER_SUPPORT_FUNC("RESHAPE",
- tfLiteContext,
- IsReshapeSupported,
- data.m_Backends,
- isSupported,
- setBackend,
- reshapedOutputTensorInfo,
- outputTensorInfo,
- desc);
-
- if (!isSupported)
- {
- return nullptr;
- }
-
- armnn::IConnectableLayer* reshapeLayer = data.m_Network->AddReshapeLayer(desc);
- reshapeLayer->SetBackendId(setBackend);
- ARMNN_ASSERT(reshapeLayer != nullptr);
-
- prevLayer->GetOutputSlot(0).SetTensorInfo(reshapedOutputTensorInfo);
- reshapeLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);
-
- // Connect and prepare output slots
- for (unsigned int outputIndex = 0; outputIndex < reshapeLayer->GetNumOutputSlots(); ++outputIndex)
- {
- data.m_OutputSlotForNode[static_cast<unsigned long>(
- tfLiteNode->outputs->data[outputIndex])]->Connect(reshapeLayer->GetInputSlot(0));
- armnn::IOutputSlot& outputSlot = reshapeLayer->GetOutputSlot(outputIndex);
- data.m_OutputSlotForNode[static_cast<unsigned long>(
- tfLiteNode->outputs->data[outputIndex])] = &outputSlot;
- }
- return reshapeLayer;
-}
-
-armnn::DataType GetDataType(const TfLiteTensor& tfLiteTensor)
-{
- switch (tfLiteTensor.type)
- {
- case kTfLiteBool:
- return armnn::DataType::Boolean;
- case kTfLiteFloat32:
- return armnn::DataType::Float32;
- case kTfLiteFloat16:
- return armnn::DataType::Float16;
- case kTfLiteUInt8:
- return armnn::DataType::QAsymmU8;
- case kTfLiteInt8:
- {
- auto quantizationInfo = tfLiteTensor.quantization;
- if (quantizationInfo.type == kTfLiteAffineQuantization)
- {
- auto* quantization =
- reinterpret_cast<TfLiteAffineQuantization*>(tfLiteTensor.quantization.params);
- if (quantization->zero_point != nullptr && quantization->zero_point->size == 1)
- {
- return armnn::DataType::QAsymmS8;
- }
- else
- {
- return armnn::DataType::QSymmS8;
- }
- }
- else
- {
- return armnn::DataType::QAsymmS8;
- }
- }
- case kTfLiteInt16:
- return armnn::DataType::QSymmS16;
- case kTfLiteInt32:
- return armnn::DataType::Signed32;
- case kTfLiteInt64:
- return armnn::DataType::Signed64;
- default:
- throw armnn::Exception(&"TfLiteArmnnDelegate: Unsupported data type: " [ tfLiteTensor.type]);
- }
-}
-
-armnn::TensorInfo GetTensorInfoForTfLiteTensor(const TfLiteTensor& tfLiteTensor, bool isOutput = false)
-{
- armnn::DataType type = GetDataType(tfLiteTensor);
- armnn::TensorInfo ret;
- auto tensorDimensionSize = tfLiteTensor.dims->size;
- if (tensorDimensionSize == 0)
- {
- // If input tensor does not have a shape
- // assuming that it has 1D tensor
- if (!isOutput)
- {
- std::vector<unsigned int> safeShape = { 1 };
- bool dimensionsSpecificity[1] = { true };
- armnn::TensorShape tensorShape(armnn::numeric_cast<unsigned int>(safeShape.size()),
- safeShape.data(),
- dimensionsSpecificity);
- ret = armnn::TensorInfo(tensorShape, type);
- if(tflite::IsConstantTensor(&tfLiteTensor))
- {
- ret.SetConstant(true);
- }
- }
- else
- {
- armnn::TensorShape tensorShape(armnn::Dimensionality::NotSpecified);
- ret = armnn::TensorInfo(tensorShape, type);
- }
- }
- else
- {
- std::vector<unsigned int> tensorDims(static_cast<unsigned int>(tensorDimensionSize));
- bool dimensionsSpecificity[5] = { true, true, true, true, true };
- for (unsigned int i = 0; i < static_cast<unsigned int>(tensorDimensionSize); ++i) {
- auto dim = tfLiteTensor.dims->data[i];
- if (dim == 0)
- {
- dimensionsSpecificity[i] = false;
- }
- tensorDims[i] = static_cast<unsigned int>(dim);
- }
- armnn::TensorShape tensorShape(static_cast<unsigned int>(tensorDimensionSize),
- tensorDims.data(),
- dimensionsSpecificity);
-
- if(tflite::IsConstantTensor(&tfLiteTensor))
- {
- ret = armnn::TensorInfo(tensorShape, type);
- ret.SetConstant(true);
- }
- else
- {
- ret = armnn::TensorInfo(tensorShape, type);
- }
- }
-
- auto quantizationInfo = tfLiteTensor.quantization;
- if (quantizationInfo.type == kTfLiteAffineQuantization)
- {
- // get per-channel quantization parameters
- const auto* affineQuantization =
- reinterpret_cast<TfLiteAffineQuantization*>(tfLiteTensor.quantization.params);
- if (affineQuantization->scale->size > 1)
- {
- std::vector<float> quantizationScales;
- for (unsigned int i = 0; i < static_cast<unsigned int>(affineQuantization->scale->size); ++i)
- {
- quantizationScales.push_back(affineQuantization->scale->data[i]);
- }
- ret.SetQuantizationScales(quantizationScales);
- ret.SetQuantizationDim(armnn::numeric_cast<unsigned int>(affineQuantization->quantized_dimension));
- }
- else
- {
- ret.SetQuantizationScale(affineQuantization->scale->data[0]);
- ret.SetQuantizationOffset(affineQuantization->zero_point->data[0]);
- }
- }
- else
- {
- auto quantizationParameters = tfLiteTensor.params;
- ret.SetQuantizationScale(quantizationParameters.scale);
- ret.SetQuantizationOffset(quantizationParameters.zero_point);
- }
-
- return ret;
-}
-
-armnn::ConstTensor CreateConstTensor(const TfLiteTensor* tfLiteTensor,
- const armnn::TensorInfo& tensorInfo)
-{
- if (tfLiteTensor->allocation_type != kTfLiteMmapRo)
- {
- throw armnn::Exception(
- "TfLiteArmnnDelegate: Not constant allocation type: " + std::to_string(tfLiteTensor->allocation_type));
- }
-
- return armnn::ConstTensor(tensorInfo, tfLiteTensor->data.data);
-}
-
-armnn::ConstTensor* GetConstTensorForTfLiteTensor(const TfLiteTensor* tfLiteTensors, TfLiteNode* tfLiteNode, int index)
-{
- const TfLiteTensor &tfLiteTensor = tfLiteTensors[tfLiteNode->inputs->data[index]];
- armnn::TensorInfo tensorInfo = GetTensorInfoForTfLiteTensor(tfLiteTensor);
- return new armnn::ConstTensor(tensorInfo, tfLiteTensor.data.data);
}
void CalcPadding(uint32_t inputSize,
@@ -521,91 +80,6 @@ void CalcPadding(uint32_t inputSize,
}
}
-TfLiteStatus ConnectConstant(armnn::IConnectableLayer* layer,
- const armnn::TensorInfo& constTensorInfo,
- TfLiteContext* tfLiteContext,
- const TfLiteTensor& tfLiteTensor,
- armnnDelegate::DelegateData& data,
- unsigned int slotIndex)
-{
- IgnoreUnused(layer);
- bool isSupported = false;
- armnn::BackendId setBackend;
- FORWARD_LAYER_SUPPORT_FUNC("CONSTANT",
- tfLiteContext,
- IsConstantSupported,
- data.m_Backends,
- isSupported,
- setBackend,
- constTensorInfo);
- if (!isSupported)
- {
- return kTfLiteError;
- }
-
- auto constantInput = CreateConstTensor(&tfLiteTensor,
- constTensorInfo);
- armnn::IConnectableLayer* constantLayer = data.m_Network->AddConstantLayer(constantInput);
- constantLayer->SetBackendId(setBackend);
- armnn::IOutputSlot& outputSlot = constantLayer->GetOutputSlot(0);
- outputSlot.SetTensorInfo(constTensorInfo);
-
- data.m_OutputSlotForNode[static_cast<unsigned long>(slotIndex)] = &outputSlot;
-
- return kTfLiteOk;
-}
-
-bool IsOptionalOperandPresent(TfLiteNode* tfLiteNode, const int operandIndex)
-{
- // If the inputs array has fewer than operandIndex entries or if the entry at operandIndex has a value of -1 or
- // less then the input is not present.
- if (tfLiteNode->inputs->size > operandIndex && tfLiteNode->inputs->data[operandIndex] >= 0)
- {
- return true;
- }
- return false;
-}
-
-TfLiteStatus ProcessInputs(armnn::IConnectableLayer* layer,
- armnnDelegate::DelegateData& delegateData,
- TfLiteContext* tfLiteContext,
- TfLiteNode* tfLiteNode)
-{
- const TfLiteTensor* tfLiteTensors = tfLiteContext->tensors;
- // Process input tensors
- // If input tensor is a Constant tensor create a constant layer and connect it to the network
- for (unsigned int inputIndex = 0; inputIndex < layer->GetNumInputSlots(); ++inputIndex)
- {
- const TfLiteTensor& tfLiteInputTensor = tfLiteTensors[tfLiteNode->inputs->data[inputIndex]];
- if (tflite::IsConstantTensor(&tfLiteInputTensor))
- {
- armnn::TensorInfo inputTensorInfo = GetTensorInfoForTfLiteTensor(tfLiteInputTensor);
- bool isSupported = false;
- armnn::BackendId setBackend;
- FORWARD_LAYER_SUPPORT_FUNC("CONSTANT",
- tfLiteContext,
- IsConstantSupported,
- delegateData.m_Backends,
- isSupported,
- setBackend,
- inputTensorInfo);
- if (!isSupported)
- {
- return kTfLiteError;
- }
- auto constantInput = CreateConstTensor(&tfLiteInputTensor,
- inputTensorInfo);
- armnn::IConnectableLayer* constantLayer = delegateData.m_Network->AddConstantLayer(constantInput);
- constantLayer->SetBackendId(setBackend);
- armnn::IOutputSlot& outputSlot = constantLayer->GetOutputSlot(0);
- outputSlot.SetTensorInfo(inputTensorInfo);
-
- delegateData.m_OutputSlotForNode[tfLiteNode->inputs->data[inputIndex]] = &outputSlot;
- }
- }
- return kTfLiteOk;
-}
-
unsigned int ComputeWrappedIndex(int index, unsigned int numDimensions)
{
int numDims = armnn::numeric_cast<int>(numDimensions);
@@ -633,7 +107,6 @@ void UpdateConstantTensorOutputs(const armnn::TensorInfo& inputInfo, armnn::Tens
{
outputInfo.SetShape(inputInfo.GetShape());
}
- return;
}
} // namespace anonymous