//
// Copyright © 2017 Arm Ltd and Contributors. All rights reserved.
// SPDX-License-Identifier: MIT
//
#include "Serializer.hpp"
#include "SerializerUtils.hpp"

#include <armnn/Descriptors.hpp>
#include <armnn/LstmParams.hpp>
#include <armnn/QuantizedLstmParams.hpp>
#include <armnn/utility/IgnoreUnused.hpp>
#include <armnn/utility/NumericCast.hpp>

#include <fmt/format.h>
#include <iostream>


using namespace armnn;
namespace fb = flatbuffers;
namespace serializer = armnnSerializer;

namespace armnnSerializer
{

ISerializer::ISerializer() : pSerializerImpl(new SerializerImpl())
{
}

ISerializer::~ISerializer() = default;

ISerializer* ISerializer::CreateRaw()
{
    return new ISerializer();
}

ISerializerPtr ISerializer::Create()
{
    return ISerializerPtr(CreateRaw(), &ISerializer::Destroy);
}

void ISerializer::Destroy(ISerializer* serializer)
{
    delete serializer;
}

void ISerializer::Serialize(const armnn::INetwork& inNetwork)
{
    pSerializerImpl->Serialize(inNetwork);
}

bool ISerializer::SaveSerializedToStream(std::ostream& stream)
{
    return pSerializerImpl->SaveSerializedToStream(stream);
}

serializer::ActivationFunction GetFlatBufferActivationFunction(armnn::ActivationFunction function)
{
    switch (function)
    {
        case armnn::ActivationFunction::Sigmoid:
            return serializer::ActivationFunction::ActivationFunction_Sigmoid;
        case armnn::ActivationFunction::TanH:
            return serializer::ActivationFunction::ActivationFunction_TanH;
        case armnn::ActivationFunction::Linear:
            return serializer::ActivationFunction::ActivationFunction_Linear;
        case armnn::ActivationFunction::ReLu:
            return serializer::ActivationFunction::ActivationFunction_ReLu;
        case armnn::ActivationFunction::BoundedReLu:
            return serializer::ActivationFunction::ActivationFunction_BoundedReLu;
        case armnn::ActivationFunction::LeakyReLu:
            return serializer::ActivationFunction::ActivationFunction_LeakyReLu;
        case armnn::ActivationFunction::Abs:
            return serializer::ActivationFunction::ActivationFunction_Abs;
        case armnn::ActivationFunction::Sqrt:
            return serializer::ActivationFunction::ActivationFunction_Sqrt;
        case armnn::ActivationFunction::Square:
            return serializer::ActivationFunction::ActivationFunction_Square;
        case armnn::ActivationFunction::Elu:
            return serializer::ActivationFunction::ActivationFunction_Elu;
        case armnn::ActivationFunction::HardSwish:
            return serializer::ActivationFunction::ActivationFunction_HardSwish;
        default:
            return serializer::ActivationFunction::ActivationFunction_Sigmoid;
    }
}

serializer::ArgMinMaxFunction GetFlatBufferArgMinMaxFunction(armnn::ArgMinMaxFunction function)
{
    switch (function)
    {
        case armnn::ArgMinMaxFunction::Max:
            return serializer::ArgMinMaxFunction::ArgMinMaxFunction_Max;
        case armnn::ArgMinMaxFunction::Min:
        default:
            return serializer::ArgMinMaxFunction::ArgMinMaxFunction_Min;
    }
}

uint32_t SerializerStrategy::GetSerializedId(armnn::LayerGuid guid)
{
    if (m_guidMap.empty())
    {
        m_guidMap.insert(std::make_pair(guid, m_layerId));
    }
    else if (m_guidMap.find(guid) == m_guidMap.end())
    {
        ++m_layerId;
        m_guidMap.insert(std::make_pair(guid, m_layerId));

        return m_layerId;
    }
    return m_guidMap[guid];
}

// Build FlatBuffer for Input Layer
void SerializerStrategy::SerializeInputLayer(const armnn::IConnectableLayer* layer, LayerBindingId id, const char* name)
{
    IgnoreUnused(name);

    // Create FlatBuffer BaseLayer
    auto flatBufferInputBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Input);

    // Create FlatBuffer BindableBaseLayer
    auto flatBufferInputBindableBaseLayer = serializer::CreateBindableLayerBase(m_flatBufferBuilder,
                                                                                flatBufferInputBaseLayer,
                                                                                id);
    // Push layer binding id to outputIds.
    m_inputIds.push_back(id);

    // Create the FlatBuffer InputLayer
    auto flatBufferInputLayer = serializer::CreateInputLayer(m_flatBufferBuilder, flatBufferInputBindableBaseLayer);

    // Add the AnyLayer to the FlatBufferLayers
    CreateAnyLayer(flatBufferInputLayer.o, serializer::Layer::Layer_InputLayer);
}

// Build FlatBuffer for Output Layer
void SerializerStrategy::SerializeOutputLayer(const armnn::IConnectableLayer* layer,
                                              LayerBindingId id, const char* name)
{
    IgnoreUnused(name);

    // Create FlatBuffer BaseLayer
    auto flatBufferOutputBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Output);

    // Create FlatBuffer BindableBaseLayer
    auto flatBufferOutputBindableBaseLayer = serializer::CreateBindableLayerBase(m_flatBufferBuilder,
                                                                                 flatBufferOutputBaseLayer,
                                                                                 id);
    // Push layer binding id to outputIds.
    m_outputIds.push_back(id);

    // Create the FlatBuffer OutputLayer
    auto flatBufferOutputLayer = serializer::CreateOutputLayer(m_flatBufferBuilder, flatBufferOutputBindableBaseLayer);
    // Add the AnyLayer to the FlatBufferLayers
    CreateAnyLayer(flatBufferOutputLayer.o, serializer::Layer::Layer_OutputLayer);
}

void SerializerStrategy::SerializeAbsLayer(const armnn::IConnectableLayer* layer, const char* name)
{
    IgnoreUnused(name);
    auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Abs);
    auto flatBufferAbsLayer  = serializer::CreateAbsLayer(m_flatBufferBuilder, flatBufferBaseLayer);

    CreateAnyLayer(flatBufferAbsLayer.o, serializer::Layer::Layer_AbsLayer);
}

// Build FlatBuffer for Activation Layer
void SerializerStrategy::SerializeActivationLayer(const armnn::IConnectableLayer* layer,
                                                  const armnn::ActivationDescriptor& descriptor,
                                                  const char* name)
{
    IgnoreUnused(name);

    // Create FlatBuffer BaseLayer
    auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Activation);

    // Create the FlatBuffer ActivationDescriptor
    auto flatBufferDescriptor = CreateActivationDescriptor(m_flatBufferBuilder,
                                                           GetFlatBufferActivationFunction(descriptor.m_Function),
                                                           descriptor.m_A,
                                                           descriptor.m_B);

    // Create the FlatBuffer ActivationLayer
    auto flatBufferAdditionLayer = CreateActivationLayer(m_flatBufferBuilder,
                                                         flatBufferBaseLayer,
                                                         flatBufferDescriptor);

    // Add the AnyLayer to the FlatBufferLayers
    CreateAnyLayer(flatBufferAdditionLayer.o, serializer::Layer::Layer_ActivationLayer);
}

// Build FlatBuffer for Addition Layer
void SerializerStrategy::SerializeAdditionLayer(const armnn::IConnectableLayer* layer, const char* name)
{
    IgnoreUnused(name);

    // Create FlatBuffer BaseLayer
    auto flatBufferAdditionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Addition);

    // Create the FlatBuffer AdditionLayer
    auto flatBufferAdditionLayer = serializer::CreateAdditionLayer(m_flatBufferBuilder, flatBufferAdditionBaseLayer);

    // Add the AnyLayer to the FlatBufferLayers
    CreateAnyLayer(flatBufferAdditionLayer.o, serializer::Layer::Layer_AdditionLayer);
}

// Build FlatBuffer for ArgMinMax Layer
void SerializerStrategy::SerializeArgMinMaxLayer(const armnn::IConnectableLayer *layer,
                                                 const armnn::ArgMinMaxDescriptor& descriptor,
                                                 const char *name)
{
    IgnoreUnused(name);

    // Create FlatBuffer BaseLayer
    auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ArgMinMax);

    // Create FlatBuffer Descriptor
    auto flatBufferDescriptor = CreateArgMinMaxDescriptor(m_flatBufferBuilder,
                                                          GetFlatBufferArgMinMaxFunction(descriptor.m_Function),
                                                          descriptor.m_Axis);

    // Create FlatBuffer ArgMinMaxLayer
    auto flatBufferLayer = CreateArgMinMaxLayer(m_flatBufferBuilder,
                                                flatBufferBaseLayer,
                                                flatBufferDescriptor);

    CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ArgMinMaxLayer);
}

// Build FlatBuffer for BatchToSpaceNd Layer
void SerializerStrategy::SerializeBatchToSpaceNdLayer(const armnn::IConnectableLayer* layer,
                                                      const armnn::BatchToSpaceNdDescriptor& descriptor,
                                                      const char* name)
{
    IgnoreUnused(name);

    // Create FlatBuffer BaseLayer
    auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_BatchToSpaceNd);

    std::vector<unsigned int> crops;
    crops.reserve(descriptor.m_Crops.size() * 2);
    for (auto& crop : descriptor.m_Crops)
    {
        crops.push_back(crop.first);
        crops.push_back(crop.second);
    }

    auto flatBufferDescriptor =
        CreateBatchToSpaceNdDescriptor(m_flatBufferBuilder,
                                       m_flatBufferBuilder.CreateVector(descriptor.m_BlockShape),
                                       m_flatBufferBuilder.CreateVector(crops),
                                       GetFlatBufferDataLayout(descriptor.m_DataLayout));

    auto flatBufferLayer = serializer::CreateBatchToSpaceNdLayer(m_flatBufferBuilder,
                                                                 flatBufferBaseLayer,
                                                                 flatBufferDescriptor);

    CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_BatchToSpaceNdLayer);
}

void SerializerStrategy::SerializeBatchNormalizationLayer(
        const armnn::IConnectableLayer* layer,
        const armnn::BatchNormalizationDescriptor& batchNormDescriptor,
        const std::vector<armnn::ConstTensor>& constants,
        const char* name)
{
    IgnoreUnused(name);

    const armnn::ConstTensor& mean     = constants[0];
    const armnn::ConstTensor& variance = constants[1];
    const armnn::ConstTensor& beta     = constants[2];
    const armnn::ConstTensor& gamma    = constants[3];

    auto fbBatchNormalizationBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_BatchNormalization);
    auto fbBatchNormalizationDescriptor = serializer::CreateBatchNormalizationDescriptor(
                                                  m_flatBufferBuilder,
                                                  batchNormDescriptor.m_Eps,
                                                  GetFlatBufferDataLayout(batchNormDescriptor.m_DataLayout));

    auto fbMeanConstTensorInfo     = CreateConstTensorInfo(mean);
    auto fbVarianceConstTensorInfo = CreateConstTensorInfo(variance);
    auto fbBetaConstTensorInfo     = CreateConstTensorInfo(beta);
    auto fbGammaConstTensorInfo    = CreateConstTensorInfo(gamma);
    auto fbBatchNormalizationLayer = serializer::CreateBatchNormalizationLayer(m_flatBufferBuilder,
                                                                               fbBatchNormalizationBaseLayer,
                                                                               fbBatchNormalizationDescriptor,
                                                                               fbMeanConstTensorInfo,
                                                                               fbVarianceConstTensorInfo,
                                                                               fbBetaConstTensorInfo,
                                                                               fbGammaConstTensorInfo);

    CreateAnyLayer(fbBatchNormalizationLayer.o, serializer::Layer::Layer_BatchNormalizationLayer);
}

