//
// Copyright © 2022 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>

// 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));
    }
    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 suppport 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;
        }
    }
}

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());
            for (unsigned int i = 0; i < tensorPtr->shape_signature.size(); ++i)
            {
                dimMask[i] = tensorPtr->shape_signature[i] == -1 ? false : 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 = 0.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)
{
    auto const& dimensions = AsUnsignedVector(tensorPtr->shape);
    return ToTensorInfo(tensorPtr, dimensions);
}

armnn::TensorInfo ToTensorInfo(TfLiteParserImpl::TensorRawPtr tensorPtr,
                               const bool outputTensor)
{
    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;
}

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()));
    }
}

} // <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_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_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;
}

void TfLiteParserImpl::ResetParser()
{
    m_Network = armnn::INetworkPtr(nullptr, nullptr);
    m_Model = nullptr;
    m_SubgraphConnections.clear();
    m_OverridenOutputShapes.clear();
    m_ConstantsToDequantize.clear();
    m_ConstantsToBeCreated.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)
        {
            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);
}

std::unique_ptr<float[]> AsFloatArray(TfLiteParserImpl::BufferRawPtr bufferPtr,
                                      const TensorInfo& tensorInfo)
{
    if (tensorInfo.GetDataType() == DataType::QAsymmS8 || tensorInfo.GetDataType() == DataType::QSymmS8 ||
        tensorInfo.GetDataType() == DataType::QAsymmU8)
    {
        std::unique_ptr<float[]> buffer(new float[tensorInfo.GetNumElements()]);

        if (tensorInfo.HasPerAxisQuantization())
        {
            unsigned int axis = tensorInfo.GetQuantizationDim().value();
            auto axisDimensionality = tensorInfo.GetShape()[axis];
            auto axisFactor = armnnUtils::GetNumElementsAfter(tensorInfo.GetShape(), axis);

            for (unsigned int i = 0; i < tensorInfo.GetNumDimensions(); ++i)
            {
                unsigned int axisIndex = (i / axisFactor) % axisDimensionality;
                buffer[i] = Dequantize<int8_t>(bufferPtr->data[i], tensorInfo.GetQuantizationScales()[axisIndex],
                                               tensorInfo.GetQuantizationOffset());
            }
        }
        else
        {
            for (unsigned int i = 0; i < tensorInfo.GetNumElements(); ++i)
            {
                buffer[i] = Dequantize<int8_t>(bufferPtr->data[i], tensorInfo.GetQuantizationScale(),
                                               tensorInfo.GetQuantizationOffset());
            }
        }
        return buffer;
    }
    throw ParseException(
            fmt::format("Unsupported input/weights combination:  Input {} not supported with Weights {}",
                        GetDataTypeName(DataType::Float32),
                        GetDataTypeName(tensorInfo.GetDataType()),
                        CHECK_LOCATION().AsString()));
}

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 correspondes 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[i], 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 = ToTensorInfo(outputs[0], true);
    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 = ToTensorInfo(inputs[0]);
    armnn::TensorInfo filterTensorInfo = ToTensorInfo(inputs[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 (IsConstTensor(inputs[1]) && inputTensorInfo.GetDataType() == DataType::Float32 &&
        (filterTensorInfo.GetDataType() == DataType::QAsymmU8 ||
            filterTensorInfo.GetDataType() == DataType::QAsymmS8))
    {
        m_ConstantsToDequantize.emplace_back(inputs[1]->buffer);
    }

    if (desc.m_BiasEnabled)
    {
        armnn::TensorInfo biasTensorInfo = ToTensorInfo(inputs[2]);

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

        if (IsConstTensor(inputs[2]) && inputTensorInfo.GetDataType() == DataType::Float32 &&
            (filterTensorInfo.GetDataType() == DataType::QAsymmU8 ||
                filterTensorInfo.GetDataType() == DataType::QAsymmS8))
        {
            m_ConstantsToDequantize.emplace_back(inputs[2]->buffer);
        }
    }

    ARMNN_ASSERT(layer != nullptr);

    armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);
    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  = ToTensorInfo(inputs[0]);
    armnn::TensorInfo filterTensorInfo = ToTensorInfo(inputs[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 = ToTensorInfo(outputs[0], true);
    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  = ToTensorInfo(inputs[0]);
    armnn::TensorInfo filterTensorInfo = ToTensorInfo(inputs[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 = ToTensorInfo(inputs[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 = ToTensorInfo(outputs[0], true);
    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 = ToTensorInfo(outputs[0], true);
    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 = ToTensorInfo(inputs[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);
    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 = ToTensorInfo(inputs[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  = ToTensorInfo(inputs[0]);
    TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);
    CheckMatchingQuantization(inputTensorInfo, outputTensorInfo, layerName, "Input 0", "Output 0");

    IConnectableLayer* layer = m_Network->AddTransposeLayer(desc, 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::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);

    if (inputs[0])
    {
        armnn::TensorInfo tensorInfo = ToTensorInfo(inputs[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;
    }
    armnn::TensorInfo inputTensorInfo  = ToTensorInfo(inputs[2]);
    armnn::TensorInfo filterTensorInfo = ToTensorInfo(inputs[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];

    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 = ToTensorInfo(inputs[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 = ToTensorInfo(outputs[0], true);
    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 = ToTensorInfo(inputs[0]);
    TensorInfo inputYTensorInfo = ToTensorInfo(inputs[1]);

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

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

    BatchMatMulDescriptor descriptor(false,
                                     false,
                                     options->adj_x,
                                     options->adj_y);
                                     // Arbitrary DataLayout

    IConnectableLayer* layer = m_Network->AddBatchMatMulLayer(descriptor, 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], 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 = ToTensorInfo(inputs[1]);
    BufferRawPtr blockShapeBufferPtr = GetBuffer(m_Model, inputs[1]->buffer);

    armnn::TensorInfo cropsTensorInfo = ToTensorInfo(inputs[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  = ToTensorInfo(inputs[0]);
    TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);
    CheckMatchingQuantization(inputTensorInfo, outputTensorInfo, layerName, "Input 0", "Output 0");

    IConnectableLayer* layer = m_Network->AddBatchToSpaceNdLayer(desc, 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::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 = ToTensorInfo(outputs[0], true);
    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  = ToTensorInfo(inputs[0]);
    TensorInfo input1TensorInfo = ToTensorInfo(inputs[1]);
    CheckMatchingQuantization(inputTensorInfo, input1TensorInfo, layerName, "Input 0", "Input 1");

    TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);
    CheckMatchingQuantization(inputTensorInfo, outputTensorInfo, layerName, "Input 0", "Output 0");

    IConnectableLayer* layer = m_Network->AddMaximumLayer(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], 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  = ToTensorInfo(inputs[0]);
    TensorInfo input1TensorInfo = ToTensorInfo(inputs[1]);
    CheckMatchingQuantization(inputTensorInfo, input1TensorInfo, layerName, "Input 0", "Input 1");

    TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);
    CheckMatchingQuantization(inputTensorInfo, outputTensorInfo, layerName, "Input 0", "Output 0");

    IConnectableLayer* layer = m_Network->AddMinimumLayer(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], 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  = ToTensorInfo(inputs[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);

    armnn::TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);
    CheckMatchingQuantization(inputTensorInfo, outputTensorInfo, layerName, "Input 0", "Output 0");

    IConnectableLayer* layer = m_Network->AddPooling2dLayer(desc, layerName.c_str());
    ARMNN_ASSERT(layer != nullptr);
    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 = ToTensorInfo(inputs[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 = ToTensorInfo(inputs[2]);
    BufferRawPtr sizeBufferPtr = GetBuffer(m_Model, inputs[2]->buffer);

    std::vector<int> signedSize(sizeTensorInfo.GetNumElements());
    ::memcpy(signedSize.data(), sizeBufferPtr->data.data(), sizeTensorInfo.GetNumBytes());
    std::vector<unsigned int> size(sizeTensorInfo.GetNumElements());
    TensorInfo inputTensorInfo = ToTensorInfo(inputs[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);

    TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);
    CheckMatchingQuantization(inputTensorInfo, outputTensorInfo, layerName, "Input 0", "Output 0");

    IConnectableLayer* const layer = m_Network->AddSliceLayer(desc, layerName.c_str());
    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 = ToTensorInfo(outputs[0], true);
    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 = ToTensorInfo(outputs[0], true);
    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 = ToTensorInfo(inputs[1]);
    BufferRawPtr blockShapeBufferPtr = GetBuffer(m_Model, inputs[1]->buffer);

    armnn::TensorInfo padListTensorInfo = ToTensorInfo(inputs[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  = ToTensorInfo(inputs[0]);
    TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);
    CheckMatchingQuantization(inputTensorInfo, outputTensorInfo, layerName, "Input 0", "Output 0");

    IConnectableLayer* layer = m_Network->AddSpaceToBatchNdLayer(desc, 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]});
}

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 = ToTensorInfo(outputs[0], true);
    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  = ToTensorInfo(inputs[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();

    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 = ToTensorInfo(inputs[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 = ToTensorInfo(inputs[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 = ToTensorInfo(inputs[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 = ToTensorInfo(outputs[0], true);
    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  = ToTensorInfo(inputs[0]);
    armnn::TensorInfo input1TensorInfo = ToTensorInfo(inputs[1]);

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

    TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);
    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  = ToTensorInfo(inputs[0]);
    armnn::TensorInfo input1TensorInfo = ToTensorInfo(inputs[1]);

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

    TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);
    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  = ToTensorInfo(inputs[0]);
    armnn::TensorInfo input1TensorInfo = ToTensorInfo(inputs[1]);

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

    TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);
    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  = ToTensorInfo(inputs[0]);
    armnn::TensorInfo input1TensorInfo = ToTensorInfo(inputs[1]);

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

    TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);
    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  = ToTensorInfo(inputs[0]);
    armnn::TensorInfo input1TensorInfo = ToTensorInfo(inputs[1]);

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

    TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);
    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);

    armnn::TensorInfo dimTensorInfo = ToTensorInfo(inputs[1]);
    BufferRawPtr bufferPtr = GetBuffer(m_Model, inputs[1]->buffer);

    armnn::MeanDescriptor desc;
    std::vector<unsigned int> axis(dimTensorInfo.GetNumElements());
    ::memcpy(axis.data(), bufferPtr->data.data(), dimTensorInfo.GetNumBytes());
    desc.m_Axis = axis;

    armnn::TensorInfo inputTensorInfo  = ToTensorInfo(inputs[0]);
    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);

    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 = ToTensorInfo(inputs[0]);
    armnn::TensorInfo padTensorInfo = ToTensorInfo(inputs[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 = ToTensorInfo(inputs[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);
    TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);

    IConnectableLayer* layer = m_Network->AddPadLayer(desc, 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::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 = ToTensorInfo(inputs[0]);

    armnn::TensorInfo padTensorInfo = ToTensorInfo(inputs[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);
    TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);

    IConnectableLayer* layer = m_Network->AddPadLayer(desc, 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::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  = ToTensorInfo(inputs[0]);
    armnn::TensorInfo alphaTensorInfo  = ToTensorInfo(inputs[1]);
    armnn::TensorInfo outputTensorInfo  = ToTensorInfo(outputs[0], true);
    CheckMatchingQuantization(inputTensorInfo, outputTensorInfo, layerName, "Input 0", "Output 0");

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

    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);
    }

    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 = ToTensorInfo(outputs[0], true);
    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 = ToTensorInfo(outputs[0], true);
    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  = ToTensorInfo(inputs[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();
                    // The parser only supports shape (batch, -1) or (-1) for non-constant shape input.
                    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()));
                    }

                    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
    const armnn::TensorShape& reshapeOutputTensorShape = reshapeOutputTensorInfo.GetShape();
    if (inputs.size() > 1 && !CheckShape(reshapeOutputTensorShape, outputs[0]->shape))
    {
        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());
    }

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

    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 = ToTensorInfo(inputs[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  = ToTensorInfo(inputs[0]);
    TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);
    CheckMatchingQuantization(inputTensorInfo, outputTensorInfo, layerName, "Input 0", "Output 0");

    IConnectableLayer* layer = m_Network->AddResizeLayer(desc, 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);
}

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);
    CHECK_VALID_SIZE(outputs.size(), 1);

    unsigned int numConcatView = static_cast<unsigned int>(inputs.size());
    uint32_t inputRank = ToTensorInfo(inputs[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 = ToTensorInfo(inputs[viewIndex]);

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

    auto layerName = fmt::format("Concatenation:{}:{}", subgraphIndex, operatorIndex);
    TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);

    IConnectableLayer* layer = m_Network->AddConcatLayer(concatDescriptor, 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});

    // 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 = ToTensorInfo(inputs[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]};
    std::vector<unsigned int> ignoreInputWhenRegister = {};
    armnn::TensorInfo inputTensorInfo = ToTensorInfo(inputs[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 (desc.m_ConstantWeights && inputTensorInfo.GetDataType() == DataType::Float32 &&
        (filterTensorInfo.GetDataType() == DataType::QAsymmU8 ||
         filterTensorInfo.GetDataType() == DataType::QAsymmS8))
    {
        m_ConstantsToDequantize.emplace_back(inputs[1]->buffer);
    }

    if (inputs.size() == 3)
    {
        desc.m_BiasEnabled = true;
        armnn::TensorInfo biasTensorInfo = ToTensorInfo(inputs[2]);

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

        if (desc.m_ConstantWeights && inputTensorInfo.GetDataType() == DataType::Float32 &&
            (biasTensorInfo.GetDataType() == DataType::QAsymmU8 ||
             biasTensorInfo.GetDataType() == DataType::QAsymmS8))
        {
            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 = ToTensorInfo(inputs[0]);
        reshapedTensorInfo.SetShape(armnn::TensorShape{ 2, reshapedDimensions.data() });

        std::string reshapeLayerName = fmt::format("Reshape_for:{}", layer->GetName());
        armnn::ReshapeDescriptor reshapeDescriptor;
        reshapeDescriptor.m_TargetShape = reshapedTensorInfo.GetShape();
        armnn::IConnectableLayer* reshapeLayer = m_Network->AddReshapeLayer(reshapeDescriptor, layerName.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 = ToTensorInfo(outputs[0], true);
    layer->GetOutputSlot(0).SetTensorInfo(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]});
}

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 = ToTensorInfo(inputs[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_OverridenOutputShapes.push_back({ 1, numDetectedBox, 4 });
    m_OverridenOutputShapes.push_back({ 1, numDetectedBox });
    m_OverridenOutputShapes.push_back({ 1, numDetectedBox });
    m_OverridenOutputShapes.push_back({ 1 });

    for (unsigned int i = 0 ; i < outputs.size() ; ++i)
    {
        armnn::TensorInfo detectionBoxOutputTensorInfo = ToTensorInfo(outputs[i], m_OverridenOutputShapes[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 = ToTensorInfo(inputs[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 = ToTensorInfo(outputs[0], true);
    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 = ToTensorInfo(inputs[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  = ToTensorInfo(inputs[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 = ToTensorInfo(inputs[1]);
    armnn::TensorInfo axisTensorInfo  = ToTensorInfo(inputs[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  = ToTensorInfo(inputs[0]);
    armnn::TensorInfo axisTensorInfo   = ToTensorInfo(inputs[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);
    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 = ToTensorInfo(inputs[0]);
    armnn::TensorInfo indicesTensorInfo = ToTensorInfo(inputs[1]);
    TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);

    armnn::GatherDescriptor gatherDescriptor;

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

    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;

    auto layerName = fmt::format("Gather:{}:{}", subgraphIndex, operatorIndex);
    IConnectableLayer* layer = m_Network->AddGatherLayer(gatherDescriptor, 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], 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 = ToTensorInfo(inputs[0]);
    armnn::TensorInfo indicesTensorInfo = ToTensorInfo(inputs[1]);
    TensorInfo outputTensorInfo = ToTensorInfo(outputs[0], true);

    auto layerName = fmt::format("GatherNd:{}:{}", subgraphIndex, operatorIndex);
    IConnectableLayer* layer = m_Network->AddGatherNdLayer(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], 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 = ToTensorInfo(outputs[0], true);
    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 = ToTensorInfo(inputs[0]);
    armnn::TensorInfo inputTensorInfo1 = ToTensorInfo(inputs[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 = ToTensorInfo(outputs[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  = ToTensorInfo(inputs[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 = ToTensorInfo(outputs[0], true);
    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::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 = ToTensorInfo(outputs[0], true);
    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  = ToTensorInfo(inputs[0]);
    armnn::TensorInfo input1TensorInfo = ToTensorInfo(inputs[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 = ToTensorInfo(outputs[0], true);
    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::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 suppport 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::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::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)
    {
        TensorInfo constTensorInfo(tensorInfo.GetShape(), DataType::Float32, 0.0f, 0, true);
        std::unique_ptr<float[]> data = AsFloatArray(bufferPtr, tensorInfo);
        return std::make_pair(ConstTensor(constTensorInfo, data.get()), std::move(data));
    }
    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)
    {
        TensorInfo constTensorInfo(tensorInfo.GetShape(), DataType::Float32, 0.0f, 0, true);
        std::unique_ptr<float[]> data = AsFloatArray(bufferPtr, tensorInfo);
        return std::make_pair(new ConstTensor(constTensorInfo, data.get()), std::move(data));
    }
    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_OverridenOutputShapes.size() > 0 ?
                                                m_OverridenOutputShapes[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
