//
// Copyright © 2017-2023 Arm Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//

#include "TfLiteParser.hpp"

#include "armnnTfLiteParser/Version.hpp"
#include "armnn/LstmParams.hpp"

#include <armnn/BackendOptions.hpp>
#include <armnn/Descriptors.hpp>
#include <armnn/Exceptions.hpp>
#include <armnn/Logging.hpp>
#include <armnn/Tensor.hpp>
#include <armnnUtils/TensorUtils.hpp>
#include <armnn/TypesUtils.hpp>
#include <armnn/utility/Assert.hpp>
#include <armnn/utility/IgnoreUnused.hpp>
#include <armnn/utility/NumericCast.hpp>
#include <armnn/LayerSupport.hpp>

// armnnUtils:
#include <armnnUtils/Permute.hpp>
#include <armnnUtils/Filesystem.hpp>

#include <ParserHelper.hpp>
#include <VerificationHelpers.hpp>

// The generated code based on the Tf Lite schema:
#include <schema_generated.h>

#include <flatbuffers/flexbuffers.h>

#include <fmt/format.h>

#include <algorithm>
#include <iostream>
#include <limits>
#include <numeric>

#define ARMNN_THROW_PARSE_EXCEPTION(msg) \
          { \
            throw armnn::ParseException( static_cast<const std::stringstream&>( std::stringstream() << msg \
               << ": " \
               << CHECK_LOCATION().AsString()).str()); \
          }

using namespace armnn;
using armnn::CheckLocation;
namespace armnnTfLiteParser
{

ITfLiteParser::ITfLiteParser(const armnn::Optional<TfLiteParserOptions>& options) :
    pTfLiteParserImpl(new TfLiteParserImpl(options)) {}

ITfLiteParser::~ITfLiteParser() = default;

ITfLiteParser* ITfLiteParser::CreateRaw(const armnn::Optional<TfLiteParserOptions>& options)
{
    return new ITfLiteParser(options);
}

ITfLiteParserPtr ITfLiteParser::Create(const armnn::Optional<TfLiteParserOptions>& options)
{
    return ITfLiteParserPtr(CreateRaw(options), &ITfLiteParser::Destroy);
}

void ITfLiteParser::Destroy(ITfLiteParser* parser)
{
    delete parser;
}

armnn::INetworkPtr ITfLiteParser::CreateNetworkFromBinaryFile(const char* graphFile)
{
    return pTfLiteParserImpl->CreateNetworkFromBinaryFile(graphFile);
}

armnn::INetworkPtr ITfLiteParser::CreateNetworkFromBinary(const std::vector<uint8_t>& binaryContent)
{
    return pTfLiteParserImpl->CreateNetworkFromBinary(binaryContent);
}

BindingPointInfo ITfLiteParser::GetNetworkInputBindingInfo(size_t subgraphId,
                                                           const std::string& name) const
{
    return pTfLiteParserImpl->GetNetworkInputBindingInfo(subgraphId, name);
}

BindingPointInfo ITfLiteParser::GetNetworkOutputBindingInfo(size_t subgraphId,
                                                            const std::string& name) const
{
    return pTfLiteParserImpl->GetNetworkOutputBindingInfo(subgraphId, name);
}

size_t ITfLiteParser::GetSubgraphCount() const
{
    return pTfLiteParserImpl->GetSubgraphCount();
}

std::vector<std::string> ITfLiteParser::GetSubgraphInputTensorNames(size_t subgraphId) const
{
    return pTfLiteParserImpl->GetSubgraphInputTensorNames(subgraphId);
}

std::vector<std::string> ITfLiteParser::GetSubgraphOutputTensorNames(size_t subgraphId) const
{
    return pTfLiteParserImpl->GetSubgraphOutputTensorNames(subgraphId);
}

namespace
{

const uint32_t VIRTUAL_OPERATOR_ID = std::numeric_limits<uint32_t>::max();

void CheckSubgraph(const TfLiteParserImpl::ModelPtr& model,
                   size_t subgraphIndex,
                   const CheckLocation& location)
{
    if (model.get() == nullptr)
    {
        throw ParseException(
            fmt::format("{} was called with invalid (null) model. "
                        "Possible reason is that the model is not yet loaded and Unpack(ed). "
                        "subgraph:{} at {}",
                        location.m_Function,
                        subgraphIndex,
                        location.FileLine()));
    }
    else if (subgraphIndex >= model->subgraphs.size())
    {
        throw ParseException(
            fmt::format("{} was called with an invalid subgraph index. "
                        "subgraph:{} at {}",
                        location.m_Function,
                        subgraphIndex,
                        location.FileLine()));
    }
}

#define CHECK_SUBGRAPH(MODEL, SUBGRAPH_INDEX) \
    CheckSubgraph(MODEL, SUBGRAPH_INDEX, CHECK_LOCATION())

void CheckModel(const TfLiteParserImpl::ModelPtr& model,
                size_t subgraphIndex,
                size_t operatorIndex,
                const CheckLocation& location)
{
    if (model.get() == nullptr)
    {
        throw ParseException(
            fmt::format("{} was called with invalid (null) model. "
                        "Possible reason is that the model is not yet loaded and Unpack(ed). "
                        "subgraph:{} operator:{} at {}",
                        location.m_Function,
                        subgraphIndex,
                        operatorIndex,
                        location.FileLine()));
    }
    else if (subgraphIndex >= model->subgraphs.size())
    {
        throw ParseException(
            fmt::format("{} was called with an invalid subgraph index. "
                        "subgraph:{} operator:{} at {}",
                        location.m_Function,
                        subgraphIndex,
                        operatorIndex,
                        location.FileLine()));
    }
    else if (operatorIndex >= model->subgraphs[subgraphIndex]->operators.size() &&
             operatorIndex != VIRTUAL_OPERATOR_ID)
    {
        throw ParseException(
            fmt::format("{} was called with an invalid operator index. "
                        "subgraph:{} operator:{} at {}",
                        location.m_Function,
                        subgraphIndex,
                        operatorIndex,
                        location.FileLine()));
    }
}

#define CHECK_MODEL(MODEL, SUBGRAPH_INDEX, OPERATOR_INDEX) \
    CheckModel(MODEL, SUBGRAPH_INDEX, OPERATOR_INDEX, CHECK_LOCATION())

void CheckTensor(const TfLiteParserImpl::ModelPtr& model,
                 size_t subgraphIndex,
                 size_t tensorIndex,
                 const CheckLocation& location)
{
    // not checking model, because I assume CHECK_MODEL already run
    // and checked that. An assert would do.
    ARMNN_ASSERT_MSG(model.get() != nullptr, "Expecting a valid model in this function");

    // also subgraph index should be checked by CHECK_MODEL so
    // I only add an assert here
    ARMNN_ASSERT_MSG(subgraphIndex < model->subgraphs.size(), "Expecting a valid subgraph index");

    // the tensor index is the only one to check here
    if (tensorIndex >= model->subgraphs[subgraphIndex]->tensors.size())
    {
        throw ParseException(
            fmt::format("{} was called with an invalid tensor index. "
                        "subgraph:{} tensor:{} at {}",
                        location.m_Function,
                        subgraphIndex,
                        tensorIndex,
                        location.FileLine()));
    }
}

#define CHECK_TENSOR(MODEL, SUBGRAPH_INDEX, TENSOR_INDEX) \
    CheckTensor(MODEL, SUBGRAPH_INDEX, TENSOR_INDEX, CHECK_LOCATION())

void CheckTensorPtr(TfLiteParserImpl::TensorRawPtr rawPtr,
                    const CheckLocation& location)
{
    if (rawPtr == nullptr)
    {
        throw ParseException(
            fmt::format("{} was called with a null tensor pointer at {}", location.m_Function, location.FileLine()));
    }
}

#define CHECK_TENSOR_PTR(TENSOR_PTR) \
    CheckTensorPtr(TENSOR_PTR, CHECK_LOCATION())

void CheckBuffer(const TfLiteParserImpl::ModelPtr& model,
                 size_t bufferIndex,
                 const CheckLocation& location)
{
    if (model.get() == nullptr)
    {
        throw ParseException(
            fmt::format("{} was called with invalid (null) model. "
                        "Possible reason is that the model is not yet loaded and Unpack(ed). "
                        "buffer:{} at {}",
                        location.m_Function,
                        bufferIndex,
                        location.FileLine()));
    }
    else if (bufferIndex >= model->buffers.size())
    {
        throw ParseException(
            fmt::format("{} was called with an invalid buffer index. "
                        "buffer index:{} at {}",
                        location.m_Function,
                        bufferIndex,
                        location.FileLine()));
    }
    else if (model->buffers[bufferIndex].get() == nullptr)
    {
        throw ParseException(
            fmt::format("The buffer #{} is null. {}",
                        bufferIndex,
                        location.AsString()));
    }
}

#define CHECK_BUFFER(MODEL, BUFFER_INDEX) \
    CheckBuffer(MODEL, BUFFER_INDEX, CHECK_LOCATION())

void CheckBufferSize(TfLiteParserImpl::BufferRawPtr bufferPtr,
                     const armnn::TensorInfo& tensorInfo,
                     uint32_t bufferId,
                     const CheckLocation& location)
{
    if (bufferPtr == nullptr)
    {
        throw ParseException(
            fmt::format("BufferPtr is null for buffer:{}. {}",
                        bufferId,
                        location.AsString()));
    }
    else if(tensorInfo.GetNumElements() > bufferPtr->data.size() ||
            tensorInfo.GetNumBytes() > bufferPtr->data.size())
    {
        std::stringstream ss;
        ss << "Buffer #" << bufferId << " has " << bufferPtr->data.size() << " bytes. "
           << "For tensor: " << tensorInfo.GetShape()
           << " expecting: " << tensorInfo.GetNumBytes() << " bytes and "
           << tensorInfo.GetNumElements() << " elements. " << location.AsString();
        throw ParseException(ss.str());
    }
}


tflite::BuiltinOperator GetOpCode(const TfLiteParserImpl::ModelPtr& model, size_t subgraphIndex, size_t operatorIndex)
{
    const auto& operatorPtr = model->subgraphs[subgraphIndex]->operators[operatorIndex];
    auto opcodeIndex = operatorPtr->opcode_index;

// work around the introduction of the deprecated_builtin_code introduced in 2.4 in a backwards compatible manner
#if defined(ARMNN_POST_TFLITE_2_3)
    auto opcode = std::max(model->operator_codes[opcodeIndex]->builtin_code,
            static_cast<tflite::BuiltinOperator>(model->operator_codes[opcodeIndex]->deprecated_builtin_code));
#else
    auto opcode = model->operator_codes[opcodeIndex]->builtin_code;
#endif
    return opcode;
}

std::vector<unsigned int> GetUIntBuffer(armnn::TensorInfo info,
                                        const TfLiteParserImpl::ModelPtr& model,
                                        size_t bufferIndex)
{
    TfLiteParserImpl::BufferRawPtr bufferPtr = TfLiteParserImpl::GetBuffer(model, bufferIndex);
    std::vector<unsigned int> buffer(info.GetNumElements());

    if (info.GetDataType() == DataType::Signed32)
    {
        ::memcpy(buffer.data(), bufferPtr->data.data(), bufferPtr->data.size());
    }
    else if (info.GetDataType() == DataType::Signed64)
    {
        std::vector<uint64_t> uint64Buffer(info.GetNumElements());
        ::memcpy(uint64Buffer.data(), bufferPtr->data.data(), bufferPtr->data.size());
        buffer.assign(std::begin(uint64Buffer), std::end(uint64Buffer));
    }
    else
    {
        CheckLocation location = CHECK_LOCATION();
        throw ParseException(
                fmt::format("Unsupported data type for uint buffer {}, only Signed 32 or Signed 64 are supported. {}",
                            GetDataTypeName(info.GetDataType()),
                            location.AsString()));
    }
    return buffer;
}

#define CHECK_BUFFER_SIZE(BUFFER_PTR, TENSOR_INFO, BUFFER_ID) \
    CheckBufferSize(BUFFER_PTR, TENSOR_INFO, BUFFER_ID, CHECK_LOCATION())

bool IsActivationSupported(tflite::ActivationFunctionType activationType)
{
    switch(activationType)
    {
        case tflite::ActivationFunctionType_NONE:
        case tflite::ActivationFunctionType_RELU:
        case tflite::ActivationFunctionType_RELU6:
        case tflite::ActivationFunctionType_TANH:
        {
            return true;
        }
        default:
        {
            return false;
        }
    }
}

#define CHECK_SUPPORTED_FUSED_ACTIVATION(OPTION, SUBGRAPH_INDEX, OPERATOR_INDEX) \
    do { \
        if (IsActivationSupported(OPTION->fused_activation_function) == false) \
        { \
            throw ParseException( \
                fmt::format("TfLite parser doesn't support fused activation: " \
                            "{}/{} in {} subgraph:{} operator:{} at {}", \
                            OPTION->fused_activation_function, \
                            tflite::EnumNameActivationFunctionType(\
                            OPTION->fused_activation_function), \
                            __func__, \
                            SUBGRAPH_INDEX, \
                            OPERATOR_INDEX, \
                            CHECK_LOCATION().FileLine())); \
        } \
    } while(false)


std::vector<unsigned int> AsUnsignedVector(const std::vector<int32_t>& in)
{
    std::vector<unsigned int> result;
    result.reserve(in.size());
    for (auto& i : in)
    {
        // If the location of the input data is -1 then the input should be ignored.
        if (i == -1)
        {
            continue;
        }
        result.push_back(CHECKED_NON_NEGATIVE(i));
    }
    return result;
}

bool IsOptionalOperandPresent(int input)
{
    return (input >= 0);
}

void CalcPadding(uint32_t inputSize,
                 uint32_t filterSize,
                 uint32_t stride,
                 uint32_t dilation,
                 uint32_t& paddingFront,
                 uint32_t& paddingBack,
                 tflite::Padding padding)
{
    paddingFront = 0;
    paddingBack = 0;
    if (padding == tflite::Padding_SAME)
    {
        uint32_t outputSize = (inputSize + stride - 1) / stride;
        uint32_t dilatedSize = filterSize + (dilation - 1) * (filterSize - 1);
        uint32_t temp = (outputSize - 1) * stride + dilatedSize;
        if (temp > inputSize)
        {
            paddingFront = (temp - inputSize) / 2;
            paddingBack = (temp - inputSize) - paddingFront;
        }
    }
}

// Function that calculates explicit padding when the output shape is known.
// At the moment the output is only given as an input parameter in Transpose Convolution,
// not in Convolution and Depthwise Convolution
void CalcPadding(uint32_t inputSize,
                 uint32_t filterSize,
                 uint32_t stride,
                 uint32_t dilation,
                 uint32_t& paddingFront,
                 uint32_t& paddingBack,
                 tflite::Padding padding,
                 uint32_t outputSize)
{
    IgnoreUnused(dilation);
    paddingFront = 0;
    paddingBack = 0;
    if (padding == tflite::Padding_SAME)
    {
        uint32_t totalPadding = (inputSize - 1) * stride + filterSize - outputSize;
        paddingFront = totalPadding / 2;
        paddingBack = totalPadding - paddingFront;
    }
}

armnn::TensorInfo ToTensorInfo(TfLiteParserImpl::TensorRawPtr tensorPtr,
                               const std::vector<unsigned int>& shape,
                               const bool outputTensor = false)
{
    armnn::DataType type;
    CHECK_TENSOR_PTR(tensorPtr);

    switch (tensorPtr->type)
    {
        case tflite::TensorType_UINT8:
            type = armnn::DataType::QAsymmU8;
            break;
        case tflite::TensorType_FLOAT32:
            type = armnn::DataType::Float32;
            break;
        case tflite::TensorType_FLOAT16:
            type = armnn::DataType::Float16;
            break;
        case tflite::TensorType_INT8:
            if (tensorPtr->quantization->zero_point.size() == 1)
            {
                // Per-tensor
                type = armnn::DataType::QAsymmS8;
            }
            else
            {
                // Per-channel
                type = armnn::DataType::QSymmS8;
            }
            break;
        case tflite::TensorType_INT16:
            type = armnn::DataType::QSymmS16;
            break;
        case tflite::TensorType_INT32:
            type = armnn::DataType::Signed32;
            break;
        case tflite::TensorType_INT64:
            type = armnn::DataType::Signed64;
            break;
        case tflite::TensorType_BOOL:
            type = armnn::DataType::Boolean;
            break;
        default:
        {
            CheckLocation location = CHECK_LOCATION();
            throw ParseException(
                fmt::format("Unsupported data type {} = {} for tensor: {}. {}",
                            tensorPtr->type,
                            tflite::EnumNameTensorType(tensorPtr->type),
                            tensorPtr->name,
                            location.AsString()));
        }
    }
    TensorShape tensorShape;

    std::vector<unsigned int> safeShape = shape;
    if (shape.size() == 0)
    {
        safeShape.push_back(1);
    }

    if (!outputTensor)
    {
        tensorShape = TensorShape(armnn::numeric_cast<unsigned int>(safeShape.size()), safeShape.data());
    }
    else
    {
        size_t shapeSignatureSize = tensorPtr->shape_signature.size();

        // If a shape signature exists we will use that to infer dynamic tensors
        if (shapeSignatureSize != 0)
        {
            // If the shape is incompatible with the shape signature override the shape
            if (shapeSignatureSize != shape.size())
            {
                safeShape = {};

                for (unsigned int i = 0; i < shapeSignatureSize; ++i)
                {
                    unsigned int dim = tensorPtr->shape_signature[i] > -1 ?
                                       static_cast<unsigned int>(tensorPtr->shape_signature[i]) : 0;
                    safeShape.push_back(dim);
                }
            }

            std::unique_ptr<bool[]> dimMask = std::make_unique<bool[]>(tensorPtr->shape_signature.size());
            bool batchOnly = true;
            for (unsigned int i = 0; i < tensorPtr->shape_signature.size(); ++i)
            {
                dimMask[i] = tensorPtr->shape_signature[i] != -1;

                if (i > 0 && !dimMask[i])
                {
                    batchOnly = false;
                }
            }
            if (batchOnly)
            {
                dimMask[0] = true;
            }
            tensorShape = TensorShape(static_cast<unsigned int>(safeShape.size()), safeShape.data(), dimMask.get());
        }
        // If there is no shape signature treat the tensor as dynamic if the shape has a size of zero
        else if (shape.size() == 0)
        {
            tensorShape = TensorShape(1, false);
        }
        else
        {
            tensorShape = TensorShape(armnn::numeric_cast<unsigned int>(shape.size()), shape.data());
        }
    }

    float quantizationScale = 1.0f;
    int32_t quantizationOffset = 0;

    if (tensorPtr->quantization.get())
    {
        if (tensorPtr->quantization->scale.size() <= 1)
        {
            CHECK_VALID_SIZE(tensorPtr->quantization->zero_point.size(), 0, 1);
            CHECK_VALID_SIZE(tensorPtr->quantization->zero_point.size(), 0, 1);

            if (tensorPtr->quantization->scale.size() == 1)
            {
                quantizationScale = tensorPtr->quantization->scale[0];
            }
            if (tensorPtr->quantization->zero_point.size() == 1)
            {
                // NOTE: we lose precision here when converting from 64 bit to 32
                //       but this is what we support at the moment in ArmNN
                quantizationOffset = armnn::numeric_cast<int32_t>(tensorPtr->quantization->zero_point[0]);
            }

            armnn::TensorInfo result(tensorShape,
                                     type,
                                     quantizationScale,
                                     quantizationOffset);
            return result;
        }
        else
        {
            std::vector<float> quantizationScales;
            std::vector<int32_t> quantizationOffsets;

            // Scale
            std::copy(tensorPtr->quantization->scale.begin(),
                      tensorPtr->quantization->scale.end(),
                      std::back_inserter(quantizationScales));

            // QSymmS8 Per-axis
            armnn::TensorInfo result(tensorShape,
                                     type,
                                     quantizationScales,
                                     armnn::numeric_cast<unsigned int>(tensorPtr->quantization->quantized_dimension));
            return result;
        }
    }
    else
    {
        armnn::TensorInfo result(tensorShape,
                                 type,
                                 quantizationScale,
                                 quantizationOffset);
        return result;
    }
}

armnn::TensorInfo ToTensorInfo(TfLiteParserImpl::TensorRawPtr tensorPtr,
                               const bool outputTensor = false)
{
    auto const& dimensions = AsUnsignedVector(tensorPtr->shape);
    return ToTensorInfo(tensorPtr, dimensions, outputTensor);
}

template<typename T>
std::pair<armnn::ConstTensor, std::unique_ptr<T[]>>
CreateConstTensorImpl(TfLiteParserImpl::BufferRawPtr bufferPtr,
                      TfLiteParserImpl::TensorRawPtr tensorPtr,
                      armnn::TensorInfo& tensorInfo,
                      armnn::Optional<armnn::PermutationVector&> permutationVector)
{
    IgnoreUnused(tensorPtr);
    ARMNN_ASSERT_MSG(tensorPtr != nullptr, "tensorPtr is null");
    ARMNN_ASSERT_MSG(bufferPtr != nullptr,
        fmt::format("Buffer for buffer:{} is null", tensorPtr->buffer).c_str());

    std::unique_ptr<T[]> data(new T[tensorInfo.GetNumElements()]);

    if (permutationVector.has_value() && permutationVector.value().GetSize() > 0)
    {
        tensorInfo = armnnUtils::Permuted(tensorInfo, permutationVector.value());
        armnnUtils::Permute(tensorInfo.GetShape(), permutationVector.value(),
                            reinterpret_cast<const T*>(bufferPtr->data.data()), data.get(), sizeof(T));
    }
    else
    {
        ::memcpy(data.get(), bufferPtr->data.data(), tensorInfo.GetNumBytes());
    }

    // Make sure isConstant flag is set.
    tensorInfo.SetConstant();

    return std::make_pair(ConstTensor(tensorInfo, data.get()), std::move(data));
}

armnn::LayerBindingId GenerateLayerBindingId(size_t subgraphIndex, size_t tensorIndex)
{
    // generate the binding id by shifting the tensor id by 8 bit
    // and add the subgraph id, which allows 256 subgraphs
    return static_cast<armnn::LayerBindingId>((tensorIndex<<8)+subgraphIndex);
}

bool CheckShape(const armnn::TensorShape& actual, const std::vector<int32_t>& expected)
{
    const unsigned int actualSize = actual.GetNumDimensions();
    if (actualSize != expected.size())
    {
        return false;
    }

    for (unsigned int i = 0u; i < actualSize; i++)
    {
        if (expected[i] < 0 ||
            actual[i] != static_cast<unsigned int>(expected[i]))
        {
            return false;
        }
    }

    return true;
}

bool CheckShape(const armnn::TensorShape& actual, const armnn::TensorShape& expected)
{
    std::vector<int32_t> expectedVec;
    for (uint32_t i = 0; i < expected.GetNumDimensions(); i++)
    {
        expectedVec.push_back(expected[i]);
    }
    return CheckShape(actual, expectedVec);
}

void CheckMatchingQuantization(const TensorInfo& first,
                               const TensorInfo& second,
                               const std::string& descName,
                               std::string const& firstName,
                               std::string const& secondName)
{
    if (!first.IsQuantized() ||
        !second.IsQuantized())
    {
        // Not a quantized type, ignore the validation
        return;
    }

    DataType firstDataType  = first.GetDataType();
    DataType secondDataType = second.GetDataType();

    if (firstDataType != secondDataType)
    {
        throw InvalidArgumentException(descName + ": " + firstName + " and " + secondName +
                                       " must be of the same quantized type, " +
                                       firstName + " is " + GetDataTypeName(firstDataType) + ", " +
                                       secondName + " is " + GetDataTypeName(secondDataType));
    }

    if (!first.IsTypeSpaceMatch(second))
    {
        throw InvalidArgumentException(descName + ": " + firstName + " and " + secondName +
                                       " must have the same quantization space, " +
                                       firstName + " has offset " + std::to_string(first.GetQuantizationOffset()) +
                                       " and scale " + std::to_string(first.GetQuantizationScale()) + ", " +
                                       secondName + " has offset " + std::to_string(second.GetQuantizationOffset()) +
                                       " and scale " + std::to_string(second.GetQuantizationScale()));
    }
}

bool IsDynamic(TfLiteParserImpl::TensorRawPtr tensorPtr)
{
    auto shape = tensorPtr->shape;

    if (shape.empty())
    {
        return true;
    }
    auto shapeSig = tensorPtr->shape_signature;

    if (shapeSig.empty())
    {
        return false;
    }

    for (unsigned int i = 0; i < shapeSig.size() ; ++i)
    {
        if (shapeSig[i] == -1)
        {
            return true;
        }
    }
    return false;
}

} // <anonymous>

TfLiteParserImpl::TfLiteParserImpl(const Optional<ITfLiteParser::TfLiteParserOptions>& options)
: m_Options(options)
, m_Network(nullptr, nullptr)
, m_ParserFunctions(tflite::BuiltinOperator_MAX+1, &TfLiteParserImpl::ParseUnsupportedOperator)
{
    // register supported operators
    m_ParserFunctions[tflite::BuiltinOperator_ABS]                     = &TfLiteParserImpl::ParseAbs;
    m_ParserFunctions[tflite::BuiltinOperator_ADD]                     = &TfLiteParserImpl::ParseAdd;
    m_ParserFunctions[tflite::BuiltinOperator_ARG_MIN]                 = &TfLiteParserImpl::ParseArgMin;
    m_ParserFunctions[tflite::BuiltinOperator_ARG_MAX]                 = &TfLiteParserImpl::ParseArgMax;
    m_ParserFunctions[tflite::BuiltinOperator_AVERAGE_POOL_2D]         = &TfLiteParserImpl::ParseAveragePool2D;
    m_ParserFunctions[tflite::BuiltinOperator_BATCH_TO_SPACE_ND]       = &TfLiteParserImpl::ParseBatchToSpaceND;
    m_ParserFunctions[tflite::BuiltinOperator_BATCH_MATMUL]            = &TfLiteParserImpl::ParseBatchMatMul;
    m_ParserFunctions[tflite::BuiltinOperator_CEIL]                    = &TfLiteParserImpl::ParseCeil;
    m_ParserFunctions[tflite::BuiltinOperator_CAST]                    = &TfLiteParserImpl::ParseCast;
    m_ParserFunctions[tflite::BuiltinOperator_CONCATENATION]           = &TfLiteParserImpl::ParseConcatenation;
    m_ParserFunctions[tflite::BuiltinOperator_CONV_2D]                 = &TfLiteParserImpl::ParseConv2D;
    // Conv3D support was added in TF 2.5, so for backwards compatibility a hash define is needed.
    #if defined(ARMNN_POST_TFLITE_2_4)
    m_ParserFunctions[tflite::BuiltinOperator_CONV_3D]                 = &TfLiteParserImpl::ParseConv3D;
    #endif
    m_ParserFunctions[tflite::BuiltinOperator_CUSTOM]                  = &TfLiteParserImpl::ParseCustomOperator;
    m_ParserFunctions[tflite::BuiltinOperator_DEPTH_TO_SPACE]          = &TfLiteParserImpl::ParseDepthToSpace;
    m_ParserFunctions[tflite::BuiltinOperator_DEPTHWISE_CONV_2D]       = &TfLiteParserImpl::ParseDepthwiseConv2D;
    m_ParserFunctions[tflite::BuiltinOperator_DEQUANTIZE]              = &TfLiteParserImpl::ParseDequantize;
    m_ParserFunctions[tflite::BuiltinOperator_DIV]                     = &TfLiteParserImpl::ParseDiv;
    m_ParserFunctions[tflite::BuiltinOperator_ELU]                     = &TfLiteParserImpl::ParseElu;
    m_ParserFunctions[tflite::BuiltinOperator_EQUAL]                   = &TfLiteParserImpl::ParseEqual;
    m_ParserFunctions[tflite::BuiltinOperator_EXP]                     = &TfLiteParserImpl::ParseExp;
    m_ParserFunctions[tflite::BuiltinOperator_EXPAND_DIMS]             = &TfLiteParserImpl::ParseExpandDims;
    m_ParserFunctions[tflite::BuiltinOperator_FLOOR_DIV]               = &TfLiteParserImpl::ParseFloorDiv;
    m_ParserFunctions[tflite::BuiltinOperator_FULLY_CONNECTED]         = &TfLiteParserImpl::ParseFullyConnected;
    m_ParserFunctions[tflite::BuiltinOperator_GATHER]                  = &TfLiteParserImpl::ParseGather;
    m_ParserFunctions[tflite::BuiltinOperator_GATHER_ND]               = &TfLiteParserImpl::ParseGatherNd;
    m_ParserFunctions[tflite::BuiltinOperator_GREATER]                 = &TfLiteParserImpl::ParseGreater;
    m_ParserFunctions[tflite::BuiltinOperator_GREATER_EQUAL]           = &TfLiteParserImpl::ParseGreaterOrEqual;
    m_ParserFunctions[tflite::BuiltinOperator_HARD_SWISH]              = &TfLiteParserImpl::ParseHardSwish;
    m_ParserFunctions[tflite::BuiltinOperator_LEAKY_RELU]              = &TfLiteParserImpl::ParseLeakyRelu;
    m_ParserFunctions[tflite::BuiltinOperator_LESS]                    = &TfLiteParserImpl::ParseLess;
    m_ParserFunctions[tflite::BuiltinOperator_LESS_EQUAL]              = &TfLiteParserImpl::ParseLessOrEqual;
    m_ParserFunctions[tflite::BuiltinOperator_LOCAL_RESPONSE_NORMALIZATION]
            = &TfLiteParserImpl::ParseLocalResponseNormalization;
    m_ParserFunctions[tflite::BuiltinOperator_LOG]                     = &TfLiteParserImpl::ParseLog;
    m_ParserFunctions[tflite::BuiltinOperator_LOGICAL_NOT]             = &TfLiteParserImpl::ParseLogicalNot;
    m_ParserFunctions[tflite::BuiltinOperator_LOGISTIC]                = &TfLiteParserImpl::ParseLogistic;
    m_ParserFunctions[tflite::BuiltinOperator_LOG_SOFTMAX]             = &TfLiteParserImpl::ParseLogSoftmax;
    m_ParserFunctions[tflite::BuiltinOperator_L2_NORMALIZATION]        = &TfLiteParserImpl::ParseL2Normalization;
    m_ParserFunctions[tflite::BuiltinOperator_MAX_POOL_2D]             = &TfLiteParserImpl::ParseMaxPool2D;
    m_ParserFunctions[tflite::BuiltinOperator_MAXIMUM]                 = &TfLiteParserImpl::ParseMaximum;
    m_ParserFunctions[tflite::BuiltinOperator_MEAN]                    = &TfLiteParserImpl::ParseMean;
    m_ParserFunctions[tflite::BuiltinOperator_MINIMUM]                 = &TfLiteParserImpl::ParseMinimum;
    m_ParserFunctions[tflite::BuiltinOperator_MIRROR_PAD]              = &TfLiteParserImpl::ParseMirrorPad;
    m_ParserFunctions[tflite::BuiltinOperator_MUL]                     = &TfLiteParserImpl::ParseMul;
    m_ParserFunctions[tflite::BuiltinOperator_NEG]                     = &TfLiteParserImpl::ParseNeg;
    m_ParserFunctions[tflite::BuiltinOperator_NOT_EQUAL]               = &TfLiteParserImpl::ParseNotEqual;
    m_ParserFunctions[tflite::BuiltinOperator_PACK]                    = &TfLiteParserImpl::ParsePack;
    m_ParserFunctions[tflite::BuiltinOperator_PAD]                     = &TfLiteParserImpl::ParsePad;
    m_ParserFunctions[tflite::BuiltinOperator_PADV2]                   = &TfLiteParserImpl::ParsePad;
    m_ParserFunctions[tflite::BuiltinOperator_PRELU]                   = &TfLiteParserImpl::ParsePrelu;
    m_ParserFunctions[tflite::BuiltinOperator_QUANTIZE]                = &TfLiteParserImpl::ParseQuantize;
    m_ParserFunctions[tflite::BuiltinOperator_RELU]                    = &TfLiteParserImpl::ParseRelu;
    m_ParserFunctions[tflite::BuiltinOperator_RELU6]                   = &TfLiteParserImpl::ParseRelu6;
    m_ParserFunctions[tflite::BuiltinOperator_REDUCE_MAX]              = &TfLiteParserImpl::ParseReduceMax;
    m_ParserFunctions[tflite::BuiltinOperator_REDUCE_MIN]              = &TfLiteParserImpl::ParseReduceMin;
    m_ParserFunctions[tflite::BuiltinOperator_REDUCE_PROD]             = &TfLiteParserImpl::ParseReduceProd;
    m_ParserFunctions[tflite::BuiltinOperator_RESHAPE]                 = &TfLiteParserImpl::ParseReshape;
    m_ParserFunctions[tflite::BuiltinOperator_RESIZE_BILINEAR]         = &TfLiteParserImpl::ParseResizeBilinear;
    m_ParserFunctions[tflite::BuiltinOperator_RESIZE_NEAREST_NEIGHBOR] = &TfLiteParserImpl::ParseResizeNearestNeighbor;
    m_ParserFunctions[tflite::BuiltinOperator_RSQRT]                   = &TfLiteParserImpl::ParseRsqrt;
    m_ParserFunctions[tflite::BuiltinOperator_SQRT]                    = &TfLiteParserImpl::ParseSqrt;
    m_ParserFunctions[tflite::BuiltinOperator_SHAPE]                   = &TfLiteParserImpl::ParseShape;
    m_ParserFunctions[tflite::BuiltinOperator_SIN]                     = &TfLiteParserImpl::ParseSin;
    m_ParserFunctions[tflite::BuiltinOperator_SLICE]                   = &TfLiteParserImpl::ParseSlice;
    m_ParserFunctions[tflite::BuiltinOperator_SOFTMAX]                 = &TfLiteParserImpl::ParseSoftmax;
    m_ParserFunctions[tflite::BuiltinOperator_SPACE_TO_BATCH_ND]       = &TfLiteParserImpl::ParseSpaceToBatchND;
    m_ParserFunctions[tflite::BuiltinOperator_SPACE_TO_DEPTH]          = &TfLiteParserImpl::ParseSpaceToDepth;
    m_ParserFunctions[tflite::BuiltinOperator_SPLIT]                   = &TfLiteParserImpl::ParseSplit;
    m_ParserFunctions[tflite::BuiltinOperator_SPLIT_V]                 = &TfLiteParserImpl::ParseSplitV;
    m_ParserFunctions[tflite::BuiltinOperator_SQUEEZE]                 = &TfLiteParserImpl::ParseSqueeze;
    m_ParserFunctions[tflite::BuiltinOperator_STRIDED_SLICE]           = &TfLiteParserImpl::ParseStridedSlice;
    m_ParserFunctions[tflite::BuiltinOperator_SUB]                     = &TfLiteParserImpl::ParseSub;
    m_ParserFunctions[tflite::BuiltinOperator_SUM]                     = &TfLiteParserImpl::ParseSum;
    m_ParserFunctions[tflite::BuiltinOperator_TANH]                    = &TfLiteParserImpl::ParseTanH;
    m_ParserFunctions[tflite::BuiltinOperator_TRANSPOSE]               = &TfLiteParserImpl::ParseTranspose;
    m_ParserFunctions[tflite::BuiltinOperator_TRANSPOSE_CONV]          = &TfLiteParserImpl::ParseTransposeConv;
    m_ParserFunctions[tflite::BuiltinOperator_UNIDIRECTIONAL_SEQUENCE_LSTM]
            = &TfLiteParserImpl::ParseUnidirectionalSequenceLSTM;
    m_ParserFunctions[tflite::BuiltinOperator_UNPACK]                  = &TfLiteParserImpl::ParseUnpack;

    // register supported custom operators
    m_CustomParserFunctions["TFLite_Detection_PostProcess"]      = &TfLiteParserImpl::ParseDetectionPostProcess;
}

armnn::TensorInfo TfLiteParserImpl::InputTensorInfo(size_t subgraphIndex,
                                    size_t operatorIndex,
                                    int input)
{
    const auto& subgraphPtr = m_Model->subgraphs[subgraphIndex];
    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];