void SerializerStrategy::SerializeComparisonLayer(const armnn::IConnectableLayer* layer,
                                             const armnn::ComparisonDescriptor& descriptor,
                                             const char* name)
{
    IgnoreUnused(name);

    auto fbBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_Comparison);
    auto fbDescriptor = serializer::CreateComparisonDescriptor(
        m_flatBufferBuilder,
        GetFlatBufferComparisonOperation(descriptor.m_Operation));

    auto fbLayer = serializer::CreateComparisonLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
    CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_ComparisonLayer);
}

// Build FlatBuffer for Constant Layer
void SerializerStrategy::SerializeConstantLayer(const armnn::IConnectableLayer* layer,
                                                const std::vector<armnn::ConstTensor>& constants,
                                                const char* name)
{
    IgnoreUnused(name);

    armnn::ConstTensor input = constants[0];

    // Create FlatBuffer BaseLayer
    auto flatBufferConstantBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Constant);

    auto flatBufferConstTensorInfo = CreateConstTensorInfo(input);

    // Create the FlatBuffer ConstantLayer
    auto flatBufferLayer = CreateConstantLayer(m_flatBufferBuilder,
                                               flatBufferConstantBaseLayer,
                                               flatBufferConstTensorInfo);

    // Add the AnyLayer to the FlatBufferLayers
    CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ConstantLayer);
}

// Build FlatBuffer for Convolution2dLayer
void SerializerStrategy::SerializeConvolution2dLayer(const armnn::IConnectableLayer* layer,
                                                     const armnn::Convolution2dDescriptor& descriptor,
                                                     const std::vector<armnn::ConstTensor>& constants,
                                                     const char* name)
{
    IgnoreUnused(name);

    const armnn::ConstTensor weights = constants[0];

    // Create FlatBuffer BaseLayer
    auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution2d);

    auto flatBufferDescriptor = CreateConvolution2dDescriptor(m_flatBufferBuilder,
                                                              descriptor.m_PadLeft,
                                                              descriptor.m_PadRight,
                                                              descriptor.m_PadTop,
                                                              descriptor.m_PadBottom,
                                                              descriptor.m_StrideX,
                                                              descriptor.m_StrideY,
                                                              descriptor.m_DilationX,
                                                              descriptor.m_DilationY,
                                                              descriptor.m_BiasEnabled,
                                                              GetFlatBufferDataLayout(descriptor.m_DataLayout));
    auto flatBufferWeightsConstTensorInfo = CreateConstTensorInfo(weights);
    flatbuffers::Offset<serializer::ConstTensor> flatBufferBiasesConstTensorInfo;

    if (constants.size() > 1)
    {
        const armnn::ConstTensor biases = constants[1];
        flatBufferBiasesConstTensorInfo = CreateConstTensorInfo(biases);
    }

    // Create the FlatBuffer Convolution2dLayer
    auto flatBufferLayer = CreateConvolution2dLayer(m_flatBufferBuilder,
                                                    flatBufferBaseLayer,
                                                    flatBufferDescriptor,
                                                    flatBufferWeightsConstTensorInfo,
                                                    flatBufferBiasesConstTensorInfo);

    // Add the AnyLayer to the FlatBufferLayers
    CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_Convolution2dLayer);
}

void SerializerStrategy::SerializeDepthToSpaceLayer(const armnn::IConnectableLayer* layer,
                                               const armnn::DepthToSpaceDescriptor& descriptor,
                                               const char* name)
{
    IgnoreUnused(name);

    auto fbBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_DepthToSpace);
    auto fbDescriptor = CreateDepthToSpaceDescriptor(m_flatBufferBuilder,
                                                     descriptor.m_BlockSize,
                                                     GetFlatBufferDataLayout(descriptor.m_DataLayout));

    auto fbLayer = serializer::CreateDepthToSpaceLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);

    CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_DepthToSpaceLayer);
}

void SerializerStrategy::SerializeDepthwiseConvolution2dLayer(const armnn::IConnectableLayer* layer,
                                                              const armnn::DepthwiseConvolution2dDescriptor& descriptor,
                                                              const std::vector<armnn::ConstTensor>& constants,
                                                              const char* name)
{
    IgnoreUnused(name);

    const armnn::ConstTensor& weights = constants[0];

    auto fbBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_DepthwiseConvolution2d);
    auto fbDescriptor = CreateDepthwiseConvolution2dDescriptor(m_flatBufferBuilder,
                                                               descriptor.m_PadLeft,
                                                               descriptor.m_PadRight,
                                                               descriptor.m_PadTop,
                                                               descriptor.m_PadBottom,
                                                               descriptor.m_StrideX,
                                                               descriptor.m_StrideY,
                                                               descriptor.m_DilationX,
                                                               descriptor.m_DilationY,
                                                               descriptor.m_BiasEnabled,
                                                               GetFlatBufferDataLayout(descriptor.m_DataLayout));

    flatbuffers::Offset<serializer::ConstTensor> fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
    flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;

    if (constants.size() > 1)
    {
        const armnn::ConstTensor& biases = constants[1];
        fbBiasesConstTensorInfo = CreateConstTensorInfo(biases);
    }

    auto flatBufferLayer = CreateDepthwiseConvolution2dLayer(m_flatBufferBuilder,
                                                             fbBaseLayer,
                                                             fbDescriptor,
                                                             fbWeightsConstTensorInfo,
                                                             fbBiasesConstTensorInfo);

    CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DepthwiseConvolution2dLayer);
}

void SerializerStrategy::SerializeDequantizeLayer(const armnn::IConnectableLayer* layer,
                                             const char* name)
{
    IgnoreUnused(name);

    auto fbDequantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Dequantize);
    auto fbDequantizeLayer     = serializer::CreateDequantizeLayer(m_flatBufferBuilder, fbDequantizeBaseLayer);

    CreateAnyLayer(fbDequantizeLayer.o, serializer::Layer::Layer_DequantizeLayer);
}

void SerializerStrategy::SerializeDetectionPostProcessLayer(const armnn::IConnectableLayer* layer,
                                                            const armnn::DetectionPostProcessDescriptor& descriptor,
                                                            const std::vector<armnn::ConstTensor>& constants,
                                                            const char* name)
{
    IgnoreUnused(name);

    const armnn::ConstTensor& anchors = constants[0];

    auto fbBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_DetectionPostProcess);
    auto fbDescriptor = CreateDetectionPostProcessDescriptor(m_flatBufferBuilder,
                                                             descriptor.m_MaxDetections,
                                                             descriptor.m_MaxClassesPerDetection,
                                                             descriptor.m_DetectionsPerClass,
                                                             descriptor.m_NmsScoreThreshold,
                                                             descriptor.m_NmsIouThreshold,
                                                             descriptor.m_NumClasses,
                                                             descriptor.m_UseRegularNms,
                                                             descriptor.m_ScaleX,
                                                             descriptor.m_ScaleY,
                                                             descriptor.m_ScaleW,
                                                             descriptor.m_ScaleH);

    flatbuffers::Offset<serializer::ConstTensor> fbAnchorsConstTensorInfo = CreateConstTensorInfo(anchors);

    auto flatBufferLayer = CreateDetectionPostProcessLayer(m_flatBufferBuilder,
                                                           fbBaseLayer,
                                                           fbDescriptor,
                                                           fbAnchorsConstTensorInfo);

    CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_DetectionPostProcessLayer);
}

void SerializerStrategy::SerializeDivisionLayer(const armnn::IConnectableLayer* layer, const char* name)
{
    IgnoreUnused(name);

    auto fbDivisionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Division);
    auto fbDivisionLayer     = serializer::CreateDivisionLayer(m_flatBufferBuilder, fbDivisionBaseLayer);

    CreateAnyLayer(fbDivisionLayer.o, serializer::Layer::Layer_DivisionLayer);
}

void SerializerStrategy::SerializeElementwiseUnaryLayer(const armnn::IConnectableLayer* layer,
                                                   const armnn::ElementwiseUnaryDescriptor& descriptor,
                                                   const char* name)
{
    IgnoreUnused(name);

    auto fbBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_ElementwiseUnary);
    auto fbDescriptor = serializer::CreateElementwiseUnaryDescriptor(
        m_flatBufferBuilder,
        GetFlatBufferUnaryOperation(descriptor.m_Operation));

    auto fbLayer = serializer::CreateElementwiseUnaryLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
    CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_ElementwiseUnaryLayer);
}

void SerializerStrategy::SerializeEqualLayer(const armnn::IConnectableLayer* layer, const char* name)
{
    IgnoreUnused(name);

    auto fbBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_Equal);
    auto fbEqualLayer = serializer::CreateEqualLayer(m_flatBufferBuilder, fbBaseLayer);

    CreateAnyLayer(fbEqualLayer.o, serializer::Layer::Layer_EqualLayer);
}

void SerializerStrategy::SerializeFillLayer(const armnn::IConnectableLayer* layer,
                                       const armnn::FillDescriptor& fillDescriptor,
                                       const char* name)
{
    IgnoreUnused(name);

    auto fbFillBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Fill);

    auto fbDescriptor = serializer::CreateFillDescriptor(m_flatBufferBuilder, fillDescriptor.m_Value);

    auto fbFillLayer = serializer::CreateFillLayer(m_flatBufferBuilder, fbFillBaseLayer, fbDescriptor);

    CreateAnyLayer(fbFillLayer.o, serializer::Layer::Layer_FillLayer);
}

void SerializerStrategy::SerializeFloorLayer(const armnn::IConnectableLayer *layer, const char *name)
{
    IgnoreUnused(name);

    auto flatBufferFloorBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Floor);
    auto flatBufferFloorLayer = serializer::CreateFloorLayer(m_flatBufferBuilder, flatBufferFloorBaseLayer);

    CreateAnyLayer(flatBufferFloorLayer.o, serializer::Layer::Layer_FloorLayer);
}

void SerializerStrategy::SerializeGatherLayer(const armnn::IConnectableLayer* layer,
                                         const armnn::GatherDescriptor& gatherDescriptor,
                                         const char* name)
{
    IgnoreUnused(name);

    auto fbGatherDescriptor = CreateGatherDescriptor(m_flatBufferBuilder,
                                                     gatherDescriptor.m_Axis);
    auto fbGatherBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Gather);
    auto flatBufferLayer   = serializer::CreateGatherLayer(m_flatBufferBuilder, fbGatherBaseLayer, fbGatherDescriptor);

    CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_GatherLayer);
}


void SerializerStrategy::SerializeGreaterLayer(const armnn::IConnectableLayer* layer, const char* name)
{
    IgnoreUnused(name);

    auto fbGreaterBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Greater);
    auto fbGreaterLayer = serializer::CreateGreaterLayer(m_flatBufferBuilder, fbGreaterBaseLayer);

    CreateAnyLayer(fbGreaterLayer.o, serializer::Layer::Layer_GreaterLayer);
}

void SerializerStrategy::SerializeInstanceNormalizationLayer(
    const armnn::IConnectableLayer* layer,
    const armnn::InstanceNormalizationDescriptor& instanceNormalizationDescriptor,
    const char* name)
{
    IgnoreUnused(name);

    auto fbDescriptor = serializer::CreateInstanceNormalizationDescriptor(
            m_flatBufferBuilder,
            instanceNormalizationDescriptor.m_Gamma,
            instanceNormalizationDescriptor.m_Beta,
            instanceNormalizationDescriptor.m_Eps,
            GetFlatBufferDataLayout(instanceNormalizationDescriptor.m_DataLayout));

    auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_InstanceNormalization);
    auto fbLayer     = serializer::CreateInstanceNormalizationLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);

    CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_InstanceNormalizationLayer);
}

void SerializerStrategy::SerializeL2NormalizationLayer(const armnn::IConnectableLayer* layer,
                                                  const armnn::L2NormalizationDescriptor& l2NormalizationDescriptor,
                                                  const char* name)
{
    IgnoreUnused(name);

    // Create FlatBuffer BaseLayer
    auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_L2Normalization);

    // Create the FlatBuffer L2Normalization Descriptor
    auto fbDescriptor = serializer::CreateL2NormalizationDescriptor(
            m_flatBufferBuilder,
            GetFlatBufferDataLayout(l2NormalizationDescriptor.m_DataLayout),
            l2NormalizationDescriptor.m_Eps);

    // Create FlatBuffer layer
    auto fbLayer = serializer::CreateL2NormalizationLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);

    CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_L2NormalizationLayer);
}

void SerializerStrategy::SerializeLogicalBinaryLayer(const armnn::IConnectableLayer* layer,
                                                const armnn::LogicalBinaryDescriptor& descriptor,
                                                const char* name)
{
    IgnoreUnused(name);

    auto fbBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_LogicalBinary);
    auto fbDescriptor = serializer::CreateLogicalBinaryDescriptor(
        m_flatBufferBuilder,
        GetFlatBufferLogicalBinaryOperation(descriptor.m_Operation));

    auto fbLayer = serializer::CreateLogicalBinaryLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);
    CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_LogicalBinaryLayer);
}

void SerializerStrategy::SerializeLogSoftmaxLayer(const armnn::IConnectableLayer* layer,
                                             const armnn::LogSoftmaxDescriptor& logSoftmaxDescriptor,
                                             const char* name)
{
    IgnoreUnused(name);

    // Create FlatBuffer BaseLayer
    auto flatBufferLogSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_LogSoftmax);

    // Create the FlatBuffer LogSoftmaxDescriptor
    auto flatBufferLogSoftmaxDesc =
        serializer::CreateLogSoftmaxDescriptor(m_flatBufferBuilder,
                                               logSoftmaxDescriptor.m_Beta,
                                               logSoftmaxDescriptor.m_Axis);

    // Create the FlatBuffer LogSoftmaxLayer
    auto flatBufferLogSoftmaxLayer =
        serializer::CreateLogSoftmaxLayer(m_flatBufferBuilder,
                                          flatBufferLogSoftmaxBaseLayer,
                                          flatBufferLogSoftmaxDesc);

    CreateAnyLayer(flatBufferLogSoftmaxLayer.o, serializer::Layer::Layer_LogSoftmaxLayer);
}

void SerializerStrategy::SerializeLstmLayer(const armnn::IConnectableLayer* layer,
                                            const armnn::LstmDescriptor& descriptor,
                                            const std::vector<armnn::ConstTensor>& constants,
                                            const char* name)
{
    IgnoreUnused(name);

    auto fbLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Lstm);

    auto fbLstmDescriptor = serializer::CreateLstmDescriptor(
        m_flatBufferBuilder,
        descriptor.m_ActivationFunc,
        descriptor.m_ClippingThresCell,
        descriptor.m_ClippingThresProj,
        descriptor.m_CifgEnabled,
        descriptor.m_PeepholeEnabled,
        descriptor.m_ProjectionEnabled,
        descriptor.m_LayerNormEnabled);

    // Index for constants vector
    std::size_t i = 0;

    // Get mandatory/basic input parameters
    auto inputToForgetWeights     = CreateConstTensorInfo(constants[i++]); //InputToForgetWeights
    auto inputToCellWeights       = CreateConstTensorInfo(constants[i++]); //InputToCellWeights
    auto inputToOutputWeights     = CreateConstTensorInfo(constants[i++]); //InputToOutputWeights
    auto recurrentToForgetWeights = CreateConstTensorInfo(constants[i++]); //RecurrentToForgetWeights
    auto recurrentToCellWeights   = CreateConstTensorInfo(constants[i++]); //RecurrentToCellWeights
    auto recurrentToOutputWeights = CreateConstTensorInfo(constants[i++]); //RecurrentToOutputWeights
    auto forgetGateBias           = CreateConstTensorInfo(constants[i++]); //ForgetGateBias
    auto cellBias                 = CreateConstTensorInfo(constants[i++]); //CellBias
    auto outputGateBias           = CreateConstTensorInfo(constants[i++]); //OutputGateBias



    //Define optional parameters, these will be set depending on configuration in Lstm descriptor
    flatbuffers::Offset<serializer::ConstTensor> inputToInputWeights;
    flatbuffers::Offset<serializer::ConstTensor> recurrentToInputWeights;
    flatbuffers::Offset<serializer::ConstTensor> cellToInputWeights;
    flatbuffers::Offset<serializer::ConstTensor> inputGateBias;
    flatbuffers::Offset<serializer::ConstTensor> projectionWeights;
    flatbuffers::Offset<serializer::ConstTensor> projectionBias;
    flatbuffers::Offset<serializer::ConstTensor> cellToForgetWeights;
    flatbuffers::Offset<serializer::ConstTensor> cellToOutputWeights;
    flatbuffers::Offset<serializer::ConstTensor> inputLayerNormWeights;
    flatbuffers::Offset<serializer::ConstTensor> forgetLayerNormWeights;
    flatbuffers::Offset<serializer::ConstTensor> cellLayerNormWeights;
    flatbuffers::Offset<serializer::ConstTensor> outputLayerNormWeights;

    if (!descriptor.m_CifgEnabled)
    {
        inputToInputWeights = CreateConstTensorInfo(constants[i++]); //InputToInputWeights
        recurrentToInputWeights = CreateConstTensorInfo(constants[i++]); //RecurrentToInputWeights
        inputGateBias = CreateConstTensorInfo(constants[i++]); //InputGateBias
    }

    if (descriptor.m_PeepholeEnabled)
    {
        if (!descriptor.m_CifgEnabled)
        {
            cellToInputWeights = CreateConstTensorInfo(constants[i++]); //CellToInputWeights
        }
        cellToForgetWeights = CreateConstTensorInfo(constants[i++]); //CellToForgetWeights
        cellToOutputWeights = CreateConstTensorInfo(constants[i++]); //CellToOutputWeights
    }

    if (descriptor.m_ProjectionEnabled)
    {
        projectionWeights = CreateConstTensorInfo(constants[i++]); //ProjectionWeights
        projectionBias = CreateConstTensorInfo(constants[i++]); //ProjectionBias
    }

    if (descriptor.m_LayerNormEnabled)
    {
        if (!descriptor.m_CifgEnabled)
        {
            inputLayerNormWeights = CreateConstTensorInfo(constants[i++]); //InputLayerNormWeights
        }
        forgetLayerNormWeights = CreateConstTensorInfo(constants[i++]); //ForgetLayerNormWeights
        cellLayerNormWeights   = CreateConstTensorInfo(constants[i++]); //CellLayerNormWeights
        outputLayerNormWeights = CreateConstTensorInfo(constants[i++]); //OutputLayerNormWeights
    }

    auto fbLstmParams = serializer::CreateLstmInputParams(
        m_flatBufferBuilder,
        inputToForgetWeights,
        inputToCellWeights,
        inputToOutputWeights,
        recurrentToForgetWeights,
        recurrentToCellWeights,
        recurrentToOutputWeights,
        forgetGateBias,
        cellBias,
        outputGateBias,
        inputToInputWeights,
        recurrentToInputWeights,
        cellToInputWeights,
        inputGateBias,
        projectionWeights,
        projectionBias,
        cellToForgetWeights,
        cellToOutputWeights,
        inputLayerNormWeights,
        forgetLayerNormWeights,
        cellLayerNormWeights,
        outputLayerNormWeights);

    auto fbLstmLayer = serializer::CreateLstmLayer(
        m_flatBufferBuilder,
        fbLstmBaseLayer,
        fbLstmDescriptor,
        fbLstmParams);

    CreateAnyLayer(fbLstmLayer.o, serializer::Layer::Layer_LstmLayer);
}

void SerializerStrategy::SerializeMaximumLayer(const armnn::IConnectableLayer* layer, const char* name)
{
    IgnoreUnused(name);

    auto fbMaximumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Maximum);
    auto fbMaximumLayer     = serializer::CreateMaximumLayer(m_flatBufferBuilder, fbMaximumBaseLayer);

    CreateAnyLayer(fbMaximumLayer.o, serializer::Layer::Layer_MaximumLayer);
}

void SerializerStrategy::SerializeMeanLayer(const armnn::IConnectableLayer* layer,
                                       const armnn::MeanDescriptor& descriptor,
                                       const char* name)
{
    IgnoreUnused(name);

    auto fbMeanBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_Mean);
    auto fbMeanDescriptor = serializer::CreateMeanDescriptor(m_flatBufferBuilder,
                                                             m_flatBufferBuilder.CreateVector(descriptor.m_Axis),
                                                             descriptor.m_KeepDims);

    auto fbMeanLayer = serializer::CreateMeanLayer(m_flatBufferBuilder,
                                                   fbMeanBaseLayer,
                                                   fbMeanDescriptor);

    CreateAnyLayer(fbMeanLayer.o, serializer::Layer::Layer_MeanLayer);
}

void SerializerStrategy::SerializeMinimumLayer(const armnn::IConnectableLayer* layer, const char* name)
{
    IgnoreUnused(name);

    auto fbMinimumBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Minimum);
    auto fbMinimumLayer     = serializer::CreateMinimumLayer(m_flatBufferBuilder, fbMinimumBaseLayer);

    CreateAnyLayer(fbMinimumLayer.o, serializer::Layer::Layer_MinimumLayer);
}

void SerializerStrategy::SerializeMergeLayer(const armnn::IConnectableLayer* layer, const char* name)
{
    IgnoreUnused(name);

    auto fbMergeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Merge);
    auto fbMergeLayer     = serializer::CreateMergeLayer(m_flatBufferBuilder, fbMergeBaseLayer);

    CreateAnyLayer(fbMergeLayer.o, serializer::Layer::Layer_MergeLayer);
}

void SerializerStrategy::SerializeMergerLayer(const armnn::IConnectableLayer* layer,
                                         const armnn::MergerDescriptor& mergerDescriptor,
                                         const char* name)
{
    SerializeConcatLayer(layer, mergerDescriptor, name);
}