    uint32_t inputId = CHECKED_NON_NEGATIVE(operatorPtr->inputs[input]);
    auto search = armnnTfLiteParser::TfLiteParserImpl::m_TensorInfos.find(inputId);

    if (search != m_TensorInfos.end())
    {
        return m_TensorInfos[inputId];
    }
    else
    {
        auto tensorInfo = ::armnnTfLiteParser::ToTensorInfo(subgraphPtr->tensors[inputId].get());
        m_TensorInfos.insert({ inputId, tensorInfo });
        return tensorInfo;
    }
}

armnn::TensorInfo TfLiteParserImpl::OutputTensorInfoFromInputs(size_t subgraphIndex,
                                                               size_t operatorIndex,
                                                               armnn::IConnectableLayer* layer,
                                                               int output,
                                                               std::vector<int> inputs)
{
    const auto& subgraphPtr = m_Model->subgraphs[subgraphIndex];
    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];

    uint32_t outputId = CHECKED_NON_NEGATIVE(operatorPtr->outputs[output]);

    auto outputSearch = armnnTfLiteParser::TfLiteParserImpl::m_TensorInfos.find(outputId);

    if (outputSearch != m_TensorInfos.end())
    {
        return m_TensorInfos[outputId];
    }

    const auto& outputTensorPtr = subgraphPtr->tensors[outputId].get();
    TensorInfo tensor = ::armnnTfLiteParser::ToTensorInfo(outputTensorPtr, true);

    if (IsDynamic(outputTensorPtr))
    {
        if (inputs.empty())
        {
            for (unsigned int i = 0; i < layer->GetNumInputSlots(); ++i)
            {
                inputs.emplace_back(i);
            }
        }
        auto inputTensorIds = GetInputTensorIds(m_Model, subgraphIndex, operatorIndex);
        std::vector<armnn::TensorShape> inputShapes;

        for (unsigned int i = 0; i < inputs.size(); ++i)
        {
            uint32_t inputId = CHECKED_NON_NEGATIVE(operatorPtr->inputs[inputs[i]]);
            auto search = armnnTfLiteParser::TfLiteParserImpl::m_TensorInfos.find(inputId);

            if (search != m_TensorInfos.end())
            {
                auto &inputTensorInfo = m_TensorInfos[inputId];
                inputShapes.push_back(inputTensorInfo.GetShape());
            }
            else
            {
                m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
                auto inputTensorInfo = ::armnnTfLiteParser::ToTensorInfo(subgraphPtr->tensors[inputId].get());
                m_TensorInfos.insert({ inputId, inputTensorInfo});
                inputShapes.push_back(inputTensorInfo.GetShape());
            }
        }
        const auto outputShape = layer->InferOutputShapes(inputShapes)[output];
        tensor.SetShape(outputShape);
    }
    m_TensorInfos.insert({ outputId, tensor});
    return tensor;
}

armnn::TensorInfo TfLiteParserImpl::OutputTensorInfoFromShapes(size_t subgraphIndex,
                                                               size_t operatorIndex,
                                                               armnn::IConnectableLayer* layer,
                                                               int output,
                                                               std::vector<armnn::TensorShape> inputShapes)
{
    const auto& subgraphPtr = m_Model->subgraphs[subgraphIndex];
    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];

    uint32_t outputId = CHECKED_NON_NEGATIVE(operatorPtr->outputs[output]);
    const auto& outputTensorPtr = subgraphPtr->tensors[outputId].get();
    TensorInfo tensor = ::armnnTfLiteParser::ToTensorInfo(outputTensorPtr, true);

    if (IsDynamic(outputTensorPtr))
    {
        const auto outputShape = layer->InferOutputShapes(inputShapes)[output];
        tensor.SetShape(outputShape);
    }
    m_TensorInfos.insert({ outputId, tensor});
    return tensor;
}

void TfLiteParserImpl::ResetParser()
{
    m_Network = armnn::INetworkPtr(nullptr, nullptr);
    m_Model = nullptr;
    m_SubgraphConnections.clear();
    m_OverriddenOutputShapes.clear();
    m_ConstantsToDequantize.clear();
    m_ConstantsToBeCreated.clear();
    m_TensorInfos.clear();
}

INetworkPtr TfLiteParserImpl::CreateNetworkFromBinaryFile(const char* graphFile)
{
    ResetParser();
    m_Model = LoadModelFromFile(graphFile);
    return CreateNetworkFromModel();
}

INetworkPtr TfLiteParserImpl::CreateNetworkFromBinary(const std::vector<uint8_t>& binaryContent)
{
    ResetParser();
    m_Model = LoadModelFromBinary(binaryContent.data(), binaryContent.size());
    return CreateNetworkFromModel();
}


armnn::INetworkPtr TfLiteParserImpl::LoadModel(std::unique_ptr<tflite::ModelT> model)
{
    ResetParser();
    m_Model = std::move(model);

    return CreateNetworkFromModel();
}

INetworkPtr TfLiteParserImpl::CreateNetworkFromModel()
{

    using NetworkOptions = std::vector<BackendOptions>;
    NetworkOptions networkOptions = {};
    if (m_Options)
    {
        if (m_Options.value().m_InferAndValidate)
        {
            BackendOptions shapeInferenceMethodOption("ShapeInferenceMethod",
                                                      {
                                                          { "InferAndValidate", true }
                                                      });

            networkOptions.push_back(shapeInferenceMethodOption);
        }
        if (m_Options.value().m_AllowExpandedDims)
        {
            BackendOptions shapeInferenceMethodOption("AllowExpandedDims",
                                                      {
                                                          { "AllowExpandedDims", true }
                                                      });

            networkOptions.push_back(shapeInferenceMethodOption);
        }
    }
    m_Network = INetwork::Create(networkOptions);
    ARMNN_ASSERT(m_Model.get() != nullptr);

    if (m_Model->subgraphs.size() != 1)
    {
        throw ParseException(
                fmt::format("Current TfLite parser only supports 1 subgraph. Current one has: {} {}",
                            m_Model->subgraphs.size(),
                            CHECK_LOCATION().AsString()));
    }

    size_t subgraphIndex = 0;
    size_t operatorIndex = 0;
    try
    {
        for (SubgraphPtr const& subgraph : m_Model->subgraphs)
        {
            SetupInputLayerTensorInfos(subgraphIndex);
            SetupConstantLayerTensorInfos(subgraphIndex);

            m_SubgraphConnections.emplace_back(subgraph->tensors.size());
            for (OperatorPtr const& op : subgraph->operators)
            {
                auto const& opCodePtr = m_Model->operator_codes[op->opcode_index];

// work around the introduction of the deprecated_builtin_code introduced in 2.4 in a backwards compatible manner
#if defined(ARMNN_POST_TFLITE_2_3)
                auto builtinCode = std::max(opCodePtr->builtin_code,
                        static_cast<tflite::BuiltinOperator>(opCodePtr->deprecated_builtin_code));
#else
                auto builtinCode = opCodePtr->builtin_code;
#endif

                if (builtinCode > tflite::BuiltinOperator_MAX)
                {
                    throw ParseException(fmt::format("Operator code {} is out of range 0-{}. "
                                                     "subgraph:{} operator idx:{}. {}",
                                                     builtinCode, tflite::BuiltinOperator_MAX, subgraphIndex,
                                                     operatorIndex, CHECK_LOCATION().AsString()));
                }

                // lookup and call the parser function
                auto& parserFunction = m_ParserFunctions[builtinCode];
                (this->*parserFunction)(subgraphIndex, operatorIndex);
                ++operatorIndex;
            }

            SetupInputLayers(subgraphIndex);
            SetupOutputLayers(subgraphIndex);
            SetupConstantLayers(subgraphIndex);

            ++subgraphIndex;
            operatorIndex = 0;
        }
    }
    catch (const ParseException& e)
    {
        std::stringstream errorString;
        errorString << "Failed to parse operator #" << operatorIndex << " within subgraph #"
                    << subgraphIndex << " error: " << e.what();
        ARMNN_LOG(error) << errorString.str();
        std::stringstream errors;
        errors << errorString.str() << "\n";
        throw ParseException(errors.str());
    }

    // establish the connections from the layer outputs to the inputs of the subsequent layers
    for (subgraphIndex = 0; subgraphIndex < m_SubgraphConnections.size(); ++subgraphIndex)
    {
        for (size_t tensorIndex = 0; tensorIndex < m_SubgraphConnections[subgraphIndex].size(); ++tensorIndex)
        {
            if (m_SubgraphConnections[subgraphIndex][tensorIndex].outputSlot != nullptr)
            {
                for (size_t inputSlotIdx = 0;
                    inputSlotIdx < m_SubgraphConnections[subgraphIndex][tensorIndex].inputSlots.size();
                    ++inputSlotIdx)
                {
                    m_SubgraphConnections[subgraphIndex][tensorIndex].outputSlot->Connect(
                        *(m_SubgraphConnections[subgraphIndex][tensorIndex].inputSlots[inputSlotIdx]));
                }
            }
        }
    }
    return std::move(m_Network);
}

bool TfLiteParserImpl::ShouldConstantTensorBeConverted(TfLiteParserImpl::TensorRawPtr tensorPtr,
                                                       armnn::DataType inputDataType,
                                                       armnn::DataType tensorDataType)
{
    return (TfLiteParserImpl::IsConstTensor(tensorPtr) && inputDataType == DataType::Float32 &&
            (tensorDataType == DataType::QAsymmU8 ||
             tensorDataType == DataType::QAsymmS8 ||
             tensorDataType == DataType::QSymmS8 ||
             tensorDataType == DataType::Signed32 ||
             tensorDataType == DataType::Signed64));
}

void TfLiteParserImpl::RegisterProducerOfTensor(size_t subgraphIndex,
                                                size_t tensorIndex,
                                                armnn::IOutputSlot* slot)
{
    CHECK_TENSOR(m_Model, subgraphIndex, tensorIndex);
    ARMNN_ASSERT(m_SubgraphConnections.size() > subgraphIndex);
    ARMNN_ASSERT(m_SubgraphConnections[subgraphIndex].size() > tensorIndex);

    TensorSlots & tensorSlots = m_SubgraphConnections[subgraphIndex][tensorIndex];

    if (slot->GetOwningIConnectableLayer().GetType() != LayerType::Constant)
    {

        // assuming there is only one producer for that tensor
        if (tensorSlots.outputSlot != nullptr)
        {
            throw ParseException(fmt::format("Another layer has already registered itself as the producer of "
                                             "subgraph:{} tensor:{} {}",
                                             subgraphIndex,
                                             tensorIndex,
                                             CHECK_LOCATION().AsString()));
        }
    }
    tensorSlots.outputSlot = slot;
}

void TfLiteParserImpl::RegisterConsumerOfTensor(size_t subgraphIndex,
                                                size_t tensorIndex,
                                                armnn::IInputSlot* slot)
{
    CHECK_TENSOR(m_Model, subgraphIndex, tensorIndex);
    ARMNN_ASSERT(m_SubgraphConnections.size() > subgraphIndex);
    ARMNN_ASSERT(m_SubgraphConnections[subgraphIndex].size() > tensorIndex);

    TensorSlots& tensorSlots = m_SubgraphConnections[subgraphIndex][tensorIndex];
    tensorSlots.inputSlots.push_back(slot);
}

void TfLiteParserImpl::ParseCustomOperator(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    // NOTE: By default we presume the custom operator is not supported
    auto customParserFunction = &TfLiteParserImpl::ParseUnsupportedOperator;

    // Identify custom code defined for custom operator
    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto& customCode  = m_Model->operator_codes[operatorPtr->opcode_index]->custom_code;

    // Find parser function that corresponds to custom code (if any)
    auto iterator = m_CustomParserFunctions.find(customCode);
    if (iterator != m_CustomParserFunctions.end())
    {
        customParserFunction = iterator->second;
    }

    // Run parser function
    (this->*customParserFunction)(subgraphIndex, operatorIndex);
}

void TfLiteParserImpl::ParseUnsupportedOperator(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    const auto & operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];

    auto opcodeIndex = operatorPtr->opcode_index;

// work around the introduction of the deprecated_builtin_code introduced in 2.4 in a backwards compatible manner
#if defined(ARMNN_POST_TFLITE_2_3)
    auto opcode      = std::max(m_Model->operator_codes[opcodeIndex]->builtin_code,
            static_cast<tflite::BuiltinOperator>(m_Model->operator_codes[opcodeIndex]->deprecated_builtin_code));
#else
    auto opcode      = m_Model->operator_codes[opcodeIndex]->builtin_code;
#endif

    if (!m_Options || !m_Options.value().m_StandInLayerForUnsupported)
    {
        // Do not add StandInLayer, throw ParseException instead
        throw ParseException(
            fmt::format("Operator not supported. "
                        "subgraph:{} operator:{} "
                        "opcode_index:{} opcode:{} / {} {}",
                        subgraphIndex,
                        operatorIndex,
                        opcodeIndex,
                        opcode,
                        tflite::EnumNameBuiltinOperator(opcode),
                        CHECK_LOCATION().AsString()));
    }

    auto inputs  = GetInputs(m_Model, subgraphIndex, operatorIndex);
    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);

    const unsigned int numInputs  = armnn::numeric_cast<unsigned int>(inputs.size());
    const unsigned int numOutputs = armnn::numeric_cast<unsigned int>(outputs.size());

    StandInDescriptor descriptor(numInputs, numOutputs);
    auto layerName = fmt::format("StandIn:{}:{}:{}", subgraphIndex, operatorIndex, opcode);

    // Add a non-executable StandInLayer as a placeholder for any unsupported operator
    IConnectableLayer* layer = m_Network->AddStandInLayer(descriptor, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    for (unsigned int i = 0u; i < numOutputs; ++i)
    {
        layer->GetOutputSlot(i).SetTensorInfo(ToTensorInfo(outputs[0], true));
    }

    auto inputTensorIds  = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    auto outputTensorIds = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));

    RegisterInputSlots(subgraphIndex, operatorIndex, layer, inputTensorIds);
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, outputTensorIds);
}

void TfLiteParserImpl::ParseCast(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 1);
    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    auto layerName = fmt::format("Cast:{}:{}", subgraphIndex, operatorIndex);

    IConnectableLayer* layer = m_Network->AddCastLayer(layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, outputTensorIndexes);
}

void TfLiteParserImpl::ParseConv2D(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsConv2DOptions();

    CHECK_SUPPORTED_FUSED_ACTIVATION(options, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    Convolution2dDescriptor desc;
    inputs.size() == 3 ?
        desc.m_BiasEnabled = true : desc.m_BiasEnabled = false;
    desc.m_StrideX = CHECKED_NON_NEGATIVE(options->stride_w);
    desc.m_StrideY = CHECKED_NON_NEGATIVE(options->stride_h);
    desc.m_DataLayout = armnn::DataLayout::NHWC;
    desc.m_DilationX = CHECKED_NON_NEGATIVE(options->dilation_w_factor);
    desc.m_DilationY = CHECKED_NON_NEGATIVE(options->dilation_h_factor);

    armnn::TensorInfo inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    armnn::TensorInfo filterTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);

    // assuming input is NHWC
    unsigned int inputHeight = inputTensorInfo.GetShape()[1];
    unsigned int inputWidth = inputTensorInfo.GetShape()[2];

    // assuming the filter is OHWI : Output, H, W, Input
    // which is essentially the same as NHWC
    unsigned int filterHeight = filterTensorInfo.GetShape()[1];
    unsigned int filterWidth = filterTensorInfo.GetShape()[2];

    CalcPadding(inputHeight, filterHeight, desc.m_StrideY,
                desc.m_DilationY, desc.m_PadTop, desc.m_PadBottom, options->padding);
    CalcPadding(inputWidth, filterWidth, desc.m_StrideX,
                desc.m_DilationX, desc.m_PadLeft, desc.m_PadRight, options->padding);

    // Add the first input and weights tensor to the registration list.
    // The constant weights will be added by SetupConstantLayers.
    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    std::vector<unsigned int> tensorIndexesToRegister = { inputTensorIndexes[0], inputTensorIndexes[1] };

    auto layerName = fmt::format("Conv2D:{}:{}", subgraphIndex, operatorIndex);
    armnn::IConnectableLayer* layer = m_Network->AddConvolution2dLayer(desc, layerName.c_str());

    if (ShouldConstantTensorBeConverted(inputs[1], inputTensorInfo.GetDataType(), filterTensorInfo.GetDataType()))
    {
        m_ConstantsToDequantize.emplace_back(inputs[1]->buffer);
    }

    if (desc.m_BiasEnabled)
    {
        armnn::TensorInfo biasTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 2);

        // Add the biases input to the registration list, a constant layer will be added by SetupConstantLayers.
        tensorIndexesToRegister.emplace_back(inputTensorIndexes[2]);

        if (ShouldConstantTensorBeConverted(inputs[2], inputTensorInfo.GetDataType(), biasTensorInfo.GetDataType()))
        {
            m_ConstantsToDequantize.emplace_back(inputs[2]->buffer);
        }
    }

    ARMNN_ASSERT(layer != nullptr);

    armnn::TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0, 1});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    // register the input connection slots for the layer, connections are made after all layers have been created
    // only the tensors for the inputs are relevant, exclude the const tensors
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, tensorIndexesToRegister);

    layer = AddFusedActivationLayer(layer, 0, options->fused_activation_function);
    // register the output connection slots for the layer, connections are made after all layers have been created
    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, { outputTensorIndexes[0] });
}

// Conv3D support was added in TF 2.5, so for backwards compatibility a hash define is needed.
#if defined(ARMNN_POST_TFLITE_2_4)
void TfLiteParserImpl::ParseConv3D(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsConv3DOptions();

    CHECK_SUPPORTED_FUSED_ACTIVATION(options, subgraphIndex, operatorIndex);

    Convolution3dDescriptor desc;
    desc.m_BiasEnabled = false;
    desc.m_DataLayout = armnn::DataLayout::NDHWC;
    desc.m_StrideX = CHECKED_NON_NEGATIVE(options->stride_w);
    desc.m_StrideY = CHECKED_NON_NEGATIVE(options->stride_h);
    desc.m_StrideZ = CHECKED_NON_NEGATIVE(options->stride_d);
    desc.m_DilationX = CHECKED_NON_NEGATIVE(options->dilation_w_factor);
    desc.m_DilationY = CHECKED_NON_NEGATIVE(options->dilation_h_factor);
    desc.m_DilationZ = CHECKED_NON_NEGATIVE(options->dilation_d_factor);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 2, 3);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    armnn::TensorInfo inputTensorInfo  = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    armnn::TensorInfo filterTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);

    // Assuming input is NDHWC
    unsigned int inputDepth  = inputTensorInfo.GetShape()[1];
    unsigned int inputHeight = inputTensorInfo.GetShape()[2];
    unsigned int inputWidth  = inputTensorInfo.GetShape()[3];

    // Assuming the filter is DHWIO : Depth, Height, Width, OutputChannels, InputChannels
    unsigned int filterDepth  = filterTensorInfo.GetShape()[0];
    unsigned int filterHeight = filterTensorInfo.GetShape()[1];
    unsigned int filterWidth  = filterTensorInfo.GetShape()[2];

    CalcPadding(inputDepth, filterDepth, desc.m_StrideZ,
                desc.m_DilationZ, desc.m_PadFront, desc.m_PadBack, options->padding);
    CalcPadding(inputHeight, filterHeight, desc.m_StrideY,
                desc.m_DilationY, desc.m_PadTop, desc.m_PadBottom, options->padding);
    CalcPadding(inputWidth, filterWidth, desc.m_StrideX,
                desc.m_DilationX, desc.m_PadLeft, desc.m_PadRight, options->padding);

    auto filterTensorAndData = CreateConstTensorNonPermuted(inputs[1], filterTensorInfo, inputTensorInfo.GetDataType());

    auto layerName = fmt::format("Conv3D:{}:{}", subgraphIndex, operatorIndex);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    // Add the first input and weights tensor to the registration list.
    // The constant weights will be added by SetupConstantLayers.
    std::vector<unsigned int> tensorIndexesToRegister = {inputTensorIndexes[0], inputTensorIndexes[1]};

    if (inputs.size() == 3)
    {
        desc.m_BiasEnabled = true;

        // Add the biases input to the registration list, a constant layer will be added by SetupConstantLayers.
        tensorIndexesToRegister.emplace_back(inputTensorIndexes[2]);
    }

    armnn::IConnectableLayer* layer = m_Network->AddConvolution3dLayer(desc, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    armnn::TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0, 1});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    // Register the input connection slots for the layer, connections are made after all layers have been created
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, tensorIndexesToRegister);

    layer = AddFusedActivationLayer(layer, 0, options->fused_activation_function);
    // Register the output connection slots for the layer, connections are made after all layers have been created
    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}
#endif

void TfLiteParserImpl::ParseDepthwiseConv2D(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsDepthwiseConv2DOptions();

    CHECK_SUPPORTED_FUSED_ACTIVATION(options, subgraphIndex, operatorIndex);

    DepthwiseConvolution2dDescriptor desc;
    desc.m_StrideX = CHECKED_NON_NEGATIVE(options->stride_w);
    desc.m_StrideY = CHECKED_NON_NEGATIVE(options->stride_h);
    desc.m_DataLayout = armnn::DataLayout::NHWC;
    CHECKED_NON_NEGATIVE(options->depth_multiplier);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 2, 3);
    if (inputs.size() == 3)
    {
        desc.m_BiasEnabled = true;
    }

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);
    desc.m_DilationX = CHECKED_NON_NEGATIVE(options->dilation_w_factor);
    desc.m_DilationY = CHECKED_NON_NEGATIVE(options->dilation_h_factor);

    armnn::TensorInfo inputTensorInfo  = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    armnn::TensorInfo filterTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);

    // Assuming input is NHWC
    unsigned int inputHeight = inputTensorInfo.GetShape()[1];
    unsigned int inputWidth  = inputTensorInfo.GetShape()[2];

    // TensorflowLite weights come in the format [1, H, W, I * M]
    unsigned int filterHeight = filterTensorInfo.GetShape()[1];
    unsigned int filterWidth  = filterTensorInfo.GetShape()[2];

    CalcPadding(inputHeight, filterHeight, desc.m_StrideY,
                desc.m_DilationY, desc.m_PadTop, desc.m_PadBottom, options->padding);
    CalcPadding(inputWidth, filterWidth, desc.m_StrideX,
                desc.m_DilationX, desc.m_PadLeft, desc.m_PadRight, options->padding);

    // ArmNN uses the same filter tensor layout at TfLite [1, H, W, O] no need for any permutation
    auto layerName = fmt::format("DepthwiseConv2D:{}:{}", subgraphIndex, operatorIndex);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    // Add the first input and weights tensor to the registration list.
    // The constant weights will be added by SetupConstantLayers.
    std::vector<unsigned int> tensorIndexesToRegister = {inputTensorIndexes[0], inputTensorIndexes[1]};

    armnn::IConnectableLayer* layer = m_Network->AddDepthwiseConvolution2dLayer(desc, layerName.c_str());

    if (desc.m_BiasEnabled)
    {
        desc.m_BiasEnabled = true;
        TensorInfo biasTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 2);

        // Add the biases input to the registration list, a constant layer will be added by SetupConstantLayers.
        tensorIndexesToRegister.emplace_back(inputTensorIndexes[2]);
    }
    ARMNN_ASSERT(layer != nullptr);

    armnn::TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0, 1});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    // register the input connection slots for the layer, connections are made after all layers have been created
    // only the tensors for the inputs are relevant, exclude the const tensors
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, tensorIndexesToRegister);

    layer = AddFusedActivationLayer(layer, 0, options->fused_activation_function);
    // register the output connection slots for the layer, connections are made after all layers have been created
    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseDequantize(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 1);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    auto layerName = fmt::format("Dequantize:{}:{}", subgraphIndex, operatorIndex);

    IConnectableLayer* layer = m_Network->AddDequantizeLayer(layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, outputTensorIndexes);
}

void TfLiteParserImpl::ParseExpandDims(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 2);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    auto layerName = fmt::format("ExpandDims:{}:{}", subgraphIndex, operatorIndex);

    armnn::TensorInfo inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);

    CheckMatchingQuantization(inputTensorInfo, outputTensorInfo, layerName, "Input 0", "Output 0");

    ReshapeDescriptor reshapeDesc;

    if (outputTensorInfo.GetShape().AreAllDimensionsSpecified())
    {
        reshapeDesc.m_TargetShape = outputTensorInfo.GetShape();
    }
    else
    {
        int32_t axis = inputs[1]->shape[0];

        int32_t inputDimSize = static_cast<int32_t>(inputTensorInfo.GetShape().GetNumDimensions());

        if (axis > inputDimSize || axis < 0 - (inputDimSize + 1))
        {
            throw ParseException("axis must be in range [0 - (inputDimSize + 1), inputDimSize] inclusive");
        }

        if(axis < 0)
        {
            axis = inputDimSize + axis + 1;
        }

        std::vector<unsigned int> shape(static_cast<unsigned int>(inputDimSize) + 1);
        unsigned int inputShapeIndex = 0;
        for (unsigned int i = 0; i < static_cast<unsigned int>(inputDimSize + 1); ++i)
        {
            if (i == static_cast<unsigned int>(axis))
            {
                shape[i] = 1;
            }
            else
            {
                shape[i] = inputTensorInfo.GetShape()[inputShapeIndex];
                ++inputShapeIndex;
            }
        }

        reshapeDesc.m_TargetShape = TensorShape(static_cast<unsigned int>(inputDimSize + 1), shape.data());
    }

    IConnectableLayer* layer = m_Network->AddReshapeLayer(reshapeDesc, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    reshapeDesc.m_TargetShape = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0}).GetShape();
    outputTensorInfo.SetShape(reshapeDesc.m_TargetShape);

    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseTranspose(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 1, 2);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    auto layerName = fmt::format("Transpose:{}:{}", subgraphIndex, operatorIndex);
    TransposeDescriptor desc;

    if (inputs.size() == 2)
    {
        armnn::TensorInfo permuteTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);
        BufferRawPtr permuteBufferPtr = GetBuffer(m_Model, inputs[1]->buffer);
        auto numPermVecElements = permuteTensorInfo.GetNumElements();
        std::vector<unsigned int> permuteShape(numPermVecElements);
        ::memcpy(permuteShape.data(), permuteBufferPtr->data.data(), permuteTensorInfo.GetNumBytes());
        PermutationVector permutationVector(permuteShape.data(), permuteTensorInfo.GetNumElements());

        desc = TransposeDescriptor(permutationVector);
    }
    TensorInfo inputTensorInfo  = InputTensorInfo(subgraphIndex, operatorIndex, 0);

    IConnectableLayer* layer = m_Network->AddTransposeLayer(desc, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    CheckMatchingQuantization(inputTensorInfo, outputTensorInfo, layerName, "Input 0", "Output 0");
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseTransposeConv(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsTransposeConvOptions();

    TransposeConvolution2dDescriptor desc;
    desc.m_BiasEnabled = false;
    desc.m_StrideX = CHECKED_NON_NEGATIVE(options->stride_w);
    desc.m_StrideY = CHECKED_NON_NEGATIVE(options->stride_h);
    desc.m_DataLayout = armnn::DataLayout::NHWC;

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    if (inputs.size() == 4)
    {
        desc.m_BiasEnabled = true;
    }
    else
    {
        CHECK_VALID_SIZE(inputs.size(), 3);
    }

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);


    armnn::TensorInfo inputTensorInfo  = InputTensorInfo(subgraphIndex, operatorIndex, 2);
    armnn::TensorInfo filterTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);

    // TfLite uses NHWC tensors
    const unsigned int inputHeight = inputTensorInfo.GetShape()[1];
    const unsigned int inputWidth  = inputTensorInfo.GetShape()[2];

    const unsigned int filterHeight = filterTensorInfo.GetShape()[1];
    const unsigned int filterWidth  = filterTensorInfo.GetShape()[2];

    // This block determines the output shape of the transpose convolution. If the output shape tensor ptr is not null
    // And the tensor is a constant, we can access the data at load time and set the output shape of the
    // layer. If this is not constant, We do not have access to the shape data, so we have to use
    // infer output shape and skip this code block.
    if (inputs[0] && IsConstTensor(inputs[0]))
    {
        armnn::TensorInfo tensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);
        std::vector<int> output_shape(tensorInfo.GetNumElements());

        if (tensorInfo.GetDataType() == DataType::Signed32)
        {
            ::memcpy(output_shape.data(), GetBuffer(m_Model, inputs[0]->buffer)->data.data(), tensorInfo.GetNumBytes());
        }
        if (tensorInfo.GetDataType() == DataType::QAsymmU8)
        {
            for(unsigned int i=0; i < tensorInfo.GetNumElements(); i++)
            {
                output_shape[i] = GetBuffer(m_Model, inputs[0]->buffer)->data.data()[i];
            }
        }
        // Change from signed to unsigned int to store in TransposeConvolution2dDescriptor.
        for (int dimension : output_shape)
        {
            desc.m_OutputShape.push_back(static_cast<unsigned int>(dimension));
        }
        desc.m_OutputShapeEnabled = true;

        // TfLite uses NHWC tensors
        const unsigned int outputHeight = desc.m_OutputShape[1];
        const unsigned int outputWidth  = desc.m_OutputShape[2];

        CalcPadding(inputHeight,
                    filterHeight,
                    desc.m_StrideY,
                    1, // DilationY
                    desc.m_PadTop,
                    desc.m_PadBottom,
                    options->padding,
                    outputHeight);

        CalcPadding(inputWidth,
                    filterWidth,
                    desc.m_StrideX,
                    1, // DilationX
                    desc.m_PadLeft,
                    desc.m_PadRight,
                    options->padding,
                    outputWidth);
    }
    else
    {
        CalcPadding(inputHeight,
                    filterHeight,
                    desc.m_StrideY,
                    1, // DilationY
                    desc.m_PadTop,
                    desc.m_PadBottom,
                    options->padding);

        CalcPadding(inputWidth,
                    filterWidth,
                    desc.m_StrideX,
                    1, // DilationX
                    desc.m_PadLeft,
                    desc.m_PadRight,
                    options->padding);
    }

    auto filterTensorAndData = CreateConstTensorNonPermuted(inputs[1], filterTensorInfo, inputTensorInfo.GetDataType());

    armnn::IConnectableLayer* layer = nullptr;
    auto layerName = fmt::format("TransposeConv:{}:{}", subgraphIndex, operatorIndex);

    if (desc.m_BiasEnabled)
    {
        auto biasTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 3);
        auto biasConstTensor = CreateConstTensorNonPermuted(inputs[3], biasTensorInfo, inputTensorInfo.GetDataType());
        layer = m_Network->AddTransposeConvolution2dLayer(desc,
                                                          filterTensorAndData.first,
                                                          biasConstTensor.first,
                                                          layerName.c_str());
    }
    else
    {
        layer = m_Network->AddTransposeConvolution2dLayer(desc,
                                                          filterTensorAndData.first,
                                                          EmptyOptional(),
                                                          layerName.c_str());
    }

    ARMNN_ASSERT(layer != nullptr);

    armnn::TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0 , { 2, 1 });
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    // only the tensors for the inputs are relevant, exclude the const (filter) tensor
    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[2]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseAveragePool2D(size_t subgraphIndex, size_t operatorIndex)
{
    ParsePool(subgraphIndex, operatorIndex, PoolingAlgorithm::Average);
}