void SerializerStrategy::SerializeConcatLayer(const armnn::IConnectableLayer* layer,
                                         const armnn::ConcatDescriptor& concatDescriptor,
                                         const char* name)
{
    IgnoreUnused(name);

    auto flatBufferConcatBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Concat);

    std::vector<flatbuffers::Offset<UintVector>> views;
    for (unsigned int v = 0; v < concatDescriptor.GetNumViews(); ++v)
    {
        const uint32_t* origin = concatDescriptor.GetViewOrigin(v);
        std::vector<uint32_t> origins;
        for (unsigned int d = 0; d < concatDescriptor.GetNumDimensions(); ++d)
        {
            origins.push_back(origin[d]);
        }
        auto view = m_flatBufferBuilder.CreateVector(origins);
        auto uintVector = CreateUintVector(m_flatBufferBuilder, view);
        views.push_back(uintVector);
    }

    auto flatBufferConcatDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
                                                              concatDescriptor.GetConcatAxis(),
                                                              concatDescriptor.GetNumViews(),
                                                              concatDescriptor.GetNumDimensions(),
                                                              m_flatBufferBuilder.CreateVector(views));

    auto flatBufferLayer = CreateConcatLayer(m_flatBufferBuilder,
                                             flatBufferConcatBaseLayer,
                                             flatBufferConcatDescriptor);

    CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ConcatLayer);
}

void SerializerStrategy::SerializeMultiplicationLayer(const armnn::IConnectableLayer* layer, const char* name)
{
    IgnoreUnused(name);

    auto fbMultiplicationBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Multiplication);
    auto fbMultiplicationLayer     = serializer::CreateMultiplicationLayer(m_flatBufferBuilder,
                                                                           fbMultiplicationBaseLayer);

    CreateAnyLayer(fbMultiplicationLayer.o, serializer::Layer::Layer_MultiplicationLayer);
}

void SerializerStrategy::SerializePadLayer(const armnn::IConnectableLayer* layer,
                                      const armnn::PadDescriptor& padDescriptor,
                                      const char* name)
{
    IgnoreUnused(name);

    auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Pad);

    std::vector<unsigned int> padList;
    for (auto& p: padDescriptor.m_PadList)
    {
        padList.push_back(p.first);
        padList.push_back(p.second);
    }

    auto flatBufferPadDesc = serializer::CreatePadDescriptor(m_flatBufferBuilder,
                                                             m_flatBufferBuilder.CreateVector(padList),
                                                             padDescriptor.m_PadValue);

    auto flatBufferPadLayer = serializer::CreatePadLayer(m_flatBufferBuilder,
                                                         flatBufferBaseLayer,
                                                         flatBufferPadDesc);

    CreateAnyLayer(flatBufferPadLayer.o, serializer::Layer::Layer_PadLayer);
}

void SerializerStrategy::SerializePermuteLayer(const armnn::IConnectableLayer* layer,
                                          const armnn::PermuteDescriptor& permuteDescriptor,
                                          const char* name)
{
    IgnoreUnused(name);

    // Create FlatBuffer BaseLayer
    auto flatBufferPermuteBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Permute);

    std::vector<unsigned int> dimMappings;
    for (unsigned int i=0; i<permuteDescriptor.m_DimMappings.GetSize(); ++i)
    {
        dimMappings.push_back(permuteDescriptor.m_DimMappings[i]);
    }

    auto flatBufferPermuteDesc = serializer::CreatePermuteDescriptor(m_flatBufferBuilder,
                                                                     m_flatBufferBuilder.CreateVector(dimMappings));

    // Create the FlatBuffer PermuteLayer
    auto flatBufferPermuteLayer = serializer::CreatePermuteLayer(m_flatBufferBuilder,
                                                                 flatBufferPermuteBaseLayer,
                                                                 flatBufferPermuteDesc);

    // Add the AnyLayer to the FlatBufferLayers
    CreateAnyLayer(flatBufferPermuteLayer.o, serializer::Layer::Layer_PermuteLayer);
}

// Build FlatBuffer for Rank Layer
void SerializerStrategy::SerializeRankLayer(const armnn::IConnectableLayer* layer,
                                       const char* name)
{
    IgnoreUnused(name);
    auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Rank);
    auto flatBufferRankLayer = serializer::CreateRankLayer(m_flatBufferBuilder, flatBufferBaseLayer);

    CreateAnyLayer(flatBufferRankLayer.o, serializer::Layer::Layer_RankLayer);
}

void SerializerStrategy::SerializeReduceLayer(const armnn::IConnectableLayer* layer,
                                             const armnn::ReduceDescriptor& reduceDescriptor,
                                             const char*)
{
    auto fbReduceBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reduce);
    auto fbDescriptor = CreateReduceDescriptor(m_flatBufferBuilder,
                                               reduceDescriptor.m_KeepDims,
                                               m_flatBufferBuilder.CreateVector(reduceDescriptor.m_vAxis),
                                               GetFlatBufferReduceOperation(reduceDescriptor.m_ReduceOperation));
    auto fbReduceLayer = serializer::CreateReduceLayer(m_flatBufferBuilder,
                                                       fbReduceBaseLayer,
                                                       fbDescriptor);

    CreateAnyLayer(fbReduceLayer.o, serializer::Layer::Layer_ReduceLayer);
}

// Build FlatBuffer for Reshape Layer
void SerializerStrategy::SerializeReshapeLayer(const armnn::IConnectableLayer* layer,
                                          const armnn::ReshapeDescriptor& reshapeDescriptor,
                                          const char* name)
{
    IgnoreUnused(name);

    // Create FlatBuffer BaseLayer
    auto flatBufferReshapeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Reshape);

    std::vector<unsigned int> targetShape;
    for (unsigned int i =0; i < reshapeDescriptor.m_TargetShape.GetNumDimensions(); i++)
    {
        targetShape.push_back(reshapeDescriptor.m_TargetShape[i]);
    }

    auto flatBufferReshapeDesc = serializer::CreateReshapeDescriptor(m_flatBufferBuilder,
                                                                     m_flatBufferBuilder.CreateVector(targetShape));

    // Create the FlatBuffer ReshapeLayer
    auto flatBufferReshapeLayer = serializer::CreateReshapeLayer(m_flatBufferBuilder, flatBufferReshapeBaseLayer,
                                                                 flatBufferReshapeDesc);

    // Add the AnyLayer to the FlatBufferLayers
    CreateAnyLayer(flatBufferReshapeLayer.o, serializer::Layer::Layer_ReshapeLayer);
}

void SerializerStrategy::SerializeResizeBilinearLayer(const armnn::IConnectableLayer* layer,
                                                 const armnn::ResizeBilinearDescriptor& resizeDescriptor,
                                                 const char* name)
{
    IgnoreUnused(name);

    auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_ResizeBilinear);

    auto flatBufferDescriptor =
        CreateResizeBilinearDescriptor(m_flatBufferBuilder,
                                       resizeDescriptor.m_TargetWidth,
                                       resizeDescriptor.m_TargetHeight,
                                       GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout),
                                       resizeDescriptor.m_AlignCorners,
                                       resizeDescriptor.m_HalfPixelCenters);

    auto flatBufferLayer = serializer::CreateResizeBilinearLayer(m_flatBufferBuilder,
                                                                 flatBufferBaseLayer,
                                                                 flatBufferDescriptor);

    CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeBilinearLayer);
}

void SerializerStrategy::SerializeResizeLayer(const armnn::IConnectableLayer* layer,
                                         const armnn::ResizeDescriptor& resizeDescriptor,
                                         const char* name)
{
    IgnoreUnused(name);

    auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Resize);

    auto flatBufferDescriptor =
            CreateResizeDescriptor(m_flatBufferBuilder,
                                   resizeDescriptor.m_TargetHeight,
                                   resizeDescriptor.m_TargetWidth,
                                   GetFlatBufferResizeMethod(resizeDescriptor.m_Method),
                                   GetFlatBufferDataLayout(resizeDescriptor.m_DataLayout),
                                   resizeDescriptor.m_AlignCorners,
                                   resizeDescriptor.m_HalfPixelCenters);

    auto flatBufferLayer = serializer::CreateResizeLayer(m_flatBufferBuilder,
                                                         flatBufferBaseLayer,
                                                         flatBufferDescriptor);

    CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_ResizeLayer);
}

void SerializerStrategy::SerializeRsqrtLayer(const armnn::IConnectableLayer* layer, const char* name)
{
    IgnoreUnused(name);

    auto fbRsqrtBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Rsqrt);
    auto fbRsqrtLayer     = serializer::CreateRsqrtLayer(m_flatBufferBuilder, fbRsqrtBaseLayer);

    CreateAnyLayer(fbRsqrtLayer.o, serializer::Layer::Layer_RsqrtLayer);
}

void SerializerStrategy::SerializeSliceLayer(const armnn::IConnectableLayer* layer,
                                        const armnn::SliceDescriptor& sliceDescriptor,
                                        const char* name)
{
    IgnoreUnused(name);

    auto fbSliceBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_Slice);
    auto fbSliceDescriptor = CreateSliceDescriptor(m_flatBufferBuilder,
                                                   m_flatBufferBuilder.CreateVector(sliceDescriptor.m_Begin),
                                                   m_flatBufferBuilder.CreateVector(sliceDescriptor.m_Size));

    auto fbSliceLayer = serializer::CreateSliceLayer(m_flatBufferBuilder, fbSliceBaseLayer, fbSliceDescriptor);

    CreateAnyLayer(fbSliceLayer.o, serializer::Layer::Layer_SliceLayer);
}

// Build FlatBuffer for Softmax Layer
void SerializerStrategy::SerializeSoftmaxLayer(const armnn::IConnectableLayer* layer,
                                          const armnn::SoftmaxDescriptor& softmaxDescriptor,
                                          const char* name)
{
    IgnoreUnused(name);

    // Create FlatBuffer BaseLayer
    auto flatBufferSoftmaxBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Softmax);

    // Create the FlatBuffer SoftmaxDescriptor
    auto flatBufferSoftmaxDesc =
        serializer::CreateSoftmaxDescriptor(m_flatBufferBuilder, softmaxDescriptor.m_Beta);

    // Create the FlatBuffer SoftmaxLayer
    auto flatBufferSoftmaxLayer =
        serializer::CreateSoftmaxLayer(m_flatBufferBuilder,
                                       flatBufferSoftmaxBaseLayer,
                                       flatBufferSoftmaxDesc);

    CreateAnyLayer(flatBufferSoftmaxLayer.o, serializer::Layer::Layer_SoftmaxLayer);
}