void TfLiteParserImpl::ParseBatchMatMul(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 2);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    auto layerName = fmt::format("BatchMatMul:{}:{}", subgraphIndex, operatorIndex);

    TensorInfo inputXTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    TensorInfo inputYTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsBatchMatMulOptions();

    // Adjoint in tensorflow lite performs transpose operation
    BatchMatMulDescriptor descriptor(options->adj_x,
                                     options->adj_y,
                                     false,
                                     false);
                                     // Arbitrary DataLayout

    IConnectableLayer* layer = m_Network->AddBatchMatMulLayer(descriptor, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0, 1});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0], inputTensorIndexes[1]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseBatchToSpaceND(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 3);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    armnn::TensorInfo blockShapeTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);
    BufferRawPtr blockShapeBufferPtr = GetBuffer(m_Model, inputs[1]->buffer);

    armnn::TensorInfo cropsTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 2);
    BufferRawPtr cropsBufferPtr = GetBuffer(m_Model, inputs[2]->buffer);

    std::vector<unsigned int> blockShape(blockShapeTensorInfo.GetNumElements());
    ::memcpy(blockShape.data(), blockShapeBufferPtr->data.data(), blockShapeTensorInfo.GetNumBytes());

    std::vector<unsigned int> cropsVector(cropsTensorInfo.GetNumElements());
    ::memcpy(cropsVector.data(), cropsBufferPtr->data.data(), cropsTensorInfo.GetNumBytes());

    size_t step = 2;
    std::vector<std::pair<unsigned int, unsigned int>> crops;
    for (unsigned int i = 0; i < cropsTensorInfo.GetNumElements() / step; ++i)
    {
        crops.emplace_back(cropsVector[i * step], cropsVector[i * step + 1]);
    }

    armnn::BatchToSpaceNdDescriptor desc;
    desc.m_BlockShape = blockShape;
    desc.m_Crops = crops;
    desc.m_DataLayout = armnn::DataLayout::NHWC;

    auto layerName = fmt::format("BatchToSpaceND:{}:{}", subgraphIndex, operatorIndex);

    TensorInfo inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);

    IConnectableLayer* layer = m_Network->AddBatchToSpaceNdLayer(desc, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    CheckMatchingQuantization(inputTensorInfo, outputTensorInfo, layerName, "Input 0", "Output 0");
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseL2Normalization(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 1);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    L2NormalizationDescriptor desc;
    desc.m_DataLayout = armnn::DataLayout::NHWC;
    auto layerName = fmt::format("L2Normalization:{}:{}", subgraphIndex, operatorIndex);
    IConnectableLayer* layer = m_Network->AddL2NormalizationLayer(desc, layerName.c_str());

    ARMNN_ASSERT(layer != nullptr);

    armnn::TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseMaxPool2D(size_t subgraphIndex, size_t operatorIndex)
{
    ParsePool(subgraphIndex, operatorIndex, PoolingAlgorithm::Max);
}

void TfLiteParserImpl::ParseMaximum(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 2);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    auto layerName = fmt::format("Maximum:{}:{}", subgraphIndex, operatorIndex);

    TensorInfo inputTensorInfo  = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    TensorInfo input1TensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);
    CheckMatchingQuantization(inputTensorInfo, input1TensorInfo, layerName, "Input 0", "Input 1");

    IConnectableLayer* layer = m_Network->AddElementwiseBinaryLayer(BinaryOperation::Maximum, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0, 1});
    CheckMatchingQuantization(inputTensorInfo, outputTensorInfo, layerName, "Input 0", "Output 0");
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0], inputTensorIndexes[1]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseMinimum(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 2);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    auto layerName = fmt::format("Minimum:{}:{}", subgraphIndex, operatorIndex);

    TensorInfo inputTensorInfo  = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    TensorInfo input1TensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);
    CheckMatchingQuantization(inputTensorInfo, input1TensorInfo, layerName, "Input 0", "Input 1");

    IConnectableLayer* layer = m_Network->AddElementwiseBinaryLayer(BinaryOperation::Minimum, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0, 1});
    CheckMatchingQuantization(inputTensorInfo, outputTensorInfo, layerName, "Input 0", "Output 0");
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0], inputTensorIndexes[1]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParsePool(size_t subgraphIndex,
                                 size_t operatorIndex,
                                 PoolingAlgorithm algorithm)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsPool2DOptions();

    CHECK_SUPPORTED_FUSED_ACTIVATION(options, subgraphIndex, operatorIndex);

    std::string layerName;

    switch (algorithm)
    {
        case PoolingAlgorithm::Average:
            layerName =
                fmt::format("AveragePool2D:{}:{}", subgraphIndex, operatorIndex);
            break;
        case PoolingAlgorithm::Max:
            layerName =
                fmt::format("MaxPool2D:{}:{}", subgraphIndex, operatorIndex);
            break;
        default:
            ARMNN_ASSERT_MSG(false, "Unsupported Pooling Algorithm");
    }

    Pooling2dDescriptor desc;

    desc.m_PoolType = algorithm;
    desc.m_StrideX = CHECKED_NON_NEGATIVE(options->stride_w);
    desc.m_StrideY = CHECKED_NON_NEGATIVE(options->stride_h);
    desc.m_PoolWidth = CHECKED_NON_NEGATIVE(options->filter_width);
    desc.m_PoolHeight = CHECKED_NON_NEGATIVE(options->filter_height);
    desc.m_PaddingMethod = PaddingMethod::Exclude;
    desc.m_OutputShapeRounding = OutputShapeRounding::Floor;
    desc.m_DataLayout = armnn::DataLayout::NHWC;

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 1);
    armnn::TensorInfo inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);

    // assuming input is NHWC
    unsigned int inputHeight = inputTensorInfo.GetShape()[1];
    unsigned int inputWidth  = inputTensorInfo.GetShape()[2];

    CalcPadding(inputHeight, desc.m_PoolHeight, desc.m_StrideY, 1u,
                desc.m_PadTop, desc.m_PadBottom, options->padding);
    CalcPadding(inputWidth, desc.m_PoolWidth, desc.m_StrideX, 1u,
                desc.m_PadLeft, desc.m_PadRight, options->padding);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    IConnectableLayer* layer = m_Network->AddPooling2dLayer(desc, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    armnn::TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    CheckMatchingQuantization(inputTensorInfo, outputTensorInfo, layerName, "Input 0", "Output 0");
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    // register the input connection slots for the layer, connections are made after all layers have been created
    // only the tensors for the inputs are relevant, exclude the const tensors
    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    layer = AddFusedActivationLayer(layer, 0, options->fused_activation_function);
    // register the output connection slots for the layer, connections are made after all layers have been created
    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseSlice(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 3);
    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    SliceDescriptor desc;

    // set begin tensor info for slice descriptor
    armnn::TensorInfo beginTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);
    BufferRawPtr beginBufferPtr = GetBuffer(m_Model, inputs[1]->buffer);

    std::vector<unsigned int> begin(beginTensorInfo.GetNumElements());
    ::memcpy(begin.data(), beginBufferPtr->data.data(), beginTensorInfo.GetNumBytes());

    // set size tensor info for slice descriptor
    armnn::TensorInfo sizeTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 2);
    BufferRawPtr sizeBufferPtr = GetBuffer(m_Model, inputs[2]->buffer);

    std::vector<int> signedSize(sizeTensorInfo.GetNumElements(), 1);

    // if size buffer data is not specified, all contents of size vector remain as values of 1
    if (sizeBufferPtr->data.data())
    {
        ::memcpy(signedSize.data(), sizeBufferPtr->data.data(), sizeTensorInfo.GetNumBytes());
    }

    std::vector<unsigned int> size(sizeTensorInfo.GetNumElements());
    TensorInfo inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);

    for (unsigned int i = 0; i < signedSize.size(); ++i)
    {
        int signedValue = signedSize[i];

        if (signedValue < -1 || signedValue > static_cast<int>(inputTensorInfo.GetShape()[i] - begin[i]))
        {
            throw ParseException(fmt::format("Invalid value for size {} size must be in range "
                                             "[-1, inputDimSize - begin] [-1, {}] inclusive {}",
                                             signedValue,
                                             inputTensorInfo.GetShape()[i] - begin[i],
                                             CHECK_LOCATION().AsString()));
        }

        if (signedValue == -1)
        {
            size[i] = inputTensorInfo.GetShape()[i] - begin[i];
        }
        else
        {
            size[i] = static_cast<unsigned int>(signedValue);
        }
    }

    desc = SliceDescriptor(begin, size);

    auto layerName = fmt::format("Slice:{}:{}", subgraphIndex, operatorIndex);

    IConnectableLayer* const layer = m_Network->AddSliceLayer(desc, layerName.c_str());

    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    CheckMatchingQuantization(inputTensorInfo, outputTensorInfo, layerName, "Input 0", "Output 0");
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    // register the input connection slots for the layer, connections are made after all layers have been created
    // only the tensors for the inputs are relevant, exclude the const tensors
    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    // register the output connection slots for the layer, connections are made after all layers have been created
    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseSoftmax(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);
    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsSoftmaxOptions();

    SoftmaxDescriptor desc;
    desc.m_Beta = options->beta;

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 1);
    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    auto layerName = fmt::format("Softmax:{}:{}", subgraphIndex, operatorIndex);
    IConnectableLayer* const layer = m_Network->AddSoftmaxLayer(desc, layerName.c_str());

    armnn::TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    // register the input connection slots for the layer, connections are made after all layers have been created
    // only the tensors for the inputs are relevant, exclude the const tensors
    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    // register the output connection slots for the layer, connections are made after all layers have been created
    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseLogSoftmax(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    LogSoftmaxDescriptor desc;

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 1);
    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    auto layerName = fmt::format("LogSoftmax:{}:{}", subgraphIndex, operatorIndex);
    IConnectableLayer* const layer = m_Network->AddLogSoftmaxLayer(desc, layerName.c_str());

    armnn::TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    // register the input connection slots for the layer, connections are made after all layers have been created
    // only the tensors for the inputs are relevant, exclude the const tensors
    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    // register the output connection slots for the layer, connections are made after all layers have been created
    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseSpaceToBatchND(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 3);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    armnn::TensorInfo blockShapeTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);
    BufferRawPtr blockShapeBufferPtr = GetBuffer(m_Model, inputs[1]->buffer);

    armnn::TensorInfo padListTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 2);
    BufferRawPtr padListBufferPtr = GetBuffer(m_Model, inputs[2]->buffer);

    std::vector<unsigned int> blockShape(blockShapeTensorInfo.GetNumElements());
    ::memcpy(blockShape.data(), blockShapeBufferPtr->data.data(), blockShapeTensorInfo.GetNumBytes());

    std::vector<unsigned int> padListVector(padListTensorInfo.GetNumElements());
    ::memcpy(padListVector.data(), padListBufferPtr->data.data(), padListTensorInfo.GetNumBytes());

    size_t step = 2;
    std::vector<std::pair<unsigned int, unsigned int>> padList;
    for (unsigned int i = 0; i < padListTensorInfo.GetNumElements() / step; ++i)
    {
        padList.emplace_back(padListVector[i * step], padListVector[i * step + 1]);
    }

    armnn::SpaceToBatchNdDescriptor desc;
    desc.m_BlockShape = blockShape;
    desc.m_PadList = padList;
    desc.m_DataLayout = armnn::DataLayout::NHWC;

    auto layerName = fmt::format("SpaceToBatchND:{}:{}", subgraphIndex, operatorIndex);

    TensorInfo inputTensorInfo  = InputTensorInfo(subgraphIndex, operatorIndex, 0);

    IConnectableLayer* layer = m_Network->AddSpaceToBatchNdLayer(desc, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    CheckMatchingQuantization(inputTensorInfo, outputTensorInfo, layerName, "Input 0", "Output 0");
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseSpaceToDepth(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    TfLiteParserImpl::TensorRawPtrVector inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 1);
    TfLiteParserImpl::TensorRawPtrVector outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    armnn::SpaceToDepthDescriptor descriptor;

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsSpaceToDepthOptions();
    auto blockSize = options->block_size;
    if (blockSize < 2)
    {
        throw ParseException(
                fmt::format("Operation has invalid block size: {} Block size should be >= 2 {}",
                            blockSize,
                            CHECK_LOCATION().AsString()));
    }
    descriptor.m_BlockSize = armnn::numeric_cast<uint32_t>(blockSize);

    auto layerName = fmt::format("SpaceToDepth:{}:{}", subgraphIndex, operatorIndex);
    IConnectableLayer* layer = m_Network->AddSpaceToDepthLayer(descriptor, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);
    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

armnn::TensorInfo TfLiteParserImpl::OutputShapeOfSqueeze(std::vector<uint32_t> squeezeDims,
                                                         const armnn::TensorInfo& inputTensorInfo)
{
    CHECK_VALID_SIZE(squeezeDims.size(), 0, 1, 2, 3, 4);
    static const uint32_t dimensionSequence[] = { 0, 1, 2, 3 };

    if (inputTensorInfo.GetNumDimensions() > 4)
    {
        std::stringstream ss;
        ss << "Input tensor has unexpected number of dimensions:" << inputTensorInfo.GetNumDimensions()
           << " shape:" << inputTensorInfo.GetShape() << " "
           << CHECK_LOCATION().AsString();
        throw ParseException(ss.str());
    }

    if (squeezeDims.empty())
    {
        squeezeDims.assign(dimensionSequence,
                           dimensionSequence+inputTensorInfo.GetNumDimensions());
    }

    std::vector<uint32_t> outputDims;
    for(unsigned int i = 0; i < inputTensorInfo.GetNumDimensions(); i++)
    {
        bool skipSqueeze = (std::find(squeezeDims.begin(), squeezeDims.end(), i) == squeezeDims.end());
        auto currentDimension = inputTensorInfo.GetShape()[i];
        if (skipSqueeze || currentDimension != 1)
        {
            outputDims.push_back(currentDimension);
        }
    }

    if (outputDims.size() > 4)
    {
        std::stringstream ss;
        ss << "Output tensor has unexpected number of dimensions:" << inputTensorInfo.GetNumDimensions()
           << " shape:" << inputTensorInfo.GetShape() << " "
           << CHECK_LOCATION().AsString();
        throw ParseException(ss.str());
    }

    TensorShape outShape = TensorShape(static_cast<unsigned int>(outputDims.size()),
                                       outputDims.data());

    // we need to preserve the tensor type and the quantization data as well
    TensorInfo outTensorInfo = inputTensorInfo;
    outTensorInfo.SetShape(outShape);

    return outTensorInfo;
}

void TfLiteParserImpl::ParseShape(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 1);
    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    auto layerName = fmt::format("Shape:{}:{}", subgraphIndex, operatorIndex);

    IConnectableLayer* layer = m_Network->AddShapeLayer(layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    // Check if output tensor type is Signed32 or Signed64
    if (outputTensorInfo.GetDataType() != armnn::DataType::Signed32 &&
        outputTensorInfo.GetDataType() != armnn::DataType::Signed64)
    {
        throw ParseException(
            fmt::format(
                "Output tensor data type is not supported. (Supported types: Signed32 & Signed64) {}",
                CHECK_LOCATION().AsString()));
    }

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, outputTensorIndexes);
}

void TfLiteParserImpl::ParseSqueeze(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 1);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    const auto & operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto * options = operatorPtr->builtin_options.AsSqueezeOptions();
    auto layerName = fmt::format("Squeeze:{}:{}", subgraphIndex, operatorIndex);

    armnn::TensorInfo inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);

    std::vector<uint32_t> squeezeDim;
    // A single negative dim index is interpreted as a negative index in python
    // Meaning the index will be the shape size plus the negative index value
    if (options->squeeze_dims.size() == 1 && options->squeeze_dims[0] < 0)
    {
        int32_t dim = static_cast<int32_t>(inputTensorInfo.GetShape().GetNumDimensions()) + options->squeeze_dims[0];
        squeezeDim.push_back(static_cast<uint32_t>(dim));
    }
    else
    {
        squeezeDim = AsUnsignedVector(options->squeeze_dims);
    }

    armnn::TensorInfo outputTensorInfo = TfLiteParserImpl::OutputShapeOfSqueeze(squeezeDim, inputTensorInfo);

    CheckMatchingQuantization(inputTensorInfo, outputTensorInfo, layerName, "Input 0", "Output 0");

    ReshapeDescriptor reshapeDesc;
    reshapeDesc.m_TargetShape = outputTensorInfo.GetShape();

    auto outputTensorIds = GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex);
    m_TensorInfos[outputTensorIds[0]] = outputTensorInfo;

    IConnectableLayer* layer = m_Network->AddReshapeLayer(reshapeDesc, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseStridedSlice(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 4);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsStridedSliceOptions();

    StridedSliceDescriptor desc;
    desc.m_BeginMask = options->begin_mask;
    desc.m_EllipsisMask = options->ellipsis_mask;
    desc.m_EndMask = options->end_mask;
    desc.m_NewAxisMask = options->new_axis_mask;
    desc.m_ShrinkAxisMask = options->shrink_axis_mask;
    desc.m_DataLayout = armnn::DataLayout::NHWC;

    armnn::TensorInfo beginTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);
    BufferRawPtr beginBufferPtr = GetBuffer(m_Model, inputs[1]->buffer);

    std::vector<int> begin(beginTensorInfo.GetNumElements());
    ::memcpy(begin.data(), beginBufferPtr->data.data(), beginTensorInfo.GetNumBytes());

    armnn::TensorInfo endTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 2);
    BufferRawPtr endBufferPtr = GetBuffer(m_Model, inputs[2]->buffer);

    std::vector<int> end(endTensorInfo.GetNumElements());
    ::memcpy(end.data(), endBufferPtr->data.data(), endTensorInfo.GetNumBytes());

    armnn::TensorInfo strideTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 3);
    BufferRawPtr strideBufferPtr = GetBuffer(m_Model, inputs[3]->buffer);

    std::vector<int> stride(strideTensorInfo.GetNumElements());
    ::memcpy(stride.data(), strideBufferPtr->data.data(), strideTensorInfo.GetNumBytes());

    desc.m_Begin = begin;
    desc.m_End = end;
    desc.m_Stride = stride;

    auto layerName = fmt::format("StridedSlice:{}:{}", subgraphIndex, operatorIndex);
    IConnectableLayer* layer = m_Network->AddStridedSliceLayer(desc, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    armnn::TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseSub(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsSubOptions();

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 2);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    armnn::TensorInfo inputTensorInfo  = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    armnn::TensorInfo input1TensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);

    auto layerName = fmt::format("Sub:{}:{}", subgraphIndex, operatorIndex);
    IConnectableLayer* layer = m_Network->AddElementwiseBinaryLayer(BinaryOperation::Sub, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0, 1});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0], inputTensorIndexes[1]});

    layer = AddFusedActivationLayer(layer, 0, options->fused_activation_function);

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseDiv(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsDivOptions();

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 2);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    armnn::TensorInfo inputTensorInfo  = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    armnn::TensorInfo input1TensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);

    auto layerName = fmt::format("Div:{}:{}", subgraphIndex, operatorIndex);
    IConnectableLayer* layer = m_Network->AddElementwiseBinaryLayer(BinaryOperation::Div, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0, 1});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0], inputTensorIndexes[1]});
    layer = AddFusedActivationLayer(layer, 0, options->fused_activation_function);

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseFloorDiv(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 2);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    armnn::TensorInfo inputTensorInfo  = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    armnn::TensorInfo input1TensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);

    auto layerName = fmt::format("Div:{}:{}", subgraphIndex, operatorIndex);
    IConnectableLayer* layer = m_Network->AddElementwiseBinaryLayer(BinaryOperation::Div, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0, 1});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0], inputTensorIndexes[1]});
    layer = AddFusedFloorLayer(layer, 0);

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseAdd(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsAddOptions();

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 2);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    armnn::TensorInfo inputTensorInfo  = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    armnn::TensorInfo input1TensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);

    auto layerName = fmt::format("Add:{}:{}", subgraphIndex, operatorIndex);
    IConnectableLayer* layer = m_Network->AddElementwiseBinaryLayer(BinaryOperation::Add, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0, 1});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0], inputTensorIndexes[1]});
    layer = AddFusedActivationLayer(layer, 0, options->fused_activation_function);

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseMul(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsMulOptions();

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 2);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    armnn::TensorInfo inputTensorInfo  = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    armnn::TensorInfo input1TensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);

    auto layerName = fmt::format("Mul:{}:{}", subgraphIndex, operatorIndex);
    IConnectableLayer* layer = m_Network->AddElementwiseBinaryLayer(BinaryOperation::Mul, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0, 1});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0], inputTensorIndexes[1]});
    layer = AddFusedActivationLayer(layer, 0, options->fused_activation_function);

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseMean(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    TensorInfo inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    TensorInfo dimTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);

    armnn::MeanDescriptor desc;
    BufferRawPtr axisBufferPtr = GetBuffer(m_Model, inputs[1]->buffer);
    // Get const axis value from model and set it to descriptor.
    if (axisBufferPtr != nullptr)
    {
        std::vector<int32_t> axisData(dimTensorInfo.GetNumElements());
        ::memcpy(axisData.data(), axisBufferPtr->data.data(), dimTensorInfo.GetNumBytes());

        // Convert the axis to unsigned int and remove duplicates.
        auto rank = static_cast<int32_t>(inputTensorInfo.GetNumDimensions());
        std::set<unsigned int> uniqueAxis;
        std::transform(axisData.begin(),
                       axisData.end(),
                       std::inserter(uniqueAxis, uniqueAxis.begin()),
                       [rank](int i)->unsigned int{
                           return static_cast<uint32_t>(((i + rank) % rank)); });
        desc.m_Axis.assign(uniqueAxis.begin(), uniqueAxis.end());
    }
    else
    {
        for (uint32_t i = 0; i < inputTensorInfo.GetNumDimensions(); ++i)
        {
            desc.m_Axis.push_back(i);
        }
    }

    armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);

    desc.m_KeepDims = inputTensorInfo.GetNumDimensions() == outputTensorInfo.GetNumDimensions() ? true : false;

    auto layerName = fmt::format("Mean:{}:{}", subgraphIndex, operatorIndex);
    IConnectableLayer* layer = m_Network->AddMeanLayer(desc, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParsePad(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    TfLiteParserImpl::TensorRawPtrVector inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);

    TfLiteParserImpl::TensorRawPtrVector outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    armnn::TensorInfo inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    armnn::TensorInfo padTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);

    std::vector<unsigned int> padBuffer = GetUIntBuffer(padTensorInfo, m_Model, inputs[1]->buffer);

    size_t step = 2;
    armnn::PadDescriptor desc;
    auto opcode = GetOpCode(m_Model, subgraphIndex, operatorIndex);

    if (opcode == tflite::BuiltinOperator_PAD)
    {
        CHECK_VALID_SIZE(inputs.size(), 2);

        if (inputTensorInfo.IsQuantized())
        {
            desc.m_PadValue = static_cast<float>(inputTensorInfo.GetQuantizationOffset());
        }
    }
    else if (opcode == tflite::BuiltinOperator_PADV2)
    {
        CHECK_VALID_SIZE(inputs.size(), 3);

        armnn::TensorInfo padValueTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 2);

        if (padValueTensorInfo.GetNumElements() != 1)
        {
            ARMNN_THROW_PARSE_EXCEPTION("Multiple padding values are not supported in PADV2");
        }
        BufferRawPtr padValueBufferPtr = GetBuffer(m_Model, inputs[2]->buffer);

        // Get the pad value from the input tensor
        if (padValueBufferPtr->data.size() > 0)
        {
            switch (padValueTensorInfo.GetDataType())
            {
                case armnn::DataType::Float32:
                {
                    std::vector<float> padValueBuffer(padValueTensorInfo.GetNumElements());
                    ::memcpy(padValueBuffer.data(), padValueBufferPtr->data.data(), padValueBufferPtr->data.size());
                    desc.m_PadValue = padValueBuffer[0];
                    break;
                }
                case armnn::DataType::QAsymmU8:
                {
                    std::vector<uint8_t> padValueBuffer(padValueTensorInfo.GetNumElements());
                    ::memcpy(padValueBuffer.data(), padValueBufferPtr->data.data(), padValueBufferPtr->data.size());
                    desc.m_PadValue = armnn::Dequantize<uint8_t>(padValueBuffer[0],
                                                                 padValueTensorInfo.GetQuantizationScale(),
                                                                 padValueTensorInfo.GetQuantizationOffset());
                    break;
                }
                case armnn::DataType::QAsymmS8:
                case armnn::DataType::QSymmS8:
                {
                    std::vector<int8_t> padValueBuffer(padValueTensorInfo.GetNumElements());
                    ::memcpy(padValueBuffer.data(), padValueBufferPtr->data.data(), padValueBufferPtr->data.size());
                    desc.m_PadValue = armnn::Dequantize<int8_t>(padValueBuffer[0],
                                                                padValueTensorInfo.GetQuantizationScale(),
                                                                padValueTensorInfo.GetQuantizationOffset());
                    break;
                }
                default: ARMNN_THROW_PARSE_EXCEPTION("Unsupported DataType");
            }
        }
        else if (inputTensorInfo.IsQuantized())
        {
            desc.m_PadValue = static_cast<float>(inputTensorInfo.GetQuantizationOffset());
        }
    }

    for (unsigned int i = 0; i < padTensorInfo.GetNumElements() / step; ++i)
    {
        desc.m_PadList.emplace_back(padBuffer[i * step], padBuffer[i * step + 1]);
    }

    auto layerName = (opcode == tflite::BuiltinOperator_PAD) ? fmt::format("Pad:{}:{}", subgraphIndex, operatorIndex)
            : fmt::format("PadV2:{}:{}", subgraphIndex, operatorIndex);

    IConnectableLayer* layer = m_Network->AddPadLayer(desc, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);
    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseMirrorPad(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    TfLiteParserImpl::TensorRawPtrVector inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 2);

    TfLiteParserImpl::TensorRawPtrVector outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    armnn::TensorInfo inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);

    armnn::TensorInfo padTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);
    BufferRawPtr bufferPtr = GetBuffer(m_Model, inputs[1]->buffer);

    std::vector<unsigned int> padBuffer(padTensorInfo.GetNumElements());
    ::memcpy(padBuffer.data(), bufferPtr->data.data(), padTensorInfo.GetNumBytes());

    size_t step = 2;
    armnn::PadDescriptor desc;
    for (unsigned int i = 0; i < padTensorInfo.GetNumElements() / step; ++i)
    {
        desc.m_PadList.emplace_back(padBuffer[i * step], padBuffer[i * step + 1]);
    }

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsMirrorPadOptions();

    if (options->mode == tflite::MirrorPadMode_REFLECT)
    {
        desc.m_PaddingMode = PaddingMode::Reflect;
    }
    else if (options->mode == tflite::MirrorPadMode_SYMMETRIC)
    {
        desc.m_PaddingMode = PaddingMode::Symmetric;
    }
    else
    {
        ARMNN_THROW_PARSE_EXCEPTION("PaddingMode must be either REFLECT or SYMMETRIC");
    }

    // If padding mode is Reflect then both paddings must be no greater than inputShape(i) - 1.
    // If padding mode is Symmetric then both paddings must be no greater than inputShape(i).
    auto inputShape = inputTensorInfo.GetShape();
    auto padList = desc.m_PadList;

    const unsigned int isReflect = static_cast<unsigned int>(desc.m_PaddingMode == PaddingMode::Reflect);
    for(unsigned int i = 0; i < padList.size(); ++i)
    {
        if(padList.at(i).first > (inputShape[i] - isReflect) ||
           padList.at(i).second > (inputShape[i] - isReflect))
        {
            ARMNN_THROW_PARSE_EXCEPTION("Padding values must be less (Reflect) or "
                                        "equal (Symmetric) to the dimension size.");
        }
    }

    auto layerName = fmt::format("MirrorPad:{}:{}", subgraphIndex, operatorIndex);

    IConnectableLayer* layer = m_Network->AddPadLayer(desc, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);
    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParsePrelu(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 2);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    auto layerName = fmt::format("Prelu:{}:{}", subgraphIndex, operatorIndex);

    armnn::TensorInfo inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    armnn::TensorInfo alphaTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);

    IConnectableLayer* layer = m_Network->AddPreluLayer(layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);


    if (IsConstTensor(inputs[1]))
    {
        auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
        armnn::IInputSlot* slot = &(layer->GetInputSlot(0));
        RegisterConsumerOfTensor(subgraphIndex, inputTensorIndexes[0], slot);

        auto alphaTensorAndData = CreateConstTensorNonPermuted(inputs[1], alphaTensorInfo,
                                                               inputTensorInfo.GetDataType());
        std::string constLayerName = fmt::format("Constant:{}", inputs[1]->name);
        IConnectableLayer* constLayer =
                    m_Network->AddConstantLayer(alphaTensorAndData.first, constLayerName.c_str());
        ARMNN_ASSERT(constLayer != nullptr);

        constLayer->GetOutputSlot(0).SetTensorInfo(alphaTensorInfo);
        constLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(1));
        RegisterOutputSlots(subgraphIndex,
                            VIRTUAL_OPERATOR_ID,
                            constLayer,
                            { inputTensorIndexes[1] });
    }
    else
    {
        auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
        RegisterInputSlots(subgraphIndex, operatorIndex, layer, inputTensorIndexes);
    }

    armnn::TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0, 1});
    CheckMatchingQuantization(inputTensorInfo, outputTensorInfo, layerName, "Input 0", "Output 0");
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, outputTensorIndexes);
}

void TfLiteParserImpl::ParseQuantize(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 1);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    auto layerName = fmt::format("Quantize:{}:{}", subgraphIndex, operatorIndex);

    IConnectableLayer* layer = m_Network->AddQuantizeLayer(layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, outputTensorIndexes);
}

void TfLiteParserImpl::ParseRelu(size_t subgraphIndex, size_t operatorIndex)
{
    ParseActivation(subgraphIndex,operatorIndex, ActivationFunction::ReLu);
}

void TfLiteParserImpl::ParseRelu6(size_t subgraphIndex, size_t operatorIndex)
{
    ParseActivation(subgraphIndex,operatorIndex, ActivationFunction::BoundedReLu);
}

void TfLiteParserImpl::ParseLeakyRelu(size_t subgraphIndex, size_t operatorIndex)
{
    ParseActivation(subgraphIndex, operatorIndex, ActivationFunction::LeakyReLu);
}

void TfLiteParserImpl::ParseLogistic(size_t subgraphIndex, size_t operatorIndex)
{
    ParseActivation(subgraphIndex,operatorIndex,ActivationFunction::Sigmoid);
}

void TfLiteParserImpl::ParseTanH(size_t subgraphIndex, size_t operatorIndex)
{
    ParseActivation(subgraphIndex,operatorIndex,ActivationFunction::TanH);
}

void TfLiteParserImpl::ParseElu(size_t subgraphIndex, size_t operatorIndex)
{
    ParseActivation(subgraphIndex, operatorIndex, ActivationFunction::Elu);
}

void TfLiteParserImpl::ParseHardSwish(size_t subgraphIndex, size_t operatorIndex)
{
    ParseActivation(subgraphIndex, operatorIndex, ActivationFunction::HardSwish);
}

void TfLiteParserImpl::ParseActivation(size_t subgraphIndex, size_t operatorIndex, ActivationFunction activationType)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);
    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    IgnoreUnused(operatorPtr);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 1);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    auto layerName = fmt::format("Activation:");
    ActivationDescriptor activationDesc;
    activationDesc.m_Function = activationType;

    switch (activationType)
    {
        case ActivationFunction::ReLu:
        {
            layerName += fmt::format("RELU:{}:{}", subgraphIndex, operatorIndex);
            break;
        }
        case ActivationFunction::BoundedReLu:
        {
            layerName += fmt::format("RELU6:{}:{}", subgraphIndex, operatorIndex);
            activationDesc.m_A = 6.0f;
            activationDesc.m_B = 0.0f;
            break;
        }
        case ActivationFunction::Sigmoid:
        {
            layerName += fmt::format("SIGMOID:{}:{}", subgraphIndex, operatorIndex);
            break;
        }
        case ActivationFunction::TanH:
        {
            layerName += fmt::format("TANH:{}:{}", subgraphIndex, operatorIndex);
            activationDesc.m_A = 1.0f;
            activationDesc.m_B = 1.0f;
            break;
        }
        case ActivationFunction::LeakyReLu:
        {
            layerName += fmt::format("LEAKYRELU:{}:{}", subgraphIndex, operatorIndex);
            const auto* options = operatorPtr->builtin_options.AsLeakyReluOptions();
            activationDesc.m_A = options->alpha;
            break;
        }
        case ActivationFunction::Elu:
        {
            layerName += fmt::format("ELU:{}:{}", subgraphIndex, operatorIndex);
            activationDesc.m_A = 1.0f;
            break;
        }
        case ActivationFunction::HardSwish:
        {
            layerName += fmt::format("HARDSWISH:{}:{}", subgraphIndex, operatorIndex);
            break;
        }
        default:
        {
            throw ParseException(
                fmt::format("Unexpected ActivationFunction[{}] when creating layerName {} ",
                            static_cast<int>(activationType), CHECK_LOCATION().AsString()));
        }
    }

    IConnectableLayer* const layer = m_Network->AddActivationLayer(activationDesc, layerName.c_str());

    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    // register the input connection slots for the layer, connections are made after all layers have been created
    // only the tensors for the inputs are relevant, exclude the const tensors
    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    // register the output connection slots for the layer, connections are made after all layers have been created
    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}
armnn::TensorInfo TfLiteParserImpl::OutputShapeOfReshape(const armnn::TensorInfo& inputTensorInfo,
                                                         const std::vector<int32_t>& targetDimsIn)
{
    std::vector<unsigned int> outputDims(targetDimsIn.begin(), targetDimsIn.end());
    const auto stretchDim = std::find(targetDimsIn.begin(), targetDimsIn.end(), -1);

    if (stretchDim != targetDimsIn.end())
    {
        if (std::find(std::next(stretchDim), targetDimsIn.end(), -1) != targetDimsIn.end())
        {
            throw ParseException(
                fmt::format("At most one component of shape can be -1 {}", CHECK_LOCATION().AsString()));
        }

        auto targetNumElements =
            armnn::numeric_cast<unsigned int>(
                std::accumulate(targetDimsIn.begin(), targetDimsIn.end(), -1, std::multiplies<int32_t>()));

        auto stretchIndex = static_cast<size_t>(std::distance(targetDimsIn.begin(), stretchDim));
        outputDims[stretchIndex] = inputTensorInfo.GetNumElements() / targetNumElements;
    }

    TensorShape outputShape = TensorShape(static_cast<unsigned int>(outputDims.size()), outputDims.data());

    TensorInfo reshapeInfo = inputTensorInfo;
    reshapeInfo.SetShape(outputShape);

    return reshapeInfo;
}

void TfLiteParserImpl::ParseReshape(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsReshapeOptions();
    auto layerName = fmt::format("Reshape:{}:{}", subgraphIndex, operatorIndex);

    armnn::TensorInfo inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    armnn::TensorInfo actualOutputTensorInfo  = ToTensorInfo(outputs[0]);
    CheckMatchingQuantization(inputTensorInfo, actualOutputTensorInfo, layerName, "Input 0", "Output 0");

    // Extracting new shape for the output
    // There are two ways it can be passed
    //  * First is to define the target shape in the operator built-in options
    //  * Second is to pass it as a second input tensor
    std::vector<int32_t> targetShape;
    bool targetShapeFound = false;
    // Check if built-in options were given
    if (options != nullptr)
    {
        // make sure the parameter is given
        if (options->new_shape.empty() == false)
        {
            targetShape = options->new_shape;
            targetShapeFound = true;
        }
    }

    // If there is no built-in option given or if the built-in new_shape parameter was empty
    if (!targetShapeFound)
    {
        // Check for a second input tensor
        if (inputs.size() > 1 && inputs[1] != nullptr)
        {
            if (inputs[1]->is_variable)
            {
                ARMNN_THROW_PARSE_EXCEPTION( "Target shapes defined in non-const input tensors is not supported");
            }

            if (inputs[1]->shape.size() != 1)
            {
                ARMNN_THROW_PARSE_EXCEPTION("Target 'shape' input is not a 1D tensor");
            }

            if (inputs[1]->type != tflite::TensorType_INT32)
            {
                ARMNN_THROW_PARSE_EXCEPTION("Target 'shape' input is not an int32 type");
            }

            // Extract target shape from input
            auto bufferPtr = GetBuffer(m_Model, inputs[1]->buffer);
            auto values = reinterpret_cast<const int32_t*>(bufferPtr->data.data());
            if (values)
            {
                for (int i = 0; i < inputs[1]->shape[0]; ++i)
                {
                    targetShape.push_back(values[i]);
                }
            }
            else
            {
                try
                {
                    // We attempt to infer during Runtime.
                    TensorShape reshapeShapes = ToTensorInfo(inputs[1]).GetShape();

                    if (reshapeShapes[0] == actualOutputTensorInfo.GetNumDimensions())
                    {
                        for (unsigned int i = 0; i < actualOutputTensorInfo.GetShape().GetNumDimensions(); ++i)
                        {
                            targetShape.push_back(actualOutputTensorInfo.GetShape()[i]);
                        }
                    }
                    // The parser only supports shape (batch, -1) or (-1) for non-constant shape input.
                    else if (reshapeShapes[0] > 2)
                    {
                        throw ParseException(fmt::format("Invalid input shape '{}' in Reshape layer '{}' {}. "
                                                         "When inferring during runtime, the parser only supports "
                                                         "shape (batch, -1) or (-1) for target shape input.",
                                                         reshapeShapes[0],
                                                         layerName,
                                                         CHECK_LOCATION().AsString()));
                    }
                    else
                    {
                        const int32_t numInputElements = inputTensorInfo.GetNumElements();
                        const int32_t inputTensorShape = inputTensorInfo.GetShape()[0];
                        if (reshapeShapes[0] == 1)
                        {
                            targetShape = {numInputElements};
                        }
                        else if (reshapeShapes[0] == 2)
                        {
                            targetShape = {inputTensorShape, numInputElements / inputTensorShape};
                        }
                    }
                }
                catch (const std::exception& exc)
                {
                    ARMNN_THROW_PARSE_EXCEPTION("Failed attempt to infer during runtime the target shape input for "
                                                "Reshape operation. Reshape operator target shape input buffer data "
                                                "is null. " << exc.what());
                }
            }
        }
        else
        {
            ARMNN_THROW_PARSE_EXCEPTION("Target shape not defined in reshape parameters or input tensor. "
                                        "At least one method required");
        }
    }

    armnn::TensorInfo reshapeOutputTensorInfo =
        TfLiteParserImpl::OutputShapeOfReshape(inputTensorInfo, targetShape);

    // Check for valid input size and that reshape parameters equal output shape
    // The output shape can be provided to us in 2 ways:
    // 1. through the normal 'shape' parameter given by outputs[indx]->shape
    // 2. through additional parameter 'shape_signature' given by outputs[indx]->buffer.
    //    This parameter can sometimes contain -1 value not visible in the 'shape' parameter.
    const armnn::TensorShape& reshapeOutputTensorShape = reshapeOutputTensorInfo.GetShape();
    if (inputs.size() > 1 && !CheckShape(reshapeOutputTensorShape, outputs[0]->shape))
    {
        // Attempt to extract output shape from secondary 'shape_signature'
        // parameter and try to CheckShape() with this param.
        std::vector<int32_t> secondaryOutputTargetShape = outputs[0]->shape_signature;

        // if outputs[0]->shape_signature contain a -1 value, we need to compute its actual value
        // from reshape input in order to correctly verify reshape parameters equal output shape
        armnn::TensorInfo secondaryReshapeOutputTensorInfo =
            TfLiteParserImpl::OutputShapeOfReshape(inputTensorInfo, secondaryOutputTargetShape);

        if (!CheckShape(reshapeOutputTensorShape, secondaryReshapeOutputTensorInfo.GetShape()))
        {
            std::stringstream ss;
            ss << "New shape defined in reshape parameters "
               << reshapeOutputTensorShape
               << " does not equal output shape "
               << actualOutputTensorInfo.GetShape()
               << ": "
               << CHECK_LOCATION().AsString();
            throw ParseException(ss.str());
        }
    }
    auto outputTensorIds = GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex);

    ReshapeDescriptor reshapeDesc;
    reshapeDesc.m_TargetShape = reshapeOutputTensorInfo.GetShape();
    m_TensorInfos[outputTensorIds[0]] = reshapeOutputTensorInfo;

    IConnectableLayer* layer = m_Network->AddReshapeLayer(reshapeDesc, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);
    layer->GetOutputSlot(0).SetTensorInfo(reshapeOutputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseResizeBilinear(size_t subgraphIndex, size_t operatorIndex)
{
    ParseResize(subgraphIndex, operatorIndex, ResizeMethod::Bilinear);
}

void TfLiteParserImpl::ParseResizeNearestNeighbor(size_t subgraphIndex, size_t operatorIndex)
{
    ParseResize(subgraphIndex, operatorIndex, ResizeMethod::NearestNeighbor);
}

void TfLiteParserImpl::ParseResize(size_t subgraphIndex, size_t operatorIndex, ResizeMethod resizeMethod)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 2);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    armnn::TensorInfo sizeTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);

    // Data for the parsed tensor args (size) must be stored locally.
    std::vector<int32_t> sizeTensorData(sizeTensorInfo.GetNumElements());

    BufferRawPtr sizeBufferPtr = GetBuffer(m_Model, inputs[1]->buffer);
    ::memcpy(sizeTensorData.data(), sizeBufferPtr->data.data(), sizeTensorInfo.GetNumBytes());

    ResizeDescriptor desc;
    desc.m_Method       = resizeMethod;
    desc.m_TargetHeight = static_cast<uint32_t> (sizeTensorData[0]);
    desc.m_TargetWidth  = static_cast<uint32_t> (sizeTensorData[1]);
    desc.m_DataLayout   = armnn::DataLayout::NHWC;

    auto layerName = fmt::format("Resize:");

    switch (resizeMethod)
    {
        case ResizeMethod::Bilinear:
        {
            layerName += fmt::format("BILINEAR:{}:{}", subgraphIndex, operatorIndex);

            const auto & operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
            const auto * options     = operatorPtr->builtin_options.AsResizeBilinearOptions();

            desc.m_AlignCorners = options->align_corners;
            break;
        }
        case ResizeMethod::NearestNeighbor:
        {
            layerName += fmt::format("NEARESTNEIGHBOR:{}:{}", subgraphIndex, operatorIndex);
            break;
        }
        default:
        {
            throw ParseException(
                fmt::format("Unexpected ResizeMethod[{}] when creating layerName {} ",
                            static_cast<int>(resizeMethod), CHECK_LOCATION().AsString()));
        }
    }

    TensorInfo inputTensorInfo  = InputTensorInfo(subgraphIndex, operatorIndex, 0);

    IConnectableLayer* layer = m_Network->AddResizeLayer(desc, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);
    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    CheckMatchingQuantization(inputTensorInfo, outputTensorInfo, layerName, "Input 0", "Output 0");
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, outputTensorIndexes);
}

void TfLiteParserImpl::ParseConcatenation(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsConcatenationOptions();

    CHECK_SUPPORTED_FUSED_ACTIVATION(options, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    auto inputTensorIds = GetInputTensorIds(m_Model, subgraphIndex, operatorIndex);

    CHECK_VALID_SIZE(outputs.size(), 1);

    unsigned int numConcatView = static_cast<unsigned int>(inputs.size());
    uint32_t inputRank = InputTensorInfo(subgraphIndex, operatorIndex, 0).GetNumDimensions();

    const unsigned int concatDimInput = static_cast<unsigned int>(
            (static_cast<int>(inputRank) + options->axis) % static_cast<int>(inputRank));

    OriginsDescriptor concatDescriptor(static_cast<uint32_t>(numConcatView), inputRank);
    concatDescriptor.SetConcatAxis(concatDimInput);
    unsigned int mergeDimOrigin = 0;

    for (unsigned int viewIndex = 0; viewIndex < numConcatView; ++viewIndex)
    {
        TensorInfo inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, viewIndex);

        // This set up concatDescriptor view origin
        armnnUtils::ProcessConcatInputTensorInfo(
                inputTensorInfo, concatDescriptor, concatDimInput, viewIndex, mergeDimOrigin);
    }

    auto layerName = fmt::format("Concatenation:{}:{}", subgraphIndex, operatorIndex);

    IConnectableLayer* layer = m_Network->AddConcatLayer(concatDescriptor, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);
    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes});

    // add fused activation layer
    layer = AddFusedActivationLayer(layer, 0, options->fused_activation_function);

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseFullyConnected(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    const auto& operatorRfr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto options = operatorRfr->builtin_options.AsFullyConnectedOptions();

    CHECK_SUPPORTED_FUSED_ACTIVATION(options, subgraphIndex, operatorIndex);

    FullyConnectedDescriptor desc;
    desc.m_BiasEnabled = false;
    desc.m_TransposeWeightMatrix = true;

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    armnn::TensorInfo filterTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);

    // Fully Connected Layer accepts two dimensional weights input
    int32_t weightsDimension = static_cast<int32_t>(filterTensorInfo.GetNumDimensions());
    if (weightsDimension != 2)
    {
        throw ParseException(
            fmt::format("Dimension {} for Fully Connected weights is not supported by Armnn. "
                        "Node {}",
                        weightsDimension,
                        CHECK_LOCATION().AsString()));
    }

    armnn::IConnectableLayer* layer = nullptr;
    auto layerName = fmt::format("FullyConnected:{}:{}", subgraphIndex, operatorIndex);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    // Add the first input tensor to the registration list
    std::vector<unsigned int> tensorIndexesToRegister = {inputTensorIndexes[0]};
    armnn::TensorInfo inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);

    desc.m_ConstantWeights = IsConstTensor(inputs[1]);

    // Add the weights input to the registration list, constant layers will be added by SetupConstantLayers if constant.
    tensorIndexesToRegister.emplace_back(inputTensorIndexes[1]);

    if (ShouldConstantTensorBeConverted(inputs[1], inputTensorInfo.GetDataType(), filterTensorInfo.GetDataType()))
    {
        m_ConstantsToDequantize.emplace_back(inputs[1]->buffer);
    }

    if (inputs.size() == 3)
    {
        desc.m_BiasEnabled = true;
        armnn::TensorInfo biasTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 2);

        // Add the biases input to the registration list, constant layer will be added by SetupConstantLayers.
        tensorIndexesToRegister.emplace_back(inputTensorIndexes[2]);

        if (ShouldConstantTensorBeConverted(inputs[2], inputTensorInfo.GetDataType(), biasTensorInfo.GetDataType()))
        {
            m_ConstantsToDequantize.emplace_back(inputs[2]->buffer);
        }
    }

    // Filters and biases are always passed to fully connected as inputs
    layer = m_Network->AddFullyConnectedLayer(desc, layerName.c_str());

    ARMNN_ASSERT(layer != nullptr);

    unsigned int startingSlotIndex = 0;
    if (inputTensorInfo.GetNumDimensions() > 2)
    {
        // Add reshape to flatten to 2D [batch_size, input_size],
        // where "input_size" corresponds to the number of inputs to the layer,
        // matching the second dimension of weights,
        // and "batch_size" is calculated by dividing the number of elements by "input_size".
        std::vector<unsigned int> reshapedDimensions(2);
        reshapedDimensions[1] = filterTensorInfo.GetShape()[1];
        reshapedDimensions[0] = inputTensorInfo.GetNumElements() / reshapedDimensions[1];

        if (inputTensorInfo.GetNumElements() % reshapedDimensions[1] != 0)
        {
            throw ParseException(
                    fmt::format("Failed to deduce input tensor shape from filter size {} {}",
                                reshapedDimensions[1],
                                CHECK_LOCATION().AsString()));
        }

        armnn::TensorInfo reshapedTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);
        reshapedTensorInfo.SetShape(armnn::TensorShape{ 2, reshapedDimensions.data() });
        inputTensorInfo = reshapedTensorInfo;

        std::string reshapeLayerName = fmt::format("Reshape_for:{}", layer->GetName());
        armnn::ReshapeDescriptor reshapeDescriptor;
        reshapeDescriptor.m_TargetShape = reshapedTensorInfo.GetShape();
        armnn::IConnectableLayer* reshapeLayer = m_Network->AddReshapeLayer(reshapeDescriptor,
                                                                            reshapeLayerName.c_str());

        reshapeLayer->GetOutputSlot(0).SetTensorInfo(reshapedTensorInfo);
        reshapeLayer->GetOutputSlot(0).Connect(layer->GetInputSlot(0));

        RegisterInputSlots(subgraphIndex, operatorIndex, reshapeLayer, {inputTensorIndexes[0]});
        // Fc layer connects to the reshape layer, so we skip the first input slot when registering fc's input slots
        tensorIndexesToRegister.erase(tensorIndexesToRegister.begin());
        startingSlotIndex = 1;
    }

    RegisterInputSlots(subgraphIndex, operatorIndex, layer, tensorIndexesToRegister, startingSlotIndex);

    armnn::TensorInfo outputTensorInfo = OutputTensorInfoFromShapes(subgraphIndex, operatorIndex, layer, 0,
                                                                    { inputTensorInfo.GetShape(),
                                                                      filterTensorInfo.GetShape() });

    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    if (outputTensorInfo.GetNumDimensions() > 2)
    {
        // Calculate reshape to flatten to 2D [batch_size, input_size]
        std::vector<unsigned int> reshapedDimensions(2);
        reshapedDimensions[1] = filterTensorInfo.GetShape()[0];
        reshapedDimensions[0] = outputTensorInfo.GetNumElements() / reshapedDimensions[1];
        armnn::TensorInfo reshapedOutputTensorInfo = outputTensorInfo;
        if (outputTensorInfo.GetNumElements() % reshapedDimensions[1] != 0)
        {
            throw ParseException(
                    fmt::format("Failed to deduce output tensor shape from filter size {} {}",
                                reshapedDimensions[1],
                                CHECK_LOCATION().AsString()));
        }
        reshapedOutputTensorInfo.SetShape(armnn::TensorShape{ 2, reshapedDimensions.data() });
        layer->GetOutputSlot(0).SetTensorInfo(reshapedOutputTensorInfo);

        std::string reshapeLayerName = fmt::format("ExpandDims:{}:{}", subgraphIndex, operatorIndex);
        layer = AddReshapeLayer(layer, 0, reshapeLayerName, outputTensorInfo);
    }

    // we need to add the activation layer and fortunately we don't need to care about the data layout
    armnn::IConnectableLayer* fusedActivationLayer = AddFusedActivationLayer(layer, 0,
                                                                             options->fused_activation_function);

    // register the output connection slots for the layer, connections are made after all layers have been created
    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, fusedActivationLayer, {outputTensorIndexes[0]});

    m_TensorInfos[outputTensorIndexes[0]] = layer->GetOutputSlot(0).GetTensorInfo();
}

void TfLiteParserImpl::ParseDetectionPostProcess(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 4);

    // Obtain custom options from flexbuffers
    auto custom_options = operatorPtr->custom_options;
    const flexbuffers::Map& m = flexbuffers::GetRoot(custom_options.data(), custom_options.size()).AsMap();

    // Obtain descriptor information from tf lite
    DetectionPostProcessDescriptor desc;
    desc.m_MaxDetections           = m["max_detections"].AsUInt32();
    desc.m_MaxClassesPerDetection  = m["max_classes_per_detection"].AsUInt32();
    desc.m_NmsScoreThreshold       = m["nms_score_threshold"].AsFloat();
    desc.m_NmsIouThreshold         = m["nms_iou_threshold"].AsFloat();
    desc.m_NumClasses              = m["num_classes"].AsUInt32();
    desc.m_ScaleH                  = m["h_scale"].AsFloat();
    desc.m_ScaleW                  = m["w_scale"].AsFloat();
    desc.m_ScaleX                  = m["x_scale"].AsFloat();
    desc.m_ScaleY                  = m["y_scale"].AsFloat();

    if (!(m["use_regular_nms"].IsNull()))
    {
        desc.m_UseRegularNms       = m["use_regular_nms"].AsBool();
    }
    if (!(m["detections_per_class"].IsNull()))
    {
        desc.m_DetectionsPerClass  = m["detections_per_class"].AsUInt32();
    }

    if (desc.m_NmsIouThreshold <= 0.0f || desc.m_NmsIouThreshold > 1.0f)
    {
        throw InvalidArgumentException("DetectionPostProcessTFLiteParser: Intersection over union threshold "
                                       "must be positive and less than or equal to 1.");
    }

    armnn::TensorInfo anchorTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 2);
    auto anchorTensorAndData = CreateConstTensorNonPermuted(inputs[2], anchorTensorInfo);

    auto layerName = fmt::format("DetectionPostProcess:{}:{}", subgraphIndex, operatorIndex);
    IConnectableLayer* layer = m_Network->AddDetectionPostProcessLayer(desc, anchorTensorAndData,
                                                                       layerName.c_str());

    ARMNN_ASSERT(layer != nullptr);

    // The model does not specify the output shapes.
    // The output shapes are calculated from the max_detection and max_classes_per_detection.
    unsigned int numDetectedBox = desc.m_MaxDetections * desc.m_MaxClassesPerDetection;
    m_OverriddenOutputShapes.push_back({ 1, numDetectedBox, 4 });
    m_OverriddenOutputShapes.push_back({ 1, numDetectedBox });
    m_OverriddenOutputShapes.push_back({ 1, numDetectedBox });
    m_OverriddenOutputShapes.push_back({ 1 });

    for (unsigned int i = 0 ; i < outputs.size() ; ++i)
    {
        armnn::TensorInfo detectionBoxOutputTensorInfo = ToTensorInfo(outputs[i], m_OverriddenOutputShapes[i]);
        layer->GetOutputSlot(i).SetTensorInfo(detectionBoxOutputTensorInfo);
    }

    // Register the input connection slots for the layer, connections are made after all layers have been created
    // only the tensors for the inputs are relevant, exclude the const tensors
    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0], inputTensorIndexes[1]});

    // Register the output connection slots for the layer, connections are made after all layers have been created
    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0],
                                                              outputTensorIndexes[1],
                                                              outputTensorIndexes[2],
                                                              outputTensorIndexes[3]});
}