void SerializerStrategy::SerializePooling2dLayer(const armnn::IConnectableLayer* layer,
                                            const armnn::Pooling2dDescriptor& pooling2dDescriptor,
                                            const char* name)
{
    IgnoreUnused(name);

    auto fbPooling2dBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_Pooling2d);
    auto fbPooling2dDescriptor = serializer::CreatePooling2dDescriptor(
        m_flatBufferBuilder,
        GetFlatBufferPoolingAlgorithm(pooling2dDescriptor.m_PoolType),
        pooling2dDescriptor.m_PadLeft,
        pooling2dDescriptor.m_PadRight,
        pooling2dDescriptor.m_PadTop,
        pooling2dDescriptor.m_PadBottom,
        pooling2dDescriptor.m_PoolWidth,
        pooling2dDescriptor.m_PoolHeight,
        pooling2dDescriptor.m_StrideX,
        pooling2dDescriptor.m_StrideY,
        GetFlatBufferOutputShapeRounding(pooling2dDescriptor.m_OutputShapeRounding),
        GetFlatBufferPaddingMethod(pooling2dDescriptor.m_PaddingMethod),
        GetFlatBufferDataLayout(pooling2dDescriptor.m_DataLayout));

    auto fbPooling2dLayer = serializer::CreatePooling2dLayer(m_flatBufferBuilder,
                                                             fbPooling2dBaseLayer,
                                                             fbPooling2dDescriptor);

    CreateAnyLayer(fbPooling2dLayer.o, serializer::Layer::Layer_Pooling2dLayer);
}

void SerializerStrategy::SerializePreluLayer(const armnn::IConnectableLayer* layer,
                                        const char* name)
{
    IgnoreUnused(name);

    // Create FlatBuffer BaseLayer
    auto flatBufferPreluBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Prelu);

    // Create the FlatBuffer AdditionLayer
    auto flatBufferPreluLayer = serializer::CreatePreluLayer(m_flatBufferBuilder, flatBufferPreluBaseLayer);

    // Add the AnyLayer to the FlatBufferLayers
    CreateAnyLayer(flatBufferPreluLayer.o, serializer::Layer::Layer_PreluLayer);
}

void SerializerStrategy::SerializeQuantizeLayer(const armnn::IConnectableLayer *layer, const char *name)
{
    IgnoreUnused(name);

    auto fbQuantizeBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Quantize);
    auto fbQuantizeLayer = serializer::CreateQuantizeLayer(m_flatBufferBuilder,
                                                           fbQuantizeBaseLayer);
    CreateAnyLayer(fbQuantizeLayer.o, serializer::Layer::Layer_QuantizeLayer);
}

// Build FlatBuffer for FullyConnected Layer
void SerializerStrategy::SerializeFullyConnectedLayer(const armnn::IConnectableLayer* layer,
                                                      const armnn::FullyConnectedDescriptor& fullyConnectedDescriptor,
                                                      const std::vector<armnn::ConstTensor>& constants,
                                                      const char* name)
{
    IgnoreUnused(name);

    const armnn::ConstTensor& weights = constants.at(0);

    // Create FlatBuffer BaseLayer
    auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_FullyConnected);

    // Create FlatBuffer FullyConnectedDescriptor
    auto flatBufferDescriptor =
        serializer::CreateFullyConnectedDescriptor(m_flatBufferBuilder,
                                                   fullyConnectedDescriptor.m_BiasEnabled,
                                                   fullyConnectedDescriptor.m_TransposeWeightMatrix);

    // Create FlatBuffer weights data
    auto flatBufferWeights = CreateConstTensorInfo(weights);

    // Create FlatBuffer bias data
    flatbuffers::Offset<serializer::ConstTensor> flatBufferBiases;
    if (fullyConnectedDescriptor.m_BiasEnabled)
    {
        armnn::ConstTensor biases = constants.at(1);
        flatBufferBiases = CreateConstTensorInfo(biases);
    }

    // Create FlatBuffer FullyConnectedLayer
    auto flatBufferLayer = serializer::CreateFullyConnectedLayer(m_flatBufferBuilder,
                                                                 flatBufferBaseLayer,
                                                                 flatBufferDescriptor,
                                                                 flatBufferWeights,
                                                                 flatBufferBiases);

    // Add created FullyConnectedLayer to the FlatBufferLayers
    CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_FullyConnectedLayer);
}

// Build FlatBuffer for SpaceToBatchNd Layer
void SerializerStrategy::SerializeSpaceToBatchNdLayer(const armnn::IConnectableLayer* layer,
                                                 const armnn::SpaceToBatchNdDescriptor& spaceToBatchNdDescriptor,
                                                 const char* name)
{
    IgnoreUnused(name);

    // Create FlatBuffer BaseLayer
    auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToBatchNd);

    std::vector<unsigned int> padList;
    padList.reserve(spaceToBatchNdDescriptor.m_PadList.size()*2);
    for (auto& pad : spaceToBatchNdDescriptor.m_PadList)
    {
        padList.push_back(pad.first);
        padList.push_back(pad.second);
    }

    auto flatBufferDescriptor =
        CreateSpaceToBatchNdDescriptor(m_flatBufferBuilder,
                                       m_flatBufferBuilder.CreateVector(spaceToBatchNdDescriptor.m_BlockShape),
                                       m_flatBufferBuilder.CreateVector(padList),
                                       GetFlatBufferDataLayout(spaceToBatchNdDescriptor.m_DataLayout));

    auto flatBufferLayer = serializer::CreateSpaceToBatchNdLayer(m_flatBufferBuilder,
                                                                 flatBufferBaseLayer,
                                                                 flatBufferDescriptor);

    CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToBatchNdLayer);
}

// Build FlatBuffer for SpaceToDepthLayer
void SerializerStrategy::SerializeSpaceToDepthLayer(const armnn::IConnectableLayer* layer,
                                               const armnn::SpaceToDepthDescriptor& spaceToDepthDescriptor,
                                               const char* name)
{
    IgnoreUnused(name);

    auto flatBufferBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_SpaceToDepth);
    auto flatBufferDescriptor =
        CreateSpaceToDepthDescriptor(m_flatBufferBuilder,
                                     spaceToDepthDescriptor.m_BlockSize,
                                     GetFlatBufferDataLayout(spaceToDepthDescriptor.m_DataLayout));

    auto flatBufferLayer = serializer::CreateSpaceToDepthLayer(m_flatBufferBuilder,
                                                               flatBufferBaseLayer,
                                                               flatBufferDescriptor);

    CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_SpaceToDepthLayer);
}

// Build FlatBuffer for Splitter Layer
void SerializerStrategy::SerializeSplitterLayer(const armnn::IConnectableLayer* layer,
                                           const armnn::ViewsDescriptor& viewsDescriptor,
                                           const char* name)
{
    IgnoreUnused(name);

    // Create FlatBuffer ViewOrigins
    std::vector<flatbuffers::Offset<UintVector>> flatBufferViewOrigins;
    flatBufferViewOrigins.reserve(viewsDescriptor.GetNumViews());

    for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
    {
        std::vector<uint32_t> viewOrigin;
        viewOrigin.reserve(viewsDescriptor.GetNumDimensions());

        // Copy vector
        for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
        {
            viewOrigin.push_back(viewsDescriptor.GetViewOrigin(vIdx)[dIdx]);
        }

        flatBufferViewOrigins.push_back(CreateUintVector(m_flatBufferBuilder,
                                                         m_flatBufferBuilder.CreateVector(viewOrigin)));
    }

    // Create FlatBuffer OriginsDescriptor
    auto flatBufferOriginDescriptor = CreateOriginsDescriptor(m_flatBufferBuilder,
                                                              viewsDescriptor.GetOrigins().GetConcatAxis(),
                                                              viewsDescriptor.GetOrigins().GetNumViews(),
                                                              viewsDescriptor.GetOrigins().GetNumDimensions(),
                                                              m_flatBufferBuilder.CreateVector(flatBufferViewOrigins));

    // Create FlatBuffer ViewOrigins
    std::vector<flatbuffers::Offset<UintVector>> flatBufferViewSizes;
    flatBufferViewSizes.reserve(viewsDescriptor.GetNumViews());

    for(unsigned int vIdx = 0; vIdx < viewsDescriptor.GetNumViews(); ++vIdx)
    {
        std::vector<uint32_t> viewSize;
        viewSize.reserve(viewsDescriptor.GetNumDimensions());

        // Copy vector
        for(unsigned int dIdx = 0; dIdx < viewsDescriptor.GetNumDimensions(); ++dIdx)
        {
            viewSize.push_back(viewsDescriptor.GetViewSizes(vIdx)[dIdx]);
        }

        flatBufferViewSizes.push_back(CreateUintVector(m_flatBufferBuilder,
                                                       m_flatBufferBuilder.CreateVector(viewSize)));
    }

    // Create FlatBuffer ViewsDescriptor
    auto flatBufferViewsDescriptor = CreateViewsDescriptor(m_flatBufferBuilder,
                                                           flatBufferOriginDescriptor,
                                                           m_flatBufferBuilder.CreateVector(flatBufferViewSizes));

    // Create FlatBuffer BaseLayer
    auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Splitter);

    auto flatBufferSplitterLayer = serializer::CreateSplitterLayer(m_flatBufferBuilder,
                                                                   flatBufferBaseLayer,
                                                                   flatBufferViewsDescriptor);

    CreateAnyLayer(flatBufferSplitterLayer.o, serializer::Layer::Layer_SplitterLayer);
}

void SerializerStrategy::SerializeNormalizationLayer(const armnn::IConnectableLayer* layer,
                                                const armnn::NormalizationDescriptor& descriptor,
                                                const char* name)
{
    IgnoreUnused(name);

    auto fbNormalizationBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_Normalization);

    auto fbNormalizationDescriptor = serializer::CreateNormalizationDescriptor(
        m_flatBufferBuilder,
        GetFlatBufferNormalizationAlgorithmChannel(descriptor.m_NormChannelType),
        GetFlatBufferNormalizationAlgorithmMethod(descriptor.m_NormMethodType),
        descriptor.m_NormSize,
        descriptor.m_Alpha,
        descriptor.m_Beta,
        descriptor.m_K,
        GetFlatBufferDataLayout(descriptor.m_DataLayout));

    auto flatBufferLayer = serializer::CreateNormalizationLayer(m_flatBufferBuilder,
                                                                fbNormalizationBaseLayer,
                                                                fbNormalizationDescriptor);

    CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_NormalizationLayer);
}

void SerializerStrategy::SerializeStackLayer(const armnn::IConnectableLayer* layer,
                                        const armnn::StackDescriptor& stackDescriptor,
                                        const char* name)
{
    IgnoreUnused(name);

    auto stackBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Stack);

    std::vector<unsigned int> inputShape;
    for (unsigned int i =0; i < stackDescriptor.m_InputShape.GetNumDimensions(); i++)
    {
        inputShape.push_back(stackDescriptor.m_InputShape[i]);
    }

    auto flatBufferStackDescriptor = CreateStackDescriptor(m_flatBufferBuilder,
                                                           stackDescriptor.m_Axis,
                                                           stackDescriptor.m_NumInputs,
                                                           m_flatBufferBuilder.CreateVector(inputShape));

    auto stackLayer = serializer::CreateStackLayer(m_flatBufferBuilder, stackBaseLayer, flatBufferStackDescriptor);
    CreateAnyLayer(stackLayer.o, serializer::Layer::Layer_StackLayer);
}

void SerializerStrategy::SerializeStandInLayer(const armnn::IConnectableLayer *layer,
                                          const armnn::StandInDescriptor& standInDescriptor,
                                          const char *name)
{
    IgnoreUnused(name);

    auto fbDescriptor = serializer::CreateStandInDescriptor(m_flatBufferBuilder,
                                                            standInDescriptor.m_NumInputs,
                                                            standInDescriptor.m_NumOutputs);

    auto fbBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StandIn);
    auto fbLayer     = serializer::CreateStandInLayer(m_flatBufferBuilder, fbBaseLayer, fbDescriptor);

    CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_StandInLayer);
}

void SerializerStrategy::SerializeStridedSliceLayer(const armnn::IConnectableLayer* layer,
                                               const armnn::StridedSliceDescriptor& stridedSliceDescriptor,
                                               const char* name)
{
    IgnoreUnused(name);

    auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_StridedSlice);

    auto flatBufferDescriptor =
        CreateStridedSliceDescriptor(m_flatBufferBuilder,
                                     m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Begin),
                                     m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_End),
                                     m_flatBufferBuilder.CreateVector(stridedSliceDescriptor.m_Stride),
                                     stridedSliceDescriptor.m_BeginMask,
                                     stridedSliceDescriptor.m_EndMask,
                                     stridedSliceDescriptor.m_ShrinkAxisMask,
                                     stridedSliceDescriptor.m_EllipsisMask,
                                     stridedSliceDescriptor.m_NewAxisMask,
                                     GetFlatBufferDataLayout(stridedSliceDescriptor.m_DataLayout));

    auto flatBufferLayer = serializer::CreateStridedSliceLayer(m_flatBufferBuilder,
                                                               flatBufferBaseLayer,
                                                               flatBufferDescriptor);

    CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_StridedSliceLayer);
}

void SerializerStrategy::SerializeSubtractionLayer(const armnn::IConnectableLayer* layer, const char* name)
{
    IgnoreUnused(name);

    auto fbSubtractionBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Subtraction);
    auto fbSubtractionLayer = serializer::CreateSubtractionLayer(m_flatBufferBuilder, fbSubtractionBaseLayer);

    CreateAnyLayer(fbSubtractionLayer.o, serializer::Layer::Layer_SubtractionLayer);
}

void SerializerStrategy::SerializeSwitchLayer(const armnn::IConnectableLayer* layer, const char* name)
{
    IgnoreUnused(name);

    auto fbSwitchBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Switch);
    auto fbSwitchLayer = serializer::CreateSwitchLayer(m_flatBufferBuilder, fbSwitchBaseLayer);

    CreateAnyLayer(fbSwitchLayer.o, serializer::Layer::Layer_SwitchLayer);
}

void SerializerStrategy::SerializeTransposeConvolution2dLayer(
    const armnn::IConnectableLayer* layer,
    const armnn::TransposeConvolution2dDescriptor& descriptor,
    const std::vector<armnn::ConstTensor>& constants,
    const char* name)
{
    IgnoreUnused(name);

    const armnn::ConstTensor& weights = constants.at(0);

    auto fbBaseLayer  = CreateLayerBase(layer, serializer::LayerType::LayerType_Convolution2d);
    auto fbDescriptor = CreateTransposeConvolution2dDescriptor(m_flatBufferBuilder,
                                                               descriptor.m_PadLeft,
                                                               descriptor.m_PadRight,
                                                               descriptor.m_PadTop,
                                                               descriptor.m_PadBottom,
                                                               descriptor.m_StrideX,
                                                               descriptor.m_StrideY,
                                                               descriptor.m_BiasEnabled,
                                                               GetFlatBufferDataLayout(descriptor.m_DataLayout));

    // weights & biases
    auto fbWeightsConstTensorInfo = CreateConstTensorInfo(weights);
    flatbuffers::Offset<serializer::ConstTensor> fbBiasesConstTensorInfo;
    if (constants.size() > 1)
    {
        const armnn::ConstTensor& biases = constants.at(1);
        fbBiasesConstTensorInfo = CreateConstTensorInfo(biases);
    }

    auto fbLayer = CreateTransposeConvolution2dLayer(m_flatBufferBuilder,
                                                     fbBaseLayer,
                                                     fbDescriptor,
                                                     fbWeightsConstTensorInfo,
                                                     fbBiasesConstTensorInfo);

    CreateAnyLayer(fbLayer.o, serializer::Layer::Layer_TransposeConvolution2dLayer);
}

void SerializerStrategy::SerializeTransposeLayer(const armnn::IConnectableLayer* layer,
                                            const armnn::TransposeDescriptor& descriptor,
                                            const char* name)
{
    IgnoreUnused(name);

    // Create FlatBuffer BaseLayer
    auto flatBufferBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_Transpose);

    std::vector<unsigned int> dimMappings;
    for (unsigned int i=0; i<descriptor.m_DimMappings.GetSize(); ++i)
    {
        dimMappings.push_back(descriptor.m_DimMappings[i]);
    }

    auto flatBufferDesc = serializer::CreateTransposeDescriptor(m_flatBufferBuilder,
                                                                m_flatBufferBuilder.CreateVector(dimMappings));

    // Create the FlatBuffer TransposeLayer
    auto flatBufferLayer = serializer::CreateTransposeLayer(m_flatBufferBuilder,
                                                            flatBufferBaseLayer,
                                                            flatBufferDesc);

    // Add the AnyLayer to the FlatBufferLayers
    CreateAnyLayer(flatBufferLayer.o, serializer::Layer::Layer_TransposeLayer);
}

void SerializerStrategy::SerializeQLstmLayer(const armnn::IConnectableLayer* layer,
                                             const armnn::QLstmDescriptor& descriptor,
                                             const std::vector<armnn::ConstTensor>& constants,
                                             const char* name)
{
    IgnoreUnused(name);

    auto fbQLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_QLstm);

    auto fbQLstmDescriptor = serializer::CreateQLstmDescriptor(
            m_flatBufferBuilder,
            descriptor.m_CifgEnabled,
            descriptor.m_PeepholeEnabled,
            descriptor.m_ProjectionEnabled,
            descriptor.m_LayerNormEnabled,
            descriptor.m_CellClip,
            descriptor.m_ProjectionClip,
            descriptor.m_InputIntermediateScale,
            descriptor.m_ForgetIntermediateScale,
            descriptor.m_CellIntermediateScale,
            descriptor.m_OutputIntermediateScale,
            descriptor.m_HiddenStateZeroPoint,
            descriptor.m_HiddenStateScale
            );

    // Index for constants vector
    std::size_t i = 0;

    // Mandatory params
    auto inputToForgetWeights     = CreateConstTensorInfo(constants[i++]); //InputToForgetWeights
    auto inputToCellWeights       = CreateConstTensorInfo(constants[i++]); //InputToCellWeights
    auto inputToOutputWeights     = CreateConstTensorInfo(constants[i++]); //InputToOutputWeights
    auto recurrentToForgetWeights = CreateConstTensorInfo(constants[i++]); //RecurrentToForgetWeights
    auto recurrentToCellWeights   = CreateConstTensorInfo(constants[i++]); //RecurrentToCellWeights
    auto recurrentToOutputWeights = CreateConstTensorInfo(constants[i++]); //RecurrentToOutputWeights
    auto forgetGateBias           = CreateConstTensorInfo(constants[i++]); //ForgetGateBias
    auto cellBias                 = CreateConstTensorInfo(constants[i++]); //CellBias
    auto outputGateBias           = CreateConstTensorInfo(constants[i++]); //OutputGateBias

    // CIFG
    flatbuffers::Offset<serializer::ConstTensor> inputToInputWeights;
    flatbuffers::Offset<serializer::ConstTensor> recurrentToInputWeights;
    flatbuffers::Offset<serializer::ConstTensor> inputGateBias;

    if (!descriptor.m_CifgEnabled)
    {
        inputToInputWeights = CreateConstTensorInfo(constants[i++]); //InputToInputWeights
        recurrentToInputWeights = CreateConstTensorInfo(constants[i++]); //RecurrentToInputWeights
        inputGateBias = CreateConstTensorInfo(constants[i++]); //InputGateBias
    }

    // Peephole
    flatbuffers::Offset<serializer::ConstTensor> cellToInputWeights;
    flatbuffers::Offset<serializer::ConstTensor> cellToForgetWeights;
    flatbuffers::Offset<serializer::ConstTensor> cellToOutputWeights;

    if (descriptor.m_PeepholeEnabled)
    {
        if (!descriptor.m_CifgEnabled)
        {
            cellToInputWeights = CreateConstTensorInfo(constants[i++]); //CellToInputWeights
        }
        cellToForgetWeights = CreateConstTensorInfo(constants[i++]); //CellToForgetWeights
        cellToOutputWeights = CreateConstTensorInfo(constants[i++]); //CellToOutputWeights
    }

    // Projection
    flatbuffers::Offset<serializer::ConstTensor> projectionWeights;
    flatbuffers::Offset<serializer::ConstTensor> projectionBias;

    if (descriptor.m_ProjectionEnabled)
    {
        projectionWeights = CreateConstTensorInfo(constants[i++]); //ProjectionWeights
        projectionBias = CreateConstTensorInfo(constants[i++]); //ProjectionBias
    }

    // Layer norm
    flatbuffers::Offset<serializer::ConstTensor> inputLayerNormWeights;
    flatbuffers::Offset<serializer::ConstTensor> forgetLayerNormWeights;
    flatbuffers::Offset<serializer::ConstTensor> cellLayerNormWeights;
    flatbuffers::Offset<serializer::ConstTensor> outputLayerNormWeights;

    if (descriptor.m_LayerNormEnabled)
    {
        if (!descriptor.m_CifgEnabled)
        {
            inputLayerNormWeights = CreateConstTensorInfo(constants[i++]); //InputLayerNormWeights
        }
        forgetLayerNormWeights = CreateConstTensorInfo(constants[i++]); //ForgetLayerNormWeights
        cellLayerNormWeights   = CreateConstTensorInfo(constants[i++]); //CellLayerNormWeights
        outputLayerNormWeights = CreateConstTensorInfo(constants[i++]); //OutputLayerNormWeights
    }

    auto fbQLstmParams = serializer::CreateQLstmInputParams(
            m_flatBufferBuilder,
            inputToForgetWeights,
            inputToCellWeights,
            inputToOutputWeights,
            recurrentToForgetWeights,
            recurrentToCellWeights,
            recurrentToOutputWeights,
            forgetGateBias,
            cellBias,
            outputGateBias,
            inputToInputWeights,
            recurrentToInputWeights,
            inputGateBias,
            projectionWeights,
            projectionBias,
            cellToInputWeights,
            cellToForgetWeights,
            cellToOutputWeights,
            inputLayerNormWeights,
            forgetLayerNormWeights,
            cellLayerNormWeights,
            outputLayerNormWeights);

    auto fbQLstmLayer = serializer::CreateQLstmLayer(
            m_flatBufferBuilder,
            fbQLstmBaseLayer,
            fbQLstmDescriptor,
            fbQLstmParams);

    CreateAnyLayer(fbQLstmLayer.o, serializer::Layer::Layer_QLstmLayer);
}