/// The TfLite Pack operator is equivalent to the ArmNN Stack operator
void TfLiteParserImpl::ParsePack(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    if (inputs.size() < 1)
    {
        throw ParseException("Pack must have at least one input.");
    }

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsPackOptions();

    StackDescriptor desc;
    desc.m_Axis = static_cast<uint32_t>(options->axis);
    desc.m_NumInputs = static_cast<uint32_t>(inputs.size());

    // Use the tensor shape of the first input as the "correct" input shape in the descriptor
    armnn::TensorInfo inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    desc.m_InputShape = inputTensorInfo.GetShape();

    auto layerName = fmt::format("Pack:{}:{}", subgraphIndex, operatorIndex);
    IConnectableLayer* layer = m_Network->AddStackLayer(desc, layerName.c_str());

    ARMNN_ASSERT(layer != nullptr);

    armnn::TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseUnidirectionalSequenceLSTM(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);

    if (inputs.size() < 2)
    {
        throw ParseException("UnidirectionalSequenceLSTM must have at least 2 input.");
    }

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto& subgraphPtr = m_Model->subgraphs[subgraphIndex];
    const auto nodeParams = operatorPtr->builtin_options.AsUnidirectionalSequenceLSTMOptions();
    CHECK_SUPPORTED_FUSED_ACTIVATION(nodeParams, subgraphIndex, operatorIndex);
    auto inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    auto outputTensorInfo = ToTensorInfo(outputs[0]);

    // Set the params structure for the AddUnidirectionalSequenceLstmLayer call
    // Please refer to each operand at
    // https://www.tensorflow.org/mlir/tfl_ops#tflunidirectional_sequence_lstm_tflunidirectionalsequencelstmop
    armnn::LstmInputParams params;

    if (IsOptionalOperandPresent(operatorPtr->inputs[1]))
    {
        params.m_InputToInputWeights = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[1]].get(),
                                                            inputTensorInfo).first;
    }

    params.m_InputToForgetWeights = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[2]].get(),
                                                         inputTensorInfo).first;
    params.m_InputToCellWeights = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[3]].get(),
                                                       inputTensorInfo).first;
    params.m_InputToOutputWeights = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[4]].get(),
                                                         inputTensorInfo).first;

    // Recurrent weight tensors of size {n_cell, n_output}
    if (IsOptionalOperandPresent(operatorPtr->inputs[5]))
    {
        params.m_RecurrentToInputWeights = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[5]].get(),
                                                                inputTensorInfo).first;
    }

    params.m_RecurrentToForgetWeights = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[6]].get(),
                                                             inputTensorInfo).first;
    params.m_RecurrentToCellWeights = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[7]].get(),
                                                           inputTensorInfo).first;
    params.m_RecurrentToOutputWeights = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[8]].get(),
                                                             inputTensorInfo).first;

    // Peephole weights tensors of size {n_cell}, representing a diagonal matrix.
    if (IsOptionalOperandPresent(operatorPtr->inputs[9]))
    {
        params.m_CellToInputWeights = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[9]].get(),
                                                           inputTensorInfo).first;
    }

    if (IsOptionalOperandPresent(operatorPtr->inputs[10]))
    {
        params.m_CellToForgetWeights = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[10]].get(),
                                                            inputTensorInfo).first;
    }

    if (IsOptionalOperandPresent(operatorPtr->inputs[11]))
    {
        params.m_CellToOutputWeights = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[11]].get(),
                                                            inputTensorInfo).first;
    }

    // Gates bias tensors of size {n_cell}
    if (IsOptionalOperandPresent(operatorPtr->inputs[12]))
    {
        params.m_InputGateBias = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[12]].get(),
                                                      inputTensorInfo).first;
    }

    params.m_ForgetGateBias = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[13]].get(),
                                                   inputTensorInfo).first;
    params.m_CellBias = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[14]].get(),
                                             inputTensorInfo).first;
    params.m_OutputGateBias = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[15]].get(),
                                                   inputTensorInfo).first;

    // Projection weight tensor of size {n_output, n_cell}
    if (IsOptionalOperandPresent(operatorPtr->inputs[16]))
    {
        params.m_ProjectionWeights = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[16]].get(),
                                                          inputTensorInfo).first;
    }
    // Projection bias tensor of size {n_output}
    if (IsOptionalOperandPresent(operatorPtr->inputs[17]))
    {
        params.m_ProjectionBias = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[17]].get(),
                                                       inputTensorInfo).first;
    }

    // These state tensors are defined as variable tensors, and will be modified by this op.
    armnn::TensorInfo outputStateInInfo = ToTensorInfo(subgraphPtr->tensors[operatorPtr->inputs[18]].get());
    m_ConstantsToBeCreated.push_back(operatorPtr->inputs[18]);
    armnn::TensorInfo cellStateInInfo = ToTensorInfo(subgraphPtr->tensors[operatorPtr->inputs[19]].get());
    m_ConstantsToBeCreated.push_back(operatorPtr->inputs[19]);

    // Layer norm coefficient tensors of size {n_cell}, representing a diagonal matrix.
    if (inputs.size() >= 21 && IsOptionalOperandPresent(operatorPtr->inputs[20]))
    {
        params.m_InputLayerNormWeights = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[20]].get(),
                                                              inputTensorInfo).first;
    }

    if (inputs.size() >= 22 && IsOptionalOperandPresent(operatorPtr->inputs[21]))
    {
        params.m_ForgetLayerNormWeights = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[21]].get(),
                                                               inputTensorInfo).first;
    }

    if (inputs.size() >= 23 && IsOptionalOperandPresent(operatorPtr->inputs[22]))
    {
        params.m_CellLayerNormWeights = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[22]].get(),
                                                             inputTensorInfo).first;
    }

    if (inputs.size() >= 24 && IsOptionalOperandPresent(operatorPtr->inputs[23]))
    {
        params.m_OutputLayerNormWeights = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->inputs[23]].get(),
                                                               inputTensorInfo).first;
    }

    // set the layer descriptor
    armnn::UnidirectionalSequenceLstmDescriptor desc;
    desc.m_ActivationFunc    = nodeParams->fused_activation_function;
    desc.m_ClippingThresCell = nodeParams->cell_clip;
    desc.m_ClippingThresProj = nodeParams->proj_clip;
    desc.m_CifgEnabled       = (params.m_InputToInputWeights == nullptr
                                || params.m_RecurrentToInputWeights == nullptr
                                || params.m_InputGateBias == nullptr);
    desc.m_PeepholeEnabled   = (params.m_CellToForgetWeights != nullptr || params.m_CellToOutputWeights != nullptr);
    desc.m_ProjectionEnabled = (params.m_ProjectionWeights != nullptr);
    desc.m_LayerNormEnabled  = (params.m_InputLayerNormWeights != nullptr
                                || params.m_ForgetLayerNormWeights != nullptr
                                || params.m_CellLayerNormWeights != nullptr
                                || params.m_OutputLayerNormWeights != nullptr);
    desc.m_TimeMajor         = nodeParams->time_major;

    if (operatorPtr->intermediates.size() > 3 && desc.m_LayerNormEnabled)
    {
        auto inputIntermediate = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->intermediates[0]].get(),
                                                      inputTensorInfo).first;
        auto inputIntermediateTensorInfo = inputIntermediate->GetInfo();
        desc.m_InputIntermediateScale = inputIntermediateTensorInfo.GetQuantizationScale();

        auto forgetIntermediate = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->intermediates[1]].get(),
                                                      inputTensorInfo).first;
        auto forgetIntermediateTensorInfo = forgetIntermediate->GetInfo();
        desc.m_ForgetIntermediateScale = forgetIntermediateTensorInfo.GetQuantizationScale();

        auto cellIntermediate = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->intermediates[2]].get(),
                                                      inputTensorInfo).first;
        auto cellIntermediateTensorInfo = cellIntermediate->GetInfo();
        desc.m_CellIntermediateScale = cellIntermediateTensorInfo.GetQuantizationScale();

        auto outputIntermediate = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->intermediates[3]].get(),
                                                      inputTensorInfo).first;
        auto outputIntermediateTensorInfo = outputIntermediate->GetInfo();
        desc.m_OutputIntermediateScale = outputIntermediateTensorInfo.GetQuantizationScale();
    }
    else
    {
        float defaultIntermediate = std::pow(2, -12);
        desc.m_InputIntermediateScale = defaultIntermediate;
        desc.m_ForgetIntermediateScale = defaultIntermediate;
        desc.m_CellIntermediateScale = defaultIntermediate;
        desc.m_OutputIntermediateScale = defaultIntermediate;
    }

    if (operatorPtr->intermediates.size() > 4)
    {
        auto hiddentensor = CreateConstTensorPtr(subgraphPtr->tensors[operatorPtr->intermediates[4]].get(),
                                                 inputTensorInfo).first;

        desc.m_HiddenStateScale = hiddentensor->GetInfo().GetQuantizationScale();
        desc.m_HiddenStateZeroPoint = hiddentensor->GetInfo().GetQuantizationOffset();
    }
    unsigned int batchSize  = inputTensorInfo.GetShape()[0];
    unsigned int outputSize = outputTensorInfo.GetShape()[2];
    unsigned int numUnits   = cellStateInInfo.GetShape()[1];

    armnn::DataType dataType = inputTensorInfo.GetDataType();
    float qScale = inputTensorInfo.GetQuantizationScale();
    float qOffset = inputTensorInfo.GetQuantizationOffset();

    armnn::TensorInfo scratchBufferTensorInfo({batchSize, numUnits * 3}, dataType, qScale, qOffset);
    if (!desc.m_CifgEnabled)
    {
        scratchBufferTensorInfo = armnn::TensorInfo({batchSize, numUnits * 4}, dataType, qScale, qOffset);
    }
    armnn::TensorInfo cellStateOutTensorInfo({batchSize, numUnits},
                                             cellStateInInfo.GetDataType(),
                                             cellStateInInfo.GetQuantizationScale(),
                                             cellStateInInfo.GetQuantizationOffset());
    armnn::TensorInfo outputStateOutTensorInfo({batchSize, outputSize}, dataType, qScale, qOffset);

    armnn::LstmInputParamsInfo paramsInfo;
    paramsInfo.m_InputToForgetWeights     = &(params.m_InputToForgetWeights->GetInfo());
    paramsInfo.m_InputToCellWeights       = &(params.m_InputToCellWeights->GetInfo());
    paramsInfo.m_InputToOutputWeights     = &(params.m_InputToOutputWeights->GetInfo());
    paramsInfo.m_RecurrentToForgetWeights = &(params.m_RecurrentToForgetWeights->GetInfo());
    paramsInfo.m_RecurrentToCellWeights   = &(params.m_RecurrentToCellWeights->GetInfo());
    paramsInfo.m_RecurrentToOutputWeights = &(params.m_RecurrentToOutputWeights->GetInfo());
    paramsInfo.m_ForgetGateBias           = &(params.m_ForgetGateBias->GetInfo());
    paramsInfo.m_CellBias                 = &(params.m_CellBias->GetInfo());
    paramsInfo.m_OutputGateBias           = &(params.m_OutputGateBias->GetInfo());

    if (!desc.m_CifgEnabled)
    {
        paramsInfo.m_InputToInputWeights = &(params.m_InputToInputWeights->GetInfo());
        paramsInfo.m_RecurrentToInputWeights = &(params.m_RecurrentToInputWeights->GetInfo());
        if (params.m_CellToInputWeights != nullptr)
        {
            paramsInfo.m_CellToInputWeights = &(params.m_CellToInputWeights->GetInfo());
        }
        paramsInfo.m_InputGateBias = &(params.m_InputGateBias->GetInfo());
    }

    if (desc.m_ProjectionEnabled)
    {
        paramsInfo.m_ProjectionWeights = &(params.m_ProjectionWeights->GetInfo());
        if (params.m_ProjectionBias != nullptr)
        {
            paramsInfo.m_ProjectionBias = &(params.m_ProjectionBias->GetInfo());
        }
    }

    if (desc.m_PeepholeEnabled)
    {
        paramsInfo.m_CellToForgetWeights = &(params.m_CellToForgetWeights->GetInfo());
        paramsInfo.m_CellToOutputWeights = &(params.m_CellToOutputWeights->GetInfo());
    }

    if (desc.m_LayerNormEnabled)
    {
        if(!desc.m_CifgEnabled)
        {
            paramsInfo.m_InputLayerNormWeights = &(params.m_InputLayerNormWeights->GetInfo());
        }
        paramsInfo.m_ForgetLayerNormWeights = &(params.m_ForgetLayerNormWeights->GetInfo());
        paramsInfo.m_CellLayerNormWeights = &(params.m_CellLayerNormWeights->GetInfo());
        paramsInfo.m_OutputLayerNormWeights = &(params.m_OutputLayerNormWeights->GetInfo());
    }

    auto layerName = fmt::format("UnidirectionalSequenceLSTM:{}:{}", subgraphIndex, operatorIndex);
    armnn::IConnectableLayer* layer = m_Network->AddUnidirectionalSequenceLstmLayer(desc, params);
    ARMNN_ASSERT(layer != nullptr);

    // register the input connection slots for the layer, connections are made after all layers have been created
    // only the tensors for the inputs are relevant, exclude the const tensors
    auto inputTensorIndexes = AsUnsignedVector({operatorPtr->inputs[0],
                               operatorPtr->inputs[18],
                               operatorPtr->inputs[19]});
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0],
                                                             inputTensorIndexes[1],
                                                             inputTensorIndexes[2]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));

    layer->GetOutputSlot(0).SetTensorInfo(outputStateOutTensorInfo);
    layer->GetOutputSlot(1).SetTensorInfo(cellStateOutTensorInfo);
    layer->GetOutputSlot(2).SetTensorInfo(outputTensorInfo);

    unsigned int tensorIndex = outputTensorIndexes[0];
    armnn::IOutputSlot* slot = &(layer->GetOutputSlot(2));
    RegisterProducerOfTensor(subgraphIndex, tensorIndex, slot);
}

void TfLiteParserImpl::ParseUnpack(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsUnpackOptions();

    // This unpackAxis indicates the axis to unpack
    const unsigned int unpackAxis = CHECKED_NON_NEGATIVE(options->axis);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 1);

    armnn::TensorInfo inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);

    if (unpackAxis >= inputTensorInfo.GetNumDimensions())
    {
        throw ParseException(
                fmt::format("The unpack axis: {} cannot be greater than or equal to "
                            "the number of input dimension {} {}",
                            unpackAxis,
                            inputTensorInfo.GetNumDimensions(),
                            CHECK_LOCATION().AsString()));
    }

    unsigned int unpackNum = CHECKED_NON_NEGATIVE(options->num);
    // If num is not defined, automatically infer from the length of the dimension axis.
    if(unpackNum == 0)
    {
        unpackNum = inputTensorInfo.GetShape()[unpackAxis];
    }

    // If unpack number cannot be inferred and is still zero, throw ParseException.
    if(unpackNum == 0)
    {
        throw ParseException("Number to unpack must greater than zero.");
    }

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), unpackNum);

    auto inputDimSize = inputTensorInfo.GetNumDimensions();
    std::vector<unsigned int> unpackDimSizes(inputDimSize);

    // Add current input shape to unpackDimSizes
    for (unsigned int i = 0; i < inputDimSize; ++i)
    {
        unpackDimSizes[i] = inputTensorInfo.GetShape()[i];
    }

    if (unpackDimSizes[unpackAxis] != unpackNum)
    {
        throw ParseException("Number to unpack must be the same as length of the dimension to "
                             "unpack along.");
    }

    unpackDimSizes[unpackAxis] /= unpackNum;

    SplitterDescriptor splitDesc(unpackNum, static_cast<unsigned int>(unpackDimSizes.size()));
    for (unsigned int j = 0; j < unpackNum; ++j)
    {
        // Set the size of the views.
        for (unsigned int dimIdx = 0; dimIdx < unpackDimSizes.size(); ++dimIdx)
        {
            splitDesc.SetViewSize(j, dimIdx, unpackDimSizes[dimIdx]);
        }
        splitDesc.SetViewOriginCoord(j, unpackAxis, unpackDimSizes[unpackAxis] * j);
    }

    auto layerName = fmt::format("Unpack:{}:{}", subgraphIndex, operatorIndex);
    IConnectableLayer* layer = m_Network->AddSplitterLayer(splitDesc, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    TensorShape splitOutShape = TensorShape(static_cast<unsigned int>(unpackDimSizes.size()),
                                            unpackDimSizes.data());

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    std::vector<unsigned int> reshapeDims;
    for (unsigned int axis = 0; axis < splitOutShape.GetNumDimensions(); ++axis)
    {
        if (axis != unpackAxis)
        {
            reshapeDims.push_back(splitOutShape[axis]);
        }
    }

    TensorShape reshapeOutputShape(splitOutShape.GetNumDimensions() -1, reshapeDims.data());

    // Create reshape to remove the unpacked dimension for unpack operator of each output from Splitter.
    for (unsigned int k = 0; k < layer->GetNumOutputSlots(); ++k)
    {
        armnn::TensorInfo outputTensorInfo  = ToTensorInfo(outputs[k], true);
        std::string reshapeLayerName = fmt::format("Reshape_for:{}", layer->GetName());
        armnn::ReshapeDescriptor desc;
        desc.m_TargetShape = reshapeOutputShape;
        armnn::IConnectableLayer* reshapeLayer = m_Network->AddReshapeLayer(desc, layerName.c_str());

        layer->GetOutputSlot(k).SetTensorInfo(armnn::TensorInfo(splitOutShape,
                                                                outputTensorInfo.GetDataType(),
                                                                outputTensorInfo.GetQuantizationScale(),
                                                                outputTensorInfo.GetQuantizationOffset()));
        layer->GetOutputSlot(k).Connect(reshapeLayer->GetInputSlot(0));

        reshapeLayer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

        uint32_t reshapedOutputId = CHECKED_NON_NEGATIVE(operatorPtr->outputs[k]);
        armnn::IOutputSlot* slot = &(reshapeLayer->GetOutputSlot(0));
        RegisterProducerOfTensor(subgraphIndex, reshapedOutputId, slot);
    }
}

void TfLiteParserImpl::ParseSplit(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsSplitOptions();

    const unsigned int numSplits = CHECKED_NON_NEGATIVE(options->num_splits);

    // If number of splits cannot be inferred and is zero, throw ParseException.
    if(numSplits == 0)
    {
        throw ParseException("Number to splits must greater than zero.");
    }

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 2);
    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), numSplits);

    armnn::TensorInfo inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);
    armnn::TensorInfo axisTensorInfo  = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    ARMNN_ASSERT(axisTensorInfo.GetNumElements() == 1);

    BufferRawPtr axisBufferPtr = GetBuffer(m_Model, inputs[0]->buffer);
    if (axisBufferPtr == nullptr)
    {
        throw ParseException(
                fmt::format("Operation has invalid inputs. Failed to read axis. {}",
                            CHECK_LOCATION().AsString()));
    }

    std::vector<int32_t> axisData(axisTensorInfo.GetNumElements());
    ::memcpy(axisData.data(), axisBufferPtr->data.data(), axisTensorInfo.GetNumBytes());
    int32_t axis = axisData[0];

    auto inputDimensions = static_cast<int32_t>(inputTensorInfo.GetNumDimensions());
    if (((axis < -inputDimensions) && (axis < 0)) || ((axis >= inputDimensions) && (axis > 0)))
    {
        // Square bracket denotes inclusive n while parenthesis denotes exclusive n
        // E.g. Rank 4 tensor can have axis in range [-4, 3)
        // -1 == 3, -2 == 2, -3 == 1, -4 == 0
        throw ParseException(
                fmt::format("Operation has invalid axis: {}. Axis must be in range [-n, n) {}",
                            axis,
                            CHECK_LOCATION().AsString()));
    }

    const unsigned int splitDim = armnnUtils::GetUnsignedAxis(inputTensorInfo.GetNumDimensions(), axis);

    auto inputDimSize = inputTensorInfo.GetNumDimensions();
    if (inputDimSize > MaxNumOfTensorDimensions)
    {
        throw ParseException(
            fmt::format("The number of dimensions: {} for input tensors of the split op cannot be greater than {} {}",
                        inputTensorInfo.GetNumDimensions(),
                        MaxNumOfTensorDimensions,
                        CHECK_LOCATION().AsString()));
    }

    std::vector<unsigned int> splitterDimSizes(inputDimSize);

    // Add current input shape to splitterDimSizes
    for (unsigned int i = 0; i < inputDimSize; ++i)
    {
        splitterDimSizes[i] = inputTensorInfo.GetShape()[i];
    }

    if (splitterDimSizes[splitDim] % numSplits != 0)
    {
        throw ParseException("Number of splits must evenly divide the dimension");
    }
    splitterDimSizes[splitDim] /= numSplits;

    SplitterDescriptor splitDesc(numSplits, inputDimSize);
    for (unsigned int j = 0; j < numSplits; ++j)
    {
        // Set the size of the views.
        for (unsigned int dimIdx = 0; dimIdx < splitterDimSizes.size(); ++dimIdx)
        {
            splitDesc.SetViewSize(j, dimIdx, splitterDimSizes[dimIdx]);
        }
        splitDesc.SetViewOriginCoord(j, splitDim, splitterDimSizes[splitDim] * j);
    }

    auto layerName = fmt::format("Split:{}:{}", subgraphIndex, operatorIndex);
    IConnectableLayer* layer = m_Network->AddSplitterLayer(splitDesc, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[1]});

    for (unsigned int k = 0; k < layer->GetNumOutputSlots(); ++k)
    {
        armnn::TensorInfo tensorInfo = ToTensorInfo(outputs[k], true);
        layer->GetOutputSlot(k).SetTensorInfo(tensorInfo);
    }

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, outputTensorIndexes);
}

unsigned int ComputeWrappedIndex(int idx, unsigned int numDimsIn)
{
    int numDims = armnn::numeric_cast<int>(numDimsIn);
    int v = idx < 0 ? numDims + idx : idx;
    ARMNN_ASSERT(v >= 0);
    ARMNN_ASSERT(v < numDims);

    return static_cast<unsigned int>(v);
}

void TfLiteParserImpl::ParseSplitV(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsSplitVOptions();

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 3);

    auto& inputTensor = inputs[0];
    auto& splitsTensor = inputs[1];
    auto& axisTensor = inputs[2];

    armnn::TensorInfo inputTensorInfo = ToTensorInfo(inputTensor);
    armnn::TensorInfo splitsInfo      = ToTensorInfo(splitsTensor);
    armnn::TensorInfo axisTensorInfo  = ToTensorInfo(axisTensor);
    ARMNN_ASSERT(axisTensorInfo.GetNumElements() == 1);

    // Inputs
    auto inputDimSize = inputTensorInfo.GetNumDimensions();
    if (inputDimSize > MaxNumOfTensorDimensions)
    {
        throw ParseException(
            fmt::format("The number of dimensions: {} for input tensors of the "
                        "SplitV op cannot be greater than {} {}",
                        inputTensorInfo.GetNumDimensions(),
                        MaxNumOfTensorDimensions,
                        CHECK_LOCATION().AsString()));
    }

    // Get split axis
    BufferRawPtr axisBufferPtr = GetBuffer(m_Model, axisTensor->buffer);
    if (axisBufferPtr == nullptr)
    {
        throw ParseException(
                fmt::format("Operation has invalid inputs. Failed to read axis. {}",
                            CHECK_LOCATION().AsString()));
    }

    std::vector<int> axisData(axisTensorInfo.GetNumElements());
    ::memcpy(axisData.data(), axisBufferPtr->data.data(), axisTensorInfo.GetNumBytes());
    int32_t axis = axisData[0];

    auto inputDimensions = static_cast<int32_t>(inputTensorInfo.GetNumDimensions());
    if (((axis < -inputDimensions) && (axis < 0)) || ((axis >= inputDimensions) && (axis > 0)))
    {
        // Square bracket denotes inclusive n while parenthesis denotes exclusive n
        // E.g. Rank 4 tensor can have axis in range [-4, 3)
        // -1 == 3, -2 == 2, -3 == 1, -4 == 0
        throw ParseException(
                fmt::format("Operation has invalid axis: {}. Axis must be in range [-n, n) {}",
                            axis,
                            CHECK_LOCATION().AsString()));
    }
    const unsigned int splitDim = ComputeWrappedIndex(axis, inputTensorInfo.GetNumDimensions());

    // Set split sizes
    CHECK_VALID_SIZE(splitsInfo.GetNumDimensions(), 1);
    unsigned int numSplits{0};

    if(options)
    {
        numSplits = CHECKED_NON_NEGATIVE(options->num_splits);
    }
    else
    {
        numSplits = splitsInfo.GetNumElements();
    }

    if (numSplits <=0)
    {
        throw ParseException("SplitV has invalid number of splits");
    }

    std::vector<int> splitsData(numSplits);
    BufferRawPtr splitsBufferPtr = GetBuffer(m_Model, splitsTensor->buffer);
    ::memcpy(splitsData.data(), splitsBufferPtr->data.data(), splitsInfo.GetNumBytes());

    unsigned int idx = 0;
    int numInferred{0};
    unsigned int inferIdx{0};
    int splitSum{0};
    for (auto split : splitsData)
    {
        if (split < 0)
        {
            numInferred++;
            inferIdx = idx;
        }
        else
        {
            splitSum += split;
        }
        idx++;
    }
    // Check for inferred Axis
    if (numInferred == 0)
    {
        if (splitSum != armnn::numeric_cast<int>(inputTensorInfo.GetShape()[splitDim]))
        {
            throw ParseException("SplitV split_sizes does not sum to the dimension of value along split_dim.");
        }
    }
    else if (numInferred == 1)
    {
        splitsData[inferIdx] = armnn::numeric_cast<int>(inputTensorInfo.GetShape()[splitDim]) - splitSum;
    }
    else
    {
        throw ParseException("Cannot infer split size for more than one split");
    }

    //Ouput size validation
    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), numSplits);

    // Setup Armnn descriptor
    SplitterDescriptor splitDesc(numSplits, inputDimSize);
    unsigned int accumSplit = 0;
    for (unsigned int j = 0; j < numSplits; ++j)
    {
        unsigned int splitSize = armnn::numeric_cast<unsigned int>(splitsData[j]);

        // Set the size of the views.
        for (unsigned int dimIdx = 0; dimIdx < inputTensorInfo.GetNumDimensions(); ++dimIdx)
        {
            unsigned int dimSize = inputTensorInfo.GetShape()[dimIdx];
            if (dimIdx == splitDim)
            {
                dimSize = splitSize;
            }
            splitDesc.SetViewSize(j, dimIdx, dimSize);
        }

        splitDesc.SetViewOriginCoord(j, splitDim, accumSplit);
        accumSplit += splitSize;
    }

    auto layerName = fmt::format("SplitV:{}:{}", subgraphIndex, operatorIndex);
    IConnectableLayer* layer = m_Network->AddSplitterLayer(splitDesc, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    for (unsigned int k = 0; k < layer->GetNumOutputSlots(); ++k)
    {
        armnn::TensorInfo tensorInfo = ToTensorInfo(outputs[k], true);
        layer->GetOutputSlot(k).SetTensorInfo(tensorInfo);
    }

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, outputTensorIndexes);
}

void TfLiteParserImpl::ParseArgMin(size_t subgraphIndex, size_t operatorIndex)
{
    ParseArgMinMax(subgraphIndex, operatorIndex, armnn::ArgMinMaxFunction::Min);
}

void TfLiteParserImpl::ParseArgMax(size_t subgraphIndex, size_t operatorIndex)
{
    ParseArgMinMax(subgraphIndex, operatorIndex, armnn::ArgMinMaxFunction::Max);
}

void TfLiteParserImpl::ParseArgMinMax(size_t subgraphIndex, size_t operatorIndex, ArgMinMaxFunction argMinMaxFunction)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);
    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 2);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    armnn::TensorInfo inputTensorInfo  = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    armnn::TensorInfo axisTensorInfo   = InputTensorInfo(subgraphIndex, operatorIndex, 1);
    armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);
    ARMNN_ASSERT(axisTensorInfo.GetNumElements() == 1);

    // Check if output tensor type is Signed32 or Signed64
    if (outputTensorInfo.GetDataType() != armnn::DataType::Signed32 &&
        outputTensorInfo.GetDataType() != armnn::DataType::Signed64)
    {
        throw ParseException(
                fmt::format(
                        "Output tensor data type is not supported. (Supported types: Signed32 & Signed64) {}",
                                CHECK_LOCATION().AsString()));
    }

    // Get const axis value from model and set it to descriptor.
    BufferRawPtr axisBufferPtr = GetBuffer(m_Model, inputs[1]->buffer);
    if (axisBufferPtr == nullptr)
    {
        throw ParseException(
                fmt::format("Operation has invalid inputs. Failed to read axis. {}",
                            CHECK_LOCATION().AsString()));
    }

    std::vector<int32_t> axisData(axisTensorInfo.GetNumElements());
    ::memcpy(axisData.data(), axisBufferPtr->data.data(), axisTensorInfo.GetNumBytes());
    int32_t axis = axisData.front();

    auto inputDimensions = static_cast<int32_t>(inputTensorInfo.GetNumDimensions());
    if (((axis < -inputDimensions) && (axis < 0)) || ((axis >= inputDimensions) && (axis > 0)))
    {
        // Square bracket denotes inclusive n while parenthesis denotes exclusive n
        // E.g. Rank 4 tensor can have axis in range [-4, 3)
        // -1 == 3, -2 == 2, -3 == 1, -4 == 0
        throw ParseException(
                fmt::format("Operation has invalid axis: {}. Axis must be in range [-n, n) {}",
                                    axis,
                                    CHECK_LOCATION().AsString()));
    }

    ArgMinMaxDescriptor desc;
    desc.m_Axis = axis;
    desc.m_Function = argMinMaxFunction;

    // Register a ArgMin/ArgMax layer.
    auto layerName = argMinMaxFunction == ArgMinMaxFunction::Max ? "ArgMax:{}:{}" : "ArgMin:{}:{}";
    auto layerNameFormatted = fmt::format(layerName, subgraphIndex, operatorIndex);
    IConnectableLayer *layer = m_Network->AddArgMinMaxLayer(desc, layerNameFormatted.c_str());
    ARMNN_ASSERT(layer != nullptr);
    outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    // Register input tensor to the layer.
    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    // Register output tensor to the layer.
    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, outputTensorIndexes);
}

void TfLiteParserImpl::ParseGather(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    TfLiteParserImpl::TensorRawPtrVector inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 2);
    TfLiteParserImpl::TensorRawPtrVector outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    armnn::TensorInfo inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    armnn::TensorInfo indicesTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);
    armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0]);

    armnn::GatherDescriptor gatherDescriptor;

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsGatherOptions();
    auto axis = options->axis;

    auto layerName = fmt::format("Gather:{}:{}", subgraphIndex, operatorIndex);

    auto inputDimensions = static_cast<int32_t>(inputTensorInfo.GetNumDimensions());
    auto indicesDimensions = indicesTensorInfo.GetNumDimensions();
    auto outputDimensions = outputTensorInfo.GetNumDimensions();
    if (((axis < -inputDimensions) && (axis < 0)) || ((axis >= inputDimensions) && (axis > 0)))
    {
        throw ParseException(
            fmt::format("Operation has invalid axis: {} It is out of bounds [ -{}, {} ) {}",
                        axis,
                        inputDimensions, inputDimensions,
                        CHECK_LOCATION().AsString()));
    }
    if (outputDimensions != static_cast<unsigned int>(inputDimensions) + indicesDimensions - 1)
    {
        throw ParseException(
            fmt::format("Operation has invalid output dimensions: {} Output must be an ({} + {} - 1) -D tensor {}",
                        outputDimensions,
                        inputDimensions, indicesDimensions,
                        CHECK_LOCATION().AsString()));
    }

    gatherDescriptor.m_Axis = axis;

    IConnectableLayer* layer = m_Network->AddGatherLayer(gatherDescriptor, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);
    outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0, 1});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0], inputTensorIndexes[1]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseGatherNd(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    TfLiteParserImpl::TensorRawPtrVector inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 2);
    TfLiteParserImpl::TensorRawPtrVector outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    armnn::TensorInfo inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    armnn::TensorInfo indicesTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);

    auto layerName = fmt::format("GatherNd:{}:{}", subgraphIndex, operatorIndex);
    IConnectableLayer* layer = m_Network->AddGatherNdLayer(layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);
    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0, 1});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0], inputTensorIndexes[1]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseDepthToSpace(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    TfLiteParserImpl::TensorRawPtrVector inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 1);
    TfLiteParserImpl::TensorRawPtrVector outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    armnn::DepthToSpaceDescriptor descriptor;

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsDepthToSpaceOptions();
    auto blockSize = options->block_size;
    if (blockSize < 2)
    {
        throw ParseException(
            fmt::format("Operation has invalid block size: {} Block size should be >= 2 {}",
                        blockSize,
                        CHECK_LOCATION().AsString()));
    }
    descriptor.m_BlockSize = armnn::numeric_cast<uint32_t>(blockSize);

    auto layerName = fmt::format("DepthToSpace:{}:{}", subgraphIndex, operatorIndex);
    IConnectableLayer* layer = m_Network->AddDepthToSpaceLayer(descriptor, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);
    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseSum(size_t subgraphIndex, size_t operatorIndex)
{
    ParseReduce(subgraphIndex, operatorIndex, armnn::ReduceOperation::Sum);
}

void TfLiteParserImpl::ParseReduceProd(size_t subgraphIndex, size_t operatorIndex)
{
    ParseReduce(subgraphIndex, operatorIndex, armnn::ReduceOperation::Prod);
}

void TfLiteParserImpl::ParseReduceMax(size_t subgraphIndex, size_t operatorIndex)
{
    ParseReduce(subgraphIndex, operatorIndex, armnn::ReduceOperation::Max);
}

void TfLiteParserImpl::ParseReduceMin(size_t subgraphIndex, size_t operatorIndex)
{
    ParseReduce(subgraphIndex, operatorIndex, armnn::ReduceOperation::Min);
}

void TfLiteParserImpl::ParseReduce(size_t subgraphIndex, size_t operatorIndex, ReduceOperation reduceOperation)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsReducerOptions();

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 2);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    auto layerName = fmt::format("Reduce:{}:{}", subgraphIndex, operatorIndex);

    armnn::TensorInfo inputTensorInfo0 = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    armnn::TensorInfo inputTensorInfo1 = InputTensorInfo(subgraphIndex, operatorIndex, 1);

    ReduceDescriptor desc;
    BufferRawPtr axisBufferPtr = GetBuffer(m_Model, inputs[1]->buffer);
    // Get const axis value from model and set it to descriptor.
    if (axisBufferPtr != nullptr)
    {
        std::vector<int32_t> axisData(inputTensorInfo1.GetNumElements());
        ::memcpy(axisData.data(), axisBufferPtr->data.data(), inputTensorInfo1.GetNumBytes());

        // Convert the axis to unsigned int and remove duplicates.
        auto rank = static_cast<int32_t>(inputTensorInfo0.GetNumDimensions());
        std::set<unsigned int> uniqueAxis;
        std::transform(axisData.begin(),
                       axisData.end(),
                       std::inserter(uniqueAxis, uniqueAxis.begin()),
                       [rank](int i)->unsigned int{
                               return static_cast<uint32_t>(((i + rank) % rank)); });
        desc.m_vAxis.assign(uniqueAxis.begin(), uniqueAxis.end());
    }
    else
    {
        for (uint32_t i = 0; i < inputTensorInfo0.GetNumDimensions(); ++i)
        {
            desc.m_vAxis.push_back(i);
        }
    }

    desc.m_KeepDims        = options->keep_dims;
    desc.m_ReduceOperation = reduceOperation;

    // Register a new layer object, Sum.
    IConnectableLayer* layer = m_Network->AddReduceLayer(desc, layerName.c_str());

    armnn::TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    // Register input tensor to the layer.
    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    // Register output tensor to the layer.
    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, outputTensorIndexes);
}

void TfLiteParserImpl::ParseLocalResponseNormalization(size_t subgraphIndex, size_t operatorIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 1);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    auto layerName = fmt::format("LRN:{}:{}", subgraphIndex, operatorIndex);
    std::string layerNameFormatted = fmt::format(layerName, subgraphIndex, operatorIndex);

    armnn::TensorInfo inputTensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 0);

    const auto& operatorPtr = m_Model->subgraphs[subgraphIndex]->operators[operatorIndex];
    const auto* options = operatorPtr->builtin_options.AsLocalResponseNormalizationOptions();

    armnn::NormalizationDescriptor descriptor;
    descriptor.m_DataLayout      = armnn::DataLayout::NHWC;
    descriptor.m_NormChannelType = armnn::NormalizationAlgorithmChannel::Across;
    descriptor.m_NormMethodType  = armnn::NormalizationAlgorithmMethod::LocalBrightness;
    descriptor.m_NormSize = static_cast<uint32_t>(options->radius);
    descriptor.m_K = options->bias;
    descriptor.m_Alpha = options->alpha;
    descriptor.m_Beta = options->beta;

    // ArmNN expects normSize to be the full size of the normalization
    // window rather than the radius as in TfLite.
    descriptor.m_NormSize = 1 + (2 * descriptor.m_NormSize);

    IConnectableLayer* layer = m_Network->AddNormalizationLayer(descriptor, layerNameFormatted.c_str());
    ARMNN_ASSERT(layer != nullptr);

    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

void TfLiteParserImpl::ParseAbs(size_t subgraphIndex, size_t operatorIndex)
{
    ParseElementwiseUnary(subgraphIndex, operatorIndex, armnn::UnaryOperation::Abs);
}

void TfLiteParserImpl::ParseCeil(size_t subgraphIndex, size_t operatorIndex)
{
    ParseElementwiseUnary(subgraphIndex, operatorIndex, armnn::UnaryOperation::Ceil);
}

void TfLiteParserImpl::ParseExp(size_t subgraphIndex, size_t operatorIndex)
{
    ParseElementwiseUnary(subgraphIndex, operatorIndex, armnn::UnaryOperation::Exp);
}

void TfLiteParserImpl::ParseLog(size_t subgraphIndex, size_t operatorIndex)
{
    ParseElementwiseUnary(subgraphIndex, operatorIndex, armnn::UnaryOperation::Log);
}

void TfLiteParserImpl::ParseLogicalNot(size_t subgraphIndex, size_t operatorIndex)
{
    ParseElementwiseUnary(subgraphIndex, operatorIndex, armnn::UnaryOperation::LogicalNot);
}

void TfLiteParserImpl::ParseNeg(size_t subgraphIndex, size_t operatorIndex)
{
    ParseElementwiseUnary(subgraphIndex, operatorIndex, armnn::UnaryOperation::Neg);
}

void TfLiteParserImpl::ParseRsqrt(size_t subgraphIndex, size_t operatorIndex)
{
    ParseElementwiseUnary(subgraphIndex, operatorIndex, armnn::UnaryOperation::Rsqrt);
}

void TfLiteParserImpl::ParseSin(size_t subgraphIndex, size_t operatorIndex)
{
    ParseElementwiseUnary(subgraphIndex, operatorIndex, armnn::UnaryOperation::Sin);
}

void TfLiteParserImpl::ParseSqrt(size_t subgraphIndex, size_t operatorIndex)
{
    ParseElementwiseUnary(subgraphIndex, operatorIndex, armnn::UnaryOperation::Sqrt);
}

void TfLiteParserImpl::ParseElementwiseUnary(size_t subgraphIndex, size_t operatorIndex, UnaryOperation unaryOperation)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 1);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    std::string layerName = std::string(GetUnaryOperationAsCString(unaryOperation)) + ":{}:{}";
    std::string layerNameFormatted = fmt::format(layerName, subgraphIndex, operatorIndex);

    ElementwiseUnaryDescriptor desc;
    desc.m_Operation = unaryOperation;
    IConnectableLayer* layer = m_Network->AddElementwiseUnaryLayer(desc, layerNameFormatted.c_str());
    ARMNN_ASSERT(layer != nullptr);

    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, outputTensorIndexes);
}

void TfLiteParserImpl::ParseEqual(size_t subgraphIndex, size_t operatorIndex)
{
    ParseComparison(subgraphIndex, operatorIndex, armnn::ComparisonOperation::Equal);
}

void TfLiteParserImpl::ParseNotEqual(size_t subgraphIndex, size_t operatorIndex)
{
    ParseComparison(subgraphIndex, operatorIndex, armnn::ComparisonOperation::NotEqual);
}

void TfLiteParserImpl::ParseGreater(size_t subgraphIndex, size_t operatorIndex)
{
    ParseComparison(subgraphIndex, operatorIndex, armnn::ComparisonOperation::Greater);
}

void TfLiteParserImpl::ParseGreaterOrEqual(size_t subgraphIndex, size_t operatorIndex)
{
    ParseComparison(subgraphIndex, operatorIndex, armnn::ComparisonOperation::GreaterOrEqual);
}

void TfLiteParserImpl::ParseLess(size_t subgraphIndex, size_t operatorIndex)
{
    ParseComparison(subgraphIndex, operatorIndex, armnn::ComparisonOperation::Less);
}

void TfLiteParserImpl::ParseLessOrEqual(size_t subgraphIndex, size_t operatorIndex)
{
    ParseComparison(subgraphIndex, operatorIndex, armnn::ComparisonOperation::LessOrEqual);
}

void TfLiteParserImpl::ParseComparison(size_t subgraphIndex, size_t operatorIndex,
                                       ComparisonOperation comparisonOperation)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);

    auto inputs = GetInputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(inputs.size(), 2);

    auto outputs = GetOutputs(m_Model, subgraphIndex, operatorIndex);
    CHECK_VALID_SIZE(outputs.size(), 1);

    auto layerName = std::string(GetComparisonOperationAsCString(comparisonOperation)) + ":{}:{}";
    std::string layerNameFormatted = fmt::format(layerName, subgraphIndex, operatorIndex);

    armnn::TensorInfo inputTensorInfo  = InputTensorInfo(subgraphIndex, operatorIndex, 0);
    armnn::TensorInfo input1TensorInfo = InputTensorInfo(subgraphIndex, operatorIndex, 1);
    CheckMatchingQuantization(inputTensorInfo, input1TensorInfo, layerNameFormatted, "Input 0", "Input 1");

    ComparisonDescriptor desc;
    desc.m_Operation = comparisonOperation;
    IConnectableLayer* layer = m_Network->AddComparisonLayer(desc, layerNameFormatted.c_str());
    ARMNN_ASSERT(layer != nullptr);

    TensorInfo outputTensorInfo = OutputTensorInfoFromInputs(subgraphIndex, operatorIndex, layer, 0, {0, 1});
    layer->GetOutputSlot(0).SetTensorInfo(outputTensorInfo);

    auto inputTensorIndexes = AsUnsignedVector(GetInputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterInputSlots(subgraphIndex, operatorIndex, layer, {inputTensorIndexes[0], inputTensorIndexes[1]});

    auto outputTensorIndexes = AsUnsignedVector(GetOutputTensorIds(m_Model, subgraphIndex, operatorIndex));
    RegisterOutputSlots(subgraphIndex, operatorIndex, layer, {outputTensorIndexes[0]});
}

armnn::IConnectableLayer* TfLiteParserImpl::AddReshapeLayer(armnn::IConnectableLayer* layer,
                                                            unsigned int outputSlot,
                                                            std::string reshapeLayerName,
                                                            armnn::TensorInfo outputShape)
{
    ReshapeDescriptor desc;
    desc.m_TargetShape = outputShape.GetShape();

    IConnectableLayer* reshapeLayer =
            m_Network->AddReshapeLayer(desc, reshapeLayerName.c_str());

    auto & prevOutputSlot = layer->GetOutputSlot(outputSlot);
    prevOutputSlot.Connect(reshapeLayer->GetInputSlot(0));
    reshapeLayer->GetOutputSlot(0).SetTensorInfo(outputShape);
    return reshapeLayer;
}

armnn::IConnectableLayer* TfLiteParserImpl::AddFusedActivationLayer(armnn::IConnectableLayer* prevLayer,
                                                                    unsigned int outputSlot,
                                                                    tflite::ActivationFunctionType activationType)
{
    ActivationDescriptor activationDesc;
    std::string layerName = prevLayer->GetName();

    switch(activationType)
    {
        case tflite::ActivationFunctionType_NONE:
        {
            // this is a no-op: return previous layer
            return prevLayer;
        }
        case tflite::ActivationFunctionType_RELU:
        {
            activationDesc.m_Function = ActivationFunction::ReLu;
            layerName += ":RELU";
            break;
        }
        case tflite::ActivationFunctionType_RELU6:
        {
            activationDesc.m_Function = ActivationFunction::BoundedReLu;
            activationDesc.m_A = 6.0f;
            activationDesc.m_B = 0.0f;
            layerName += ":RELU6";
            break;
        }
        case tflite::ActivationFunctionType_TANH:
        {
            activationDesc.m_Function = ActivationFunction::TanH;
            activationDesc.m_A = 1.0f;
            activationDesc.m_B = 1.0f;
            layerName += ":TANH";
            break;
        }

        // I only put these here as a reminder what others we could support
        case tflite::ActivationFunctionType_RELU_N1_TO_1:
        case tflite::ActivationFunctionType_SIGN_BIT:
        default:
        {
            throw ParseException(
                fmt::format("TfLite parser doesn't support fused activation: "
                            "{}/{} {} ",
                            activationType,
                            tflite::EnumNameActivationFunctionType(activationType),
                            CHECK_LOCATION().AsString()));

        }
    }

    IConnectableLayer* activationLayer =
        m_Network->AddActivationLayer(activationDesc, layerName.c_str());

    auto & prevOutputSlot = prevLayer->GetOutputSlot(outputSlot);
    prevOutputSlot.Connect(activationLayer->GetInputSlot(0));
    activationLayer->GetOutputSlot(0).SetTensorInfo(prevOutputSlot.GetTensorInfo());
    return activationLayer;
}

armnn::IConnectableLayer* TfLiteParserImpl::AddFusedFloorLayer(armnn::IConnectableLayer* prevLayer,
                                                               unsigned int outputSlot)
{

    auto& prevOutputSlot = prevLayer->GetOutputSlot(outputSlot);
    DataType dataType = prevOutputSlot.GetTensorInfo().GetDataType();

    if (dataType == DataType::Signed32)
    {
        return prevLayer;
    }

    std::string layerName = prevLayer->GetName();
    IConnectableLayer* floorLayer = m_Network->AddFloorLayer(layerName.c_str());

    prevOutputSlot.Connect(floorLayer->GetInputSlot(0));
    floorLayer->GetOutputSlot(0).SetTensorInfo(prevOutputSlot.GetTensorInfo());

    return floorLayer;
}

TfLiteParserImpl::ModelPtr TfLiteParserImpl::LoadModelFromFile(const char* fileName)
{
    if (fileName == nullptr)
    {
        throw InvalidArgumentException(fmt::format("Invalid (null) file name {}",
                                       CHECK_LOCATION().AsString()));
    }
    std::error_code errorCode;
    fs::path pathToFile(fileName);
    if (!fs::exists(pathToFile, errorCode))
    {
        //fmt::format() could not be used here (format error)
        std::stringstream msg;
        msg << "Cannot find the file (" << fileName << ") errorCode: " << errorCode
            << " " << CHECK_LOCATION().AsString();

        throw FileNotFoundException(msg.str());
    }
    std::ifstream file(fileName, std::ios::binary);
    std::string fileContent((std::istreambuf_iterator<char>(file)), std::istreambuf_iterator<char>());
    return LoadModelFromBinary(reinterpret_cast<const uint8_t *>(fileContent.c_str()),
                               fileContent.size());
}

TfLiteParserImpl::ModelPtr TfLiteParserImpl::LoadModelFromBinary(const uint8_t* binaryContent, size_t len)
{
    if (binaryContent == nullptr)
     {
        throw InvalidArgumentException(fmt::format("Invalid (null) binary content {}",
                                       CHECK_LOCATION().AsString()));
     }
    flatbuffers::Verifier verifier(binaryContent, len);
    if (verifier.VerifyBuffer<tflite::Model>() == false)
    {
        throw ParseException(
            fmt::format("Buffer doesn't conform to the expected Tensorflow Lite "
                        "flatbuffers format. size:{} {}",
                        len,
                        CHECK_LOCATION().AsString()));
    }
    return tflite::UnPackModel(binaryContent);
}