void SerializerStrategy::SerializeQuantizedLstmLayer(const armnn::IConnectableLayer* layer,
                                                     const std::vector<armnn::ConstTensor>& constants,
                                                     const char* name)
{
    IgnoreUnused(name);

    auto fbQuantizedLstmBaseLayer = CreateLayerBase(layer, serializer::LayerType::LayerType_QuantizedLstm);

    // index for constants vector
    size_t i = 0;

    // Get input parameters
    auto inputToInputWeights  = CreateConstTensorInfo(constants[i++]);
    auto inputToForgetWeights = CreateConstTensorInfo(constants[i++]);
    auto inputToCellWeights   = CreateConstTensorInfo(constants[i++]);
    auto inputToOutputWeights = CreateConstTensorInfo(constants[i++]);

    auto recurrentToInputWeights  = CreateConstTensorInfo(constants[i++]);
    auto recurrentToForgetWeights = CreateConstTensorInfo(constants[i++]);
    auto recurrentToCellWeights   = CreateConstTensorInfo(constants[i++]);
    auto recurrentToOutputWeights = CreateConstTensorInfo(constants[i++]);

    auto inputGateBias  = CreateConstTensorInfo(constants[i++]);
    auto forgetGateBias = CreateConstTensorInfo(constants[i++]);
    auto cellBias       = CreateConstTensorInfo(constants[i++]);
    auto outputGateBias = CreateConstTensorInfo(constants[i++]);

    auto fbQuantizedLstmParams = serializer::CreateQuantizedLstmInputParams(
        m_flatBufferBuilder,
        inputToInputWeights,
        inputToForgetWeights,
        inputToCellWeights,
        inputToOutputWeights,
        recurrentToInputWeights,
        recurrentToForgetWeights,
        recurrentToCellWeights,
        recurrentToOutputWeights,
        inputGateBias,
        forgetGateBias,
        cellBias,
        outputGateBias);

    auto fbQuantizedLstmLayer = serializer::CreateQuantizedLstmLayer(
        m_flatBufferBuilder,
        fbQuantizedLstmBaseLayer,
        fbQuantizedLstmParams);

    CreateAnyLayer(fbQuantizedLstmLayer.o, serializer::Layer::Layer_QuantizedLstmLayer);
}

fb::Offset<serializer::LayerBase> SerializerStrategy::CreateLayerBase(const IConnectableLayer* layer,
                                                                     const serializer::LayerType layerType)
{

    uint32_t fbIndex = GetSerializedId(layer->GetGuid());

    std::vector<fb::Offset<serializer::InputSlot>> inputSlots = CreateInputSlots(layer);
    std::vector<fb::Offset<serializer::OutputSlot>> outputSlots = CreateOutputSlots(layer);

    return serializer::CreateLayerBase(m_flatBufferBuilder,
                                       fbIndex,
                                       m_flatBufferBuilder.CreateString(layer->GetName()),
                                       layerType,
                                       m_flatBufferBuilder.CreateVector(inputSlots),
                                       m_flatBufferBuilder.CreateVector(outputSlots));
}

void SerializerStrategy::CreateAnyLayer(const flatbuffers::Offset<void>& layer, const serializer::Layer serializerLayer)
{

    auto anyLayer = armnnSerializer::CreateAnyLayer(m_flatBufferBuilder, serializerLayer, layer);
    m_serializedLayers.push_back(anyLayer);
}

template <typename T>
flatbuffers::Offset<flatbuffers::Vector<T>> SerializerStrategy::CreateDataVector(const void* memory, unsigned int size)
{
    const T* buffer = reinterpret_cast<const T*>(memory);
    std::vector<T> vector(buffer, buffer + (size / sizeof(T)));
    auto fbVector = m_flatBufferBuilder.CreateVector(vector);
    return fbVector;
}

flatbuffers::Offset<TensorInfo>  SerializerStrategy::CreateTensorInfo(const armnn::TensorInfo& tensorInfo)
{
    // Get the dimensions
    std::vector<unsigned int> shape;
    for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
    {
        shape.push_back(tensorInfo.GetShape()[dim]);
    }

    std::vector<bool> specificity;
    // This assumes that the TensorShape constructors have ensured that the size of m_DimensionsSpecificity
    // matches the size of dimensions.
    for(unsigned int dim = 0; dim < tensorInfo.GetShape().GetNumDimensions(); ++dim)
    {
        specificity.push_back(tensorInfo.GetShape().GetDimensionSpecificity(dim));
    }

    if (tensorInfo.HasPerAxisQuantization())
    {
        // Create FlatBuffer TensorInfo
        auto flatBufferTensorInfo =
            serializer::CreateTensorInfo(m_flatBufferBuilder,
                                         m_flatBufferBuilder.CreateVector(shape),
                                         GetFlatBufferDataType(tensorInfo.GetDataType()),
                                         tensorInfo.GetQuantizationScales()[0],
                                         tensorInfo.GetQuantizationOffset(),
                                         m_flatBufferBuilder.CreateVector(tensorInfo.GetQuantizationScales()),
                                         tensorInfo.GetQuantizationDim().value(),
                                         static_cast<unsigned int>
                                         (tensorInfo.GetShape().GetDimensionality()),
                                         m_flatBufferBuilder.CreateVector(specificity));
        return flatBufferTensorInfo;
    }

    // Create FlatBuffer TensorInfo
    auto flatBufferTensorInfo = serializer::CreateTensorInfo(m_flatBufferBuilder,
                                                             m_flatBufferBuilder.CreateVector(shape),
                                                             GetFlatBufferDataType(tensorInfo.GetDataType()),
                                                             tensorInfo.GetQuantizationScale(),
                                                             tensorInfo.GetQuantizationOffset(),
                                                             0,
                                                             0,
                                                             static_cast<unsigned int>
                                                             (tensorInfo.GetShape().GetDimensionality()),
                                                             m_flatBufferBuilder.CreateVector(specificity));
    return flatBufferTensorInfo;
}

flatbuffers::Offset<serializer::ConstTensor>
    SerializerStrategy::CreateConstTensorInfo(const armnn::ConstTensor& constTensor)
{
    armnn::TensorInfo tensorInfo = constTensor.GetInfo();

    flatbuffers::Offset<void> fbPayload;

    switch (tensorInfo.GetDataType())
    {
        case armnn::DataType::Float32:
        case armnn::DataType::Signed32:
        {
            auto fbVector = CreateDataVector<int32_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
            flatbuffers::Offset<serializer::IntData> flatBuffersData = serializer::CreateIntData(
                    m_flatBufferBuilder,
                    fbVector);
            fbPayload = flatBuffersData.o;
            break;
        }
        case armnn::DataType::Float16:
        case armnn::DataType::BFloat16:
        case armnn::DataType::QSymmS16:
        {
            auto fbVector = CreateDataVector<int16_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
            flatbuffers::Offset<serializer::ShortData> flatBuffersData = serializer::CreateShortData(
                    m_flatBufferBuilder,
                    fbVector);
            fbPayload = flatBuffersData.o;
            break;
        }
        case armnn::DataType::QSymmS8:
        case armnn::DataType::QAsymmS8:
        case armnn::DataType::QAsymmU8:
        case armnn::DataType::Boolean:
        default:
        {
            auto fbVector = CreateDataVector<int8_t>(constTensor.GetMemoryArea(), constTensor.GetNumBytes());
            flatbuffers::Offset<serializer::ByteData> flatBuffersData = serializer::CreateByteData(
                    m_flatBufferBuilder,
                    fbVector);
            fbPayload = flatBuffersData.o;
        }
    }
    flatbuffers::Offset<serializer::ConstTensor> flatBufferConstTensor = serializer::CreateConstTensor(
            m_flatBufferBuilder,
            CreateTensorInfo(tensorInfo),
            GetFlatBufferConstTensorData(tensorInfo.GetDataType()),
            fbPayload);
    return flatBufferConstTensor;
}

flatbuffers::Offset<armnnSerializer::FeatureCompatibilityVersions> SerializerStrategy::GetVersionTable()
{
    flatbuffers::Offset<armnnSerializer::FeatureCompatibilityVersions> versionsTable =
        serializer::CreateFeatureCompatibilityVersions(
                m_flatBufferBuilder,
                1 // Binding ids scheme version
            );
    return versionsTable;
}

std::vector<fb::Offset<serializer::InputSlot>>
    SerializerStrategy::CreateInputSlots(const armnn::IConnectableLayer* layer)
{
    std::vector<fb::Offset<serializer::InputSlot>> inputSlots;

    // Get the InputSlots
    for (unsigned int slotIndex = 0; slotIndex<layer->GetNumInputSlots(); ++slotIndex)
    {
        const IInputSlot& inputSlot = layer->GetInputSlot(slotIndex);

        // Get the Connection for the InputSlot
        const IOutputSlot* connection = inputSlot.GetConnection();

        // Create FlatBuffer Connection
        serializer::Connection conn(GetSerializedId(inputSlot.GetConnection()->GetOwningLayerGuid()),
                                    connection->CalculateIndexOnOwner());
        // Create FlatBuffer InputSlot
        inputSlots.push_back(serializer::CreateInputSlot(m_flatBufferBuilder, slotIndex, &conn));
    }
    return inputSlots;
}

std::vector<fb::Offset<serializer::OutputSlot>>
    SerializerStrategy::CreateOutputSlots(const armnn::IConnectableLayer* layer)
{
    std::vector<fb::Offset<serializer::OutputSlot>> outputSlots;

    // Get the OutputSlots
    for (unsigned int slotIndex = 0; slotIndex < layer->GetNumOutputSlots(); ++slotIndex)
    {
        const IOutputSlot& outputSlot = layer->GetOutputSlot(slotIndex);
        const armnn::TensorInfo& tensorInfo = outputSlot.GetTensorInfo();

        // Create FlatBuffer Outputslot
        outputSlots.push_back(serializer::CreateOutputSlot(m_flatBufferBuilder,
                                                           slotIndex,
                                                           CreateTensorInfo(tensorInfo)));
    }
    return outputSlots;
}

void SerializerStrategy::ExecuteStrategy(const armnn::IConnectableLayer* layer,
                                         const BaseDescriptor& descriptor,
                                         const std::vector<armnn::ConstTensor>& constants,
                                         const char* name,
                                         const armnn::LayerBindingId id)
{
    IgnoreUnused(constants);

    switch (layer->GetType())
    {
        case armnn::LayerType::Activation :
        {
            const armnn::ActivationDescriptor& layerDescriptor =
                    static_cast<const armnn::ActivationDescriptor&>(descriptor);
            SerializeActivationLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::Addition :
        {
            SerializeAdditionLayer(layer, name);
            break;
        }
        case armnn::LayerType::ArgMinMax :
        {
            const armnn::ArgMinMaxDescriptor& layerDescriptor =
                    static_cast<const armnn::ArgMinMaxDescriptor&>(descriptor);
            SerializeArgMinMaxLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::BatchNormalization :
        {
            const armnn::BatchNormalizationDescriptor& layerDescriptor =
                    static_cast<const armnn::BatchNormalizationDescriptor&>(descriptor);
            SerializeBatchNormalizationLayer(layer,
                                             layerDescriptor,
                                             constants,
                                             name);
            break;
        }
        case armnn::LayerType::BatchToSpaceNd :
        {
            const armnn::BatchToSpaceNdDescriptor& layerDescriptor =
                    static_cast<const armnn::BatchToSpaceNdDescriptor&>(descriptor);
            SerializeBatchToSpaceNdLayer(layer,
                                         layerDescriptor,
                                         name);
            break;
        }
        case armnn::LayerType::Comparison :
        {
            const armnn::ComparisonDescriptor& layerDescriptor =
                    static_cast<const armnn::ComparisonDescriptor&>(descriptor);
            SerializeComparisonLayer(layer,
                                     layerDescriptor,
                                     name);
            break;
        }
        case armnn::LayerType::Concat :
        {
            const armnn::ConcatDescriptor& layerDescriptor =
                    static_cast<const armnn::ConcatDescriptor&>(descriptor);
            SerializeConcatLayer(layer,
                                 layerDescriptor,
                                 name);
            break;
        }
        case armnn::LayerType::Constant :
        {
            SerializeConstantLayer(layer,
                                   constants,
                                   name);
            break;
        }
        case armnn::LayerType::Convolution2d :
        {
            const armnn::Convolution2dDescriptor& layerDescriptor =
                    static_cast<const armnn::Convolution2dDescriptor&>(descriptor);
            SerializeConvolution2dLayer(layer,
                                        layerDescriptor,
                                        constants,
                                        name);
            break;
        }
        case armnn::LayerType::DepthToSpace :
        {
            const armnn::DepthToSpaceDescriptor& layerDescriptor =
                    static_cast<const armnn::DepthToSpaceDescriptor&>(descriptor);
            SerializeDepthToSpaceLayer(layer,
                                       layerDescriptor,
                                       name);
            break;
        }
        case armnn::LayerType::DepthwiseConvolution2d :
        {
            const armnn::DepthwiseConvolution2dDescriptor& layerDescriptor =
                    static_cast<const armnn::DepthwiseConvolution2dDescriptor&>(descriptor);
            SerializeDepthwiseConvolution2dLayer(layer,
                                                 layerDescriptor,
                                                 constants,
                                                 name);
            break;
        }
        case armnn::LayerType::Dequantize :
        {
            SerializeDequantizeLayer(layer,
                                     name);
            break;
        }
        case armnn::LayerType::DetectionPostProcess :
        {
            const armnn::DetectionPostProcessDescriptor& layerDescriptor =
                    static_cast<const armnn::DetectionPostProcessDescriptor&>(descriptor);
            SerializeDetectionPostProcessLayer(layer, layerDescriptor, constants, name);
            break;
        }
        case armnn::LayerType::Division :
        {
            SerializeDivisionLayer(layer, name);
            break;
        }
        case armnn::LayerType::ElementwiseUnary :
        {
            const armnn::ElementwiseUnaryDescriptor& layerDescriptor =
                    static_cast<const armnn::ElementwiseUnaryDescriptor&>(descriptor);
            SerializeElementwiseUnaryLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::Fill :
        {
            const armnn::FillDescriptor& layerDescriptor =
                    static_cast<const armnn::FillDescriptor&>(descriptor);
            SerializeFillLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::Floor :
        {
            SerializeFloorLayer(layer, name);
            break;
        }
        case armnn::LayerType::FullyConnected :
        {
            const armnn::FullyConnectedDescriptor& layerDescriptor =
                    static_cast<const armnn::FullyConnectedDescriptor&>(descriptor);
            SerializeFullyConnectedLayer(layer, layerDescriptor, constants, name);
            break;
        }
        case armnn::LayerType::Gather :
        {
            const armnn::GatherDescriptor& layerDescriptor =
                    static_cast<const armnn::GatherDescriptor&>(descriptor);
            SerializeGatherLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::Input:
        {
            SerializeInputLayer(layer, id, name);
            break;
        }
        case armnn::LayerType::InstanceNormalization :
        {
            const armnn::InstanceNormalizationDescriptor& layerDescriptor =
                    static_cast<const armnn::InstanceNormalizationDescriptor&>(descriptor);
            SerializeInstanceNormalizationLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::L2Normalization :
        {
            const armnn::L2NormalizationDescriptor& layerDescriptor =
                    static_cast<const armnn::L2NormalizationDescriptor&>(descriptor);
            SerializeL2NormalizationLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::LogicalBinary :
        {
            const armnn::LogicalBinaryDescriptor& layerDescriptor =
                    static_cast<const armnn::LogicalBinaryDescriptor&>(descriptor);
            SerializeLogicalBinaryLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::LogSoftmax :
        {
            const armnn::LogSoftmaxDescriptor& layerDescriptor =
                    static_cast<const armnn::LogSoftmaxDescriptor&>(descriptor);
            SerializeLogSoftmaxLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::Lstm :
        {
            const armnn::LstmDescriptor& layerDescriptor =
                    static_cast<const armnn::LstmDescriptor&>(descriptor);
            SerializeLstmLayer(layer, layerDescriptor, constants, name);
            break;
        }
        case armnn::LayerType::QLstm :
        {
            const armnn::QLstmDescriptor& layerDescriptor =
                    static_cast<const armnn::QLstmDescriptor&>(descriptor);
            SerializeQLstmLayer(layer, layerDescriptor, constants, name);
            break;
        }
        case armnn::LayerType::Maximum :
        {
            SerializeMaximumLayer(layer, name);
            break;
        }
        case armnn::LayerType::Mean :
        {
            const armnn::MeanDescriptor& layerDescriptor =
                    static_cast<const armnn::MeanDescriptor&>(descriptor);
            SerializeMeanLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::Merge :
        {
            SerializeMergeLayer(layer, name);
            break;
        }
        case armnn::LayerType::Minimum :
        {
            SerializeMinimumLayer(layer, name);
            break;
        }
        case armnn::LayerType::Multiplication :
        {
            SerializeMultiplicationLayer(layer, name);
            break;
        }
        case armnn::LayerType::Normalization :
        {
            const armnn::NormalizationDescriptor& layerDescriptor =
                    static_cast<const armnn::NormalizationDescriptor&>(descriptor);
            SerializeNormalizationLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::Output:
        {
            SerializeOutputLayer(layer, id, name);
            break;
        }
        case armnn::LayerType::Pad :
        {
            const armnn::PadDescriptor& layerDescriptor =
                    static_cast<const armnn::PadDescriptor&>(descriptor);
            SerializePadLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::Permute :
        {
            const armnn::PermuteDescriptor& layerDescriptor =
                    static_cast<const armnn::PermuteDescriptor&>(descriptor);
            SerializePermuteLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::Pooling2d :
        {
            const armnn::Pooling2dDescriptor& layerDescriptor =
                    static_cast<const armnn::Pooling2dDescriptor&>(descriptor);
            SerializePooling2dLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::Prelu :
        {
            SerializePreluLayer(layer, name);
            break;
        }
        case armnn::LayerType::Quantize :
        {
            SerializeQuantizeLayer(layer, name);
            break;
        }
        case armnn::LayerType::QuantizedLstm:
            SerializeQuantizedLstmLayer(layer, constants, name);
            break;
        case armnn::LayerType::Reshape:
        {
            const armnn::ReshapeDescriptor &layerDescriptor =
                    static_cast<const armnn::ReshapeDescriptor &>(descriptor);
            SerializeReshapeLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::Rank:
        {
            SerializeRankLayer(layer, name);
            break;
        }
        case armnn::LayerType::Reduce:
        {
            const armnn::ReduceDescriptor& layerDescriptor =
                    static_cast<const armnn::ReduceDescriptor&>(descriptor);
            SerializeReduceLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::Resize:
        {
            const armnn::ResizeDescriptor& layerDescriptor =
                    static_cast<const armnn::ResizeDescriptor&>(descriptor);
            SerializeResizeLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::Slice:
        {
            const armnn::SliceDescriptor& layerDescriptor =
                    static_cast<const armnn::SliceDescriptor&>(descriptor);
            SerializeSliceLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::Softmax:
        {
            const armnn::SoftmaxDescriptor& layerDescriptor =
                    static_cast<const armnn::SoftmaxDescriptor&>(descriptor);
            SerializeSoftmaxLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::SpaceToBatchNd:
        {
            const armnn::SpaceToBatchNdDescriptor& layerDescriptor =
                    static_cast<const armnn::SpaceToBatchNdDescriptor&>(descriptor);
            SerializeSpaceToBatchNdLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::SpaceToDepth:
        {
            const armnn::SpaceToDepthDescriptor& layerDescriptor =
                    static_cast<const armnn::SpaceToDepthDescriptor&>(descriptor);
            SerializeSpaceToDepthLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::Splitter:
        {
            const armnn::SplitterDescriptor& layerDescriptor =
                    static_cast<const armnn::SplitterDescriptor&>(descriptor);
            SerializeSplitterLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::Stack:
        {
            const armnn::StackDescriptor& layerDescriptor =
                    static_cast<const armnn::StackDescriptor&>(descriptor);
            SerializeStackLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::StandIn:
        {
            const armnn::StandInDescriptor& layerDescriptor =
                    static_cast<const armnn::StandInDescriptor&>(descriptor);
            SerializeStandInLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::StridedSlice:
        {
            const armnn::StridedSliceDescriptor& layerDescriptor =
                    static_cast<const armnn::StridedSliceDescriptor&>(descriptor);
            SerializeStridedSliceLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::Subtraction:
        {
            SerializeSubtractionLayer(layer, name);
            break;
        }
        case armnn::LayerType::Switch:
        {
            SerializeSwitchLayer(layer, name);
            break;
        }
        case armnn::LayerType::Transpose:
        {
            const armnn::TransposeDescriptor& layerDescriptor =
                    static_cast<const armnn::TransposeDescriptor&>(descriptor);
            SerializeTransposeLayer(layer, layerDescriptor, name);
            break;
        }
        case armnn::LayerType::TransposeConvolution2d:
        {
            const armnn::TransposeConvolution2dDescriptor& layerDescriptor =
                    static_cast<const armnn::TransposeConvolution2dDescriptor&>(descriptor);
            SerializeTransposeConvolution2dLayer(layer, layerDescriptor, constants, name);
            break;
        }
        default:
        {
            throw InvalidArgumentException(
                    fmt::format("A layer of unknown type was given to the serializer. Layer name: {}; Layer Id: {}",
                                layer->GetName(),
                                id));
        }
    }
}

void ISerializer::SerializerImpl::Serialize(const INetwork& inNetwork)
{
    // Iterate through to network
    inNetwork.ExecuteStrategy(m_SerializerStrategy);
    flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerStrategy.GetFlatBufferBuilder();

    // Create FlatBuffer SerializedGraph
    auto serializedGraph = serializer::CreateSerializedGraph(
            fbBuilder,
            fbBuilder.CreateVector(m_SerializerStrategy.GetSerializedLayers()),
            fbBuilder.CreateVector(m_SerializerStrategy.GetInputIds()),
            fbBuilder.CreateVector(m_SerializerStrategy.GetOutputIds()),
            m_SerializerStrategy.GetVersionTable());

    // Serialize the graph
    fbBuilder.Finish(serializedGraph);
}


bool ISerializer::SerializerImpl::SaveSerializedToStream(std::ostream& stream)
{
    flatbuffers::FlatBufferBuilder& fbBuilder = m_SerializerStrategy.GetFlatBufferBuilder();

    auto bytesToWrite = armnn::numeric_cast<std::streamsize>(fbBuilder.GetSize());
    stream.write(reinterpret_cast<const char*>(fbBuilder.GetBufferPointer()), bytesToWrite);
    return !stream.bad();
}

} // namespace armnnSerializer