TfLiteParserImpl::TensorRawPtrVector TfLiteParserImpl::GetInputs(const ModelPtr& model,
                                                                 size_t subgraphIndex,
                                                                 size_t operatorIndex)
{
    CHECK_MODEL(model, subgraphIndex, operatorIndex);

    const auto& subgraphPtr = model->subgraphs[subgraphIndex];
    const auto& operatorPtr = subgraphPtr->operators[operatorIndex];

    size_t inputCount = operatorPtr->inputs.size();
    TensorRawPtrVector result;
    for (size_t i = 0; i < inputCount; ++i)
    {
        // If the input location is -1 then assume input is turned off.
        if (operatorPtr->inputs[i] == -1)
        {
            continue;
        }
        else
        {
            uint32_t inputId = CHECKED_NON_NEGATIVE(operatorPtr->inputs[i]);
            result.push_back(subgraphPtr->tensors[inputId].get());
        }
    }
    return result;
}

TfLiteParserImpl::TensorRawPtrVector TfLiteParserImpl::GetOutputs(const ModelPtr& model,
                                                                  size_t subgraphIndex,
                                                                  size_t operatorIndex)
{
    CHECK_MODEL(model, subgraphIndex, operatorIndex);

    const auto& subgraphPtr = model->subgraphs[subgraphIndex];
    const auto& operatorPtr = subgraphPtr->operators[operatorIndex];

    size_t outputCount = operatorPtr->outputs.size();
    TensorRawPtrVector result(outputCount);
    for (size_t i = 0; i < outputCount; ++i)
    {
        uint32_t outputId = CHECKED_NON_NEGATIVE(operatorPtr->outputs[i]);
        CHECK_TENSOR(model, subgraphIndex, outputId);
        result[i] = subgraphPtr->tensors[outputId].get();
    }
    return result;
}

TfLiteParserImpl::TensorIdRawPtrVector TfLiteParserImpl::GetSubgraphInputs(const ModelPtr& model,
                                                                           size_t subgraphIndex)
{
    CHECK_SUBGRAPH(model, subgraphIndex);
    const auto& subgraphPtr = model->subgraphs[subgraphIndex];

    size_t inputCount = subgraphPtr->inputs.size();
    TensorIdRawPtrVector result(inputCount);
    for (size_t i = 0; i < inputCount; ++i)
    {
        uint32_t inputId = CHECKED_NON_NEGATIVE(subgraphPtr->inputs[i]);
        CHECK_TENSOR(model, subgraphIndex, inputId);
        result[i] = std::make_pair(inputId, subgraphPtr->tensors[inputId].get());
    }
    return result;
}

TfLiteParserImpl::TensorIdRawPtrVector TfLiteParserImpl::GetSubgraphOutputs(const ModelPtr& model,
                                                                            size_t subgraphIndex)
{
    CHECK_SUBGRAPH(model, subgraphIndex);
    const auto& subgraphPtr = model->subgraphs[subgraphIndex];

    size_t outputCount = subgraphPtr->outputs.size();
    TensorIdRawPtrVector result(outputCount);
    for (size_t i = 0; i < outputCount; ++i)
    {
        uint32_t outputId = CHECKED_NON_NEGATIVE(subgraphPtr->outputs[i]);
        result[i] = std::make_pair(outputId, subgraphPtr->tensors[outputId].get());
    }
    return result;
}

std::vector<int32_t>& TfLiteParserImpl::GetInputTensorIds(const ModelPtr& model,
                                                          size_t subgraphIndex,
                                                          size_t operatorIndex)
{
    CHECK_MODEL(model, subgraphIndex, operatorIndex);
    const auto& subgraphPtr = model->subgraphs[subgraphIndex];
    const auto& operatorPtr = subgraphPtr->operators[operatorIndex];
    return operatorPtr->inputs;
}

std::vector<int32_t>& TfLiteParserImpl::GetOutputTensorIds(const ModelPtr& model,
                                                           size_t subgraphIndex,
                                                           size_t operatorIndex)
{
    CHECK_MODEL(model, subgraphIndex, operatorIndex);
    const auto& subgraphPtr = model->subgraphs[subgraphIndex];
    const auto& operatorPtr = subgraphPtr->operators[operatorIndex];
    return operatorPtr->outputs;
}

void TfLiteParserImpl::RegisterInputSlots(size_t subgraphIndex,
                                          size_t operatorIndex,
                                          IConnectableLayer* layer,
                                          const std::vector<unsigned int>& tensorIndexes,
                                          unsigned int startingSlotIndex)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);
    ARMNN_ASSERT(layer != nullptr);

    if (tensorIndexes.size() + startingSlotIndex != layer->GetNumInputSlots())
    {
        throw ParseException(
            fmt::format("The number of tensor inputs ({}) does not match the number expected ({})"
                        " for subgraph:{} operator index:{} {}",
                        tensorIndexes.size(),
                        layer->GetNumInputSlots(),
                        subgraphIndex,
                        operatorIndex,
                        CHECK_LOCATION().AsString()));
    }

    for (unsigned int index = 0; index < tensorIndexes.size() ; ++index)
    {
        unsigned int tensorIndex = tensorIndexes[index];
        armnn::IInputSlot* slot = &(layer->GetInputSlot(startingSlotIndex + index));
        RegisterConsumerOfTensor(subgraphIndex, tensorIndex, slot);
    }
}

void TfLiteParserImpl::RegisterOutputSlots(size_t subgraphIndex,
                                           size_t operatorIndex,
                                           IConnectableLayer* layer,
                                           const std::vector<unsigned int>& tensorIndexes)
{
    CHECK_MODEL(m_Model, subgraphIndex, operatorIndex);
    ARMNN_ASSERT(layer != nullptr);
    if (tensorIndexes.size() != layer->GetNumOutputSlots())
    {
        throw ParseException(
            fmt::format("The number of tensor outputs ({}) does not match the number expected ({})"
                        " for subgraph:{} operator index:{} {}",
                        tensorIndexes.size(),
                        layer->GetNumOutputSlots(),
                        subgraphIndex,
                        operatorIndex,
                        CHECK_LOCATION().AsString()));
    }

    for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
    {
        unsigned int tensorIndex = tensorIndexes[slotIndex];
        armnn::IOutputSlot* slot = &(layer->GetOutputSlot(slotIndex));
        RegisterProducerOfTensor(subgraphIndex, tensorIndex, slot);
    }
}

void TfLiteParserImpl::SetupInputLayerTensorInfos(size_t subgraphIndex)
{
    CHECK_SUBGRAPH(m_Model, subgraphIndex);

    auto inputs = GetSubgraphInputs(m_Model, subgraphIndex);
    for (auto const& tensorIdAndPtr : inputs)
    {
        auto tensorInfo = ToTensorInfo(tensorIdAndPtr.second);
        m_TensorInfos.insert({tensorIdAndPtr.first, tensorInfo});
    }
}

void TfLiteParserImpl::SetupInputLayers(size_t subgraphIndex)
{
    CHECK_SUBGRAPH(m_Model, subgraphIndex);

    auto inputs = GetSubgraphInputs(m_Model, subgraphIndex);
    for (auto const& tensorIdAndPtr : inputs)
    {
        auto bindingId = GenerateLayerBindingId(subgraphIndex, tensorIdAndPtr.first);
        IConnectableLayer* layer =
            m_Network->AddInputLayer(bindingId, tensorIdAndPtr.second->name.c_str());

        auto tensorInfo = ToTensorInfo(tensorIdAndPtr.second);
        layer->GetOutputSlot(0).SetTensorInfo(tensorInfo);

        RegisterOutputSlots(subgraphIndex,
                            VIRTUAL_OPERATOR_ID,
                            layer,
                            { static_cast<uint32_t>(tensorIdAndPtr.first) });
    }
}

void TfLiteParserImpl::SetupOutputLayers(size_t subgraphIndex)
{
    CHECK_SUBGRAPH(m_Model, subgraphIndex);

    auto outputs = GetSubgraphOutputs(m_Model, subgraphIndex);
    for (auto const& tensorIdAndPtr : outputs)
    {
        auto bindingId = GenerateLayerBindingId(subgraphIndex, tensorIdAndPtr.first);
        IConnectableLayer* layer =
            m_Network->AddOutputLayer(bindingId, tensorIdAndPtr.second->name.c_str());

        RegisterInputSlots(subgraphIndex,
                           VIRTUAL_OPERATOR_ID,
                           layer,
                           { static_cast<uint32_t>(tensorIdAndPtr.first) });
    }
}

void TfLiteParserImpl::SetupConstantLayerTensorInfos(size_t subgraph)
{
    CHECK_SUBGRAPH(m_Model, subgraph);

    const auto & subgraphPtr = m_Model->subgraphs[subgraph];
    for (unsigned int subgraphIndex = 0; subgraphIndex < m_SubgraphConnections.size(); ++subgraphIndex)
    {
        for (unsigned int tensorIndex = 0; tensorIndex < m_SubgraphConnections[subgraphIndex].size(); ++tensorIndex)
        {
            if (m_SubgraphConnections[subgraphIndex][tensorIndex].outputSlot == nullptr &&
                m_SubgraphConnections[subgraphIndex][tensorIndex].inputSlots.size() > 0)
            {
                TensorRawPtr tensorPtr = subgraphPtr->tensors[tensorIndex].get();

                armnn::TensorInfo tensorInfo = ToTensorInfo(tensorPtr);

                m_TensorInfos.insert({tensorIndex, tensorInfo});
            }
        }
    }
}

void TfLiteParserImpl::SetupConstantLayers(size_t subgraph)
{
    CHECK_SUBGRAPH(m_Model, subgraph);

    const auto & subgraphPtr = m_Model->subgraphs[subgraph];
    for (unsigned int subgraphIndex = 0; subgraphIndex < m_SubgraphConnections.size(); ++subgraphIndex)
    {
        for (unsigned int tensorIndex = 0; tensorIndex < m_SubgraphConnections[subgraphIndex].size(); ++tensorIndex)
        {
            if (m_SubgraphConnections[subgraphIndex][tensorIndex].outputSlot == nullptr &&
                m_SubgraphConnections[subgraphIndex][tensorIndex].inputSlots.size() > 0)
            {
                TensorRawPtr tensorPtr = subgraphPtr->tensors[tensorIndex].get();

                if (IsConstTensor(tensorPtr))
                {
                    armnn::TensorInfo tensorInfo = ToTensorInfo(tensorPtr);
                    armnn::DataType dataType = tensorInfo.GetDataType();

                    if (std::find(m_ConstantsToDequantize.begin(), m_ConstantsToDequantize.end(), tensorPtr->buffer)
                        != m_ConstantsToDequantize.end())
                    {
                        dataType = DataType::Float32;
                    }
                    auto tensorAndData = CreateConstTensorNonPermuted(tensorPtr, tensorInfo, dataType);

                    std::string layerName = fmt::format("Constant:{}", tensorPtr->name);
                    IConnectableLayer *layer = m_Network->AddConstantLayer(tensorAndData.first, layerName.c_str());

                    layer->GetOutputSlot(0).SetTensorInfo(tensorAndData.first.GetInfo());
                    RegisterOutputSlots(subgraphIndex,
                                        VIRTUAL_OPERATOR_ID,
                                        layer,
                                        { tensorIndex });
                }
                else if (ShouldConstantTensorBeCreated(tensorIndex))
                {
                    armnn::TensorInfo tensorInfo = ToTensorInfo(tensorPtr);
                    armnn::DataType dataType = tensorInfo.GetDataType();

                    if (std::find(m_ConstantsToDequantize.begin(), m_ConstantsToDequantize.end(), tensorPtr->buffer)
                        != m_ConstantsToDequantize.end())
                    {
                        dataType = DataType::Float32;
                    }
                    // Make sure isConstant flag is set.
                    tensorInfo.SetConstant();
                    tensorInfo.SetDataType(dataType);

                    auto tensorAndData = ConstTensor(tensorInfo, std::vector<uint8_t>(tensorInfo.GetNumBytes()));

                    std::string layerName = fmt::format("Constant:{}", tensorPtr->name);
                    IConnectableLayer* layer = m_Network->AddConstantLayer(tensorAndData, layerName.c_str());

                    layer->GetOutputSlot(0).SetTensorInfo(tensorInfo);
                    RegisterOutputSlots(subgraphIndex,
                                        VIRTUAL_OPERATOR_ID,
                                        layer,
                                        {tensorIndex});
                }
                else
                {
                    throw ParseException(
                            fmt::format("Invalid Tensor: Tensor should be constant. {}",
                                        CHECK_LOCATION().AsString()));
                }
            }
        }
    }
}

// example usage: BufferRawPtr bufferPtr = GetBuffer(m_Model, inputs[0]->buffer);
TfLiteParserImpl::BufferRawPtr TfLiteParserImpl::GetBuffer(const ModelPtr& model, size_t bufferIndex)
{
    CHECK_BUFFER(model, bufferIndex);
    return model->buffers[bufferIndex].get();
}

template<typename T>
std::pair<armnn::ConstTensor, TfLiteParserImpl::SupportedDataStorage>
TfLiteParserImpl::CreateConstTensorAndStoreData(TfLiteParserImpl::BufferRawPtr bufferPtr,
                                            TfLiteParserImpl::TensorRawPtr tensorPtr,
                                            armnn::TensorInfo& tensorInfo,
                                            armnn::Optional<armnn::PermutationVector&> permutationVector)
{
    // Make sure isConstant flag is set.
    tensorInfo.SetConstant();

    auto constData = CreateConstTensorImpl<T>(bufferPtr,
                                              tensorPtr,
                                              tensorInfo,
                                              permutationVector);
    TfLiteParserImpl::SupportedDataStorage storage(std::move(constData.second));
    return std::make_pair(constData.first, std::move(storage));
}

bool TfLiteParserImpl::ShouldConstantTensorBeCreated(unsigned int tensorIndex)
{
    // If the TensorIndex appears in the list of ConstantsToBeCreated then return true
    return (std::find(m_ConstantsToBeCreated.begin(), m_ConstantsToBeCreated.end(), tensorIndex)
            != m_ConstantsToBeCreated.end());
}

bool TfLiteParserImpl::IsConstTensor(TensorRawPtr tensorPtr)
{
    CHECK_TENSOR_PTR(tensorPtr);
    bool isConst = true;

    auto buffer = GetBuffer(m_Model, tensorPtr->buffer);
    if (buffer->data.size() == 0)
    {
        isConst = false;
    }

    return isConst;
}

std::pair<armnn::ConstTensor, TfLiteParserImpl::SupportedDataStorage>
TfLiteParserImpl::CreateConstTensorPermuted(TensorRawPtr tensorPtr,
                                            armnn::TensorInfo& tensorInfo,
                                            armnn::Optional<armnn::PermutationVector&> permutationVector)
{
    CHECK_TENSOR_PTR(tensorPtr);
    auto bufferPtr = GetBuffer(m_Model, tensorPtr->buffer);
    CHECK_BUFFER_SIZE(bufferPtr, tensorInfo, tensorPtr->buffer);

    // Make sure isConstant flag is set.
    tensorInfo.SetConstant();

    switch (tensorInfo.GetDataType())
    {
        case armnn::DataType::Float32:
            return CreateConstTensorAndStoreData<float>(bufferPtr,
                                                        tensorPtr,
                                                        tensorInfo,
                                                        permutationVector);
        case armnn::DataType::QAsymmU8:
            return CreateConstTensorAndStoreData<uint8_t>(bufferPtr,
                                                          tensorPtr,
                                                          tensorInfo,
                                                          permutationVector);
        case armnn::DataType::QSymmS8:
            return CreateConstTensorAndStoreData<int8_t>(bufferPtr,
                                                         tensorPtr,
                                                         tensorInfo,
                                                         permutationVector);
        case armnn::DataType::QAsymmS8:
            return CreateConstTensorAndStoreData<int8_t>(bufferPtr,
                                                         tensorPtr,
                                                         tensorInfo,
                                                         permutationVector);
        case armnn::DataType::Signed32:
            return CreateConstTensorAndStoreData<int32_t>(bufferPtr,
                                                          tensorPtr,
                                                          tensorInfo,
                                                          permutationVector);
        default:
        {
            std::stringstream errString;
            errString << "Unexpected datatype when creating const tensor: "
                        << armnn::GetDataTypeName(tensorInfo.GetDataType())
                        << " shape:" << tensorInfo.GetShape()
                        << CHECK_LOCATION().AsString();
            throw ParseException(errString.str());
        }
    }
}

armnn::ConstTensor TfLiteParserImpl::CreateConstTensorNonPermuted(TensorRawPtr tensorPtr,
                                                                  armnn::TensorInfo& tensorInfo)
{
    CHECK_TENSOR_PTR(tensorPtr);
    auto bufferPtr = GetBuffer(m_Model, tensorPtr->buffer);
    CHECK_BUFFER_SIZE(bufferPtr, tensorInfo, tensorPtr->buffer);

    // Make sure isConstant flag is set.
    tensorInfo.SetConstant();

    return ConstTensor(tensorInfo, bufferPtr->data.data());
}

std::pair<armnn::ConstTensor, std::unique_ptr<float[]>>
TfLiteParserImpl::CreateConstTensorNonPermuted(TensorRawPtr tensorPtr,
                                               armnn::TensorInfo& tensorInfo,
                                               armnn::DataType inputDataType)
{
    CHECK_TENSOR_PTR(tensorPtr);
    auto bufferPtr = GetBuffer(m_Model, tensorPtr->buffer);
    CHECK_BUFFER_SIZE(bufferPtr, tensorInfo, tensorPtr->buffer);

    // Make sure isConstant flag is set.
    tensorInfo.SetConstant();

    if (inputDataType == DataType::Float32 && tensorInfo.GetDataType() != DataType::Float32)
    {
        try
        {
            TensorInfo constTensorInfo(tensorInfo.GetShape(), DataType::Float32, 0.0f, 0, true);
            std::unique_ptr<float[]> data = armnnUtils::ToFloatArray(bufferPtr->data, tensorInfo);
            return std::make_pair(ConstTensor(constTensorInfo, data.get()), std::move(data));
        }
        catch (InvalidArgumentException&)
        {
            throw ParseException(
                    fmt::format("Unsupported input/weights combination:  Input {} not supported with Weights {}",
                                GetDataTypeName(DataType::Float32),
                                GetDataTypeName(tensorInfo.GetDataType()),
                                CHECK_LOCATION().AsString()));
        }
    }
    else
    {
        return std::make_pair(ConstTensor(tensorInfo, bufferPtr->data.data()), std::unique_ptr<float[]>());
    }
}

std::pair<armnn::ConstTensor*, std::unique_ptr<float[]>>
TfLiteParserImpl::CreateConstTensorPtr(TensorRawPtr tensorPtr, armnn::TensorInfo& inputTensorInfo)
{
    CHECK_TENSOR_PTR(tensorPtr);
    armnn::TensorInfo tensorInfo = ToTensorInfo(tensorPtr);
    auto bufferPtr = GetBuffer(m_Model, tensorPtr->buffer);
    CHECK_BUFFER_SIZE(bufferPtr, tensorInfo, tensorPtr->buffer);

    // Make sure isConstant flag is set.
    tensorInfo.SetConstant();

    if (inputTensorInfo.GetDataType() == DataType::Float32 && tensorInfo.GetDataType() != DataType::Float32)
    {
        try
        {
            TensorInfo constTensorInfo(tensorInfo.GetShape(), DataType::Float32, 0.0f, 0, true);
            std::unique_ptr<float[]> data = armnnUtils::ToFloatArray(bufferPtr->data, tensorInfo);
            return std::make_pair(new ConstTensor(constTensorInfo, data.get()), std::move(data));
        }
        catch (InvalidArgumentException&)
        {
            throw ParseException(
                    fmt::format("Unsupported input/weights combination:  Input {} not supported with Weights {}",
                                GetDataTypeName(DataType::Float32),
                                GetDataTypeName(tensorInfo.GetDataType()),
                                CHECK_LOCATION().AsString()));
        }
    }
    else
    {
        return std::make_pair(new ConstTensor(tensorInfo, bufferPtr->data.data()), std::unique_ptr<float[]>());
    }
}

BindingPointInfo TfLiteParserImpl::GetNetworkInputBindingInfo(size_t subgraphId,
                                                              const std::string& name) const
{
    CHECK_SUBGRAPH(m_Model, subgraphId);
    auto inputs = GetSubgraphInputs(m_Model, subgraphId);
    for (auto const& input : inputs)
    {
        if (input.second->name == name)
        {
            auto bindingId = GenerateLayerBindingId(subgraphId, input.first);
            auto inputTensorInfo = ToTensorInfo(input.second);
            // Input tensors are always treated as constant tensors during network execution.
            inputTensorInfo.SetConstant(true);
            return std::make_pair(bindingId, inputTensorInfo);
        }
    }

    std::stringstream bindings;
    for (auto const& input : inputs)
    {
        bindings << "'" << input.second->name << "' ";
    }

    throw ParseException(
        fmt::format("No input binding found for subgraph:{} and name:{}. "
                    "Possible inputs are: [{}] {}",
                    subgraphId,
                    name,
                    bindings.str(),
                    CHECK_LOCATION().AsString()));
}

BindingPointInfo TfLiteParserImpl::GetNetworkOutputBindingInfo(size_t subgraphId,
                                                               const std::string& name) const
{
    CHECK_SUBGRAPH(m_Model, subgraphId);
    auto outputs = GetSubgraphOutputs(m_Model, subgraphId);
    for (unsigned int i = 0; i < outputs.size(); ++i)
    {
        auto const output = outputs[i];
        if (output.second->name == name)
        {
            auto bindingId = GenerateLayerBindingId(subgraphId, output.first);
            std::vector<unsigned int> shape = m_OverriddenOutputShapes.size() > 0 ?
                                                m_OverriddenOutputShapes[i] : AsUnsignedVector(output.second->shape);
            return std::make_pair(bindingId, ToTensorInfo(output.second, shape));
        }
    }

    std::stringstream bindings;
    for (auto const& output : outputs)
    {
        bindings << "'" << output.second->name << "' ";
    }

    throw ParseException(
        fmt::format("No output binding found for subgraph:{} and name:{}. "
                    "Possible outputs are: [{}] {}",
                    subgraphId,
                    name,
                    bindings.str(),
                    CHECK_LOCATION().AsString()));
}

size_t TfLiteParserImpl::GetSubgraphCount() const
{
    return m_Model->subgraphs.size();
}

std::vector<std::string> TfLiteParserImpl::GetSubgraphInputTensorNames(size_t subgraphId) const
{
    CHECK_SUBGRAPH(m_Model, subgraphId);
    auto inputs = GetSubgraphInputs(m_Model, subgraphId);
    std::vector<std::string> result;
    result.reserve(inputs.size());
    for (auto const& input : inputs)
    {
        result.push_back(input.second->name);
    }
    return result;
}

std::vector<std::string> TfLiteParserImpl::GetSubgraphOutputTensorNames(size_t subgraphId) const
{
    CHECK_SUBGRAPH(m_Model, subgraphId);
    auto outputs = GetSubgraphOutputs(m_Model, subgraphId);
    std::vector<std::string> result;
    result.reserve(outputs.size());
    for (auto const& output : outputs)
    {
        result.push_back(output.second->name);
    }
    return result;
}

const std::string TfLiteParserImpl::GetVersion()
{
    return TFLITE_PARSER_VERSION;
}

TfLiteParserImpl::SupportedDataStorage::SupportedDataStorage(std::unique_ptr<float[]>&& data)
: m_FloatData(std::move(data))
, m_Uint8Data(nullptr)
, m_Int8Data(nullptr)
, m_Int32Data(nullptr)
{
}

TfLiteParserImpl::SupportedDataStorage::SupportedDataStorage(std::unique_ptr<uint8_t[]>&& data)
: m_FloatData(nullptr)
, m_Uint8Data(std::move(data))
, m_Int8Data(nullptr)
, m_Int32Data(nullptr)
{
}

TfLiteParserImpl::SupportedDataStorage::SupportedDataStorage(std::unique_ptr<int8_t[]>&& data)
: m_FloatData(nullptr)
, m_Uint8Data(nullptr)
, m_Int8Data(std::move(data))
, m_Int32Data(nullptr)
{
}

TfLiteParserImpl::SupportedDataStorage::SupportedDataStorage(std::unique_ptr<int32_t[]>&& data)
: m_FloatData(nullptr)
, m_Uint8Data(nullptr)
, m_Int8Data(nullptr)
, m_Int32Data(std::move(data))
{
}

} // armnnTfLiteParser
