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

#include <backendsCommon/TensorHandle.hpp>
#include <backendsCommon/WorkloadData.hpp>
#include <armnnUtils/DataLayoutIndexed.hpp>
#include <armnnUtils/TensorUtils.hpp>
#include <armnn/utility/NumericCast.hpp>
#include <armnn/Logging.hpp>

#include <algorithm>
#include <iomanip>
#include <string>
#include <sstream>

#include <fmt/format.h>

using namespace armnnUtils;

namespace armnn
{

//---------------------------------------------------------------
DataType GetBiasDataType(DataType inputDataType)
{
    switch (inputDataType)
    {
        case DataType::Float16:
            return DataType::Float16;
        case DataType::BFloat16:
        case DataType::Float32:
            return DataType::Float32;
        case DataType::QAsymmS8:
            return DataType::Signed32;
        case DataType::QAsymmU8:
            return DataType::Signed32;
        case DataType::QSymmS8:
            return DataType::Signed32;
        case DataType::QSymmS16:
            return DataType::Signed32;
        default:
            ARMNN_ASSERT_MSG(false, "Invalid input data type");
            return DataType::Float32;
    }
}

namespace
{

//---------------------------------------------------------------
//android ndk does not support std::to_string function.
template <typename T>
std::string to_string(T value)
{
    std::ostringstream os;
    os << value;
    return os.str();
}

//---------------------------------------------------------------
void ValidatePointer(const void* ptr, std::string const& descName, std::string const& paramName)
{
    if (!ptr)
    {
        throw InvalidArgumentException(descName +  ": Invalid null pointer. The " +
                                      paramName + " parameter must be set.");
    }
}

//---------------------------------------------------------------
void ValidateTensorShapesMatch(const TensorInfo& first,
                               const TensorInfo& second,
                               std::string const& descName,
                               std::string const& firstName,
                               std::string const& secondName)
{
    if (first.GetShape() != second.GetShape())
    {
        throw InvalidArgumentException(descName + ": "
                                       + firstName + " & " + secondName + " must have identical shapes");
    }
}

//---------------------------------------------------------------
void ValidateNumInputs(const WorkloadInfo& workloadInfo, std::string const& descName, const unsigned int expectedSize)
{
    if (workloadInfo.m_InputTensorInfos.size() != expectedSize)
    {
        throw InvalidArgumentException(descName +
                                       ": Requires exactly " + to_string(expectedSize) + "input(s). " +
                                       to_string(workloadInfo.m_InputTensorInfos.size()) + " have been provided.");
    }
}

//---------------------------------------------------------------
void ValidateNumOutputs(const WorkloadInfo& workloadInfo, std::string const& descName, const unsigned int expectedSize)
{
    if (workloadInfo.m_OutputTensorInfos.size() != expectedSize)
    {
        throw InvalidArgumentException(descName +
                                       ": Requires exactly " + to_string(expectedSize) + " output(s). " +
                                       to_string(workloadInfo.m_OutputTensorInfos.size()) + " has been provided.");
    }
}

//---------------------------------------------------------------
void ValidateTensorNumDimensions(const TensorInfo& tensor,
                                 std::string const& descName,
                                 unsigned int numDimensions,
                                 std::string const& tensorName)
{
    if (tensor.GetNumDimensions() != numDimensions)
    {
        throw InvalidArgumentException(descName + ": Expected " + to_string(numDimensions) + " but got " +
            to_string(tensor.GetNumDimensions()) + " dimensions for " +
            tensorName + " tensor.");
    }
}

//---------------------------------------------------------------
void ValidateTensorNumElements(const TensorInfo& tensor,
                               std::string const& descName,
                               unsigned int numElements,
                               std::string const& tensorName)
{
    if (tensor.GetNumElements() != numElements)
    {
        throw InvalidArgumentException(descName + ": Expected " + to_string(numElements) + " but got " +
                                       to_string(tensor.GetNumElements()) + " elements for " +
                                       tensorName + " tensor.");
    }
}

//---------------------------------------------------------------
void ValidateTensorNumDimNumElem(const TensorInfo& tensorInfo,
                                 unsigned int numDimension,
                                 unsigned int numElements,
                                 std::string const& tensorName)
{
    const std::string functionName{"ValidateTensorNumDimNumElem"};
    ValidateTensorNumDimensions(tensorInfo, functionName, numDimension, tensorName);
    ValidateTensorNumElements(tensorInfo, functionName, numElements, tensorName);
}

//---------------------------------------------------------------
void ValidateTensorDataType(const TensorInfo& tensor, DataType dataType,
    const std::string& descName, std::string const& tensorName)
{
    if (tensor.GetDataType() != dataType)
    {
        throw InvalidArgumentException(descName + ": Expected data type " + GetDataTypeName(dataType) + " but got " +
            GetDataTypeName(tensor.GetDataType()) + " for " + tensorName + " tensor.");
    }
}

void ValidPerAxisQuantizedDataType(const TensorInfo& tensor, const std::string& descName, const std::string& tensorName)
{
    if (tensor.GetDataType() != DataType::QSymmS8)
    {
        throw InvalidArgumentException(descName +
            ": Expected data type which supports per-axis quantization scheme but got " +
            GetDataTypeName(tensor.GetDataType()) + " for " + tensorName + " tensor.");
    }
}

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

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

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

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

//---------------------------------------------------------------
void ValidateBiasTensorQuantization(const TensorInfo& biasTensor,
                                    const TensorInfo& inputTensorInfo,
                                    const TensorInfo& weightsTensorInfo,
                                    const std::string& descName)
{
    // Helper lambda function to validate a single bias quantization scale value
    auto VerifyBiasQuantizationScale = [&descName](float biasScale, float expectedScale) -> void
    {
        constexpr float tolerance = 0.0001f;
        if (std::abs(biasScale - expectedScale) > tolerance)
        {
            // Print the float values with extra precision to see very small differences
            ARMNN_LOG(warning) << std::setprecision(6) << descName << ": Expected " << expectedScale <<
                " for bias quantization scale (product of input and weight scales), but got " <<
                biasScale << ". Using scale provided.";
        }
    };

    if (biasTensor.GetQuantizationOffset() != 0)
    {
        throw InvalidArgumentException(descName + ": Expected zero quantization offset for bias tensor but got " +
            to_string(biasTensor.GetQuantizationOffset()));
    }

    if (biasTensor.HasMultipleQuantizationScales() || weightsTensorInfo.HasMultipleQuantizationScales())
    {
        // Validate per-axis quantization scales
        const std::vector<float>& weightScales = weightsTensorInfo.GetQuantizationScales();
        const std::vector<float>& biasScales   = biasTensor.GetQuantizationScales();

        if (weightScales.size() != biasScales.size())
        {
            std::stringstream msg;
            msg << descName << ": Expected matching number of per-axis quantization scales for weights and bias, "
                << "but got different values. This is currently unsupported: weights=" << weightScales.size()
                << ", biases=" << biasScales.size();
            throw InvalidArgumentException(msg.str(), CHECK_LOCATION());
        }

        for (size_t i = 0ul; i < biasScales.size(); ++i)
        {
            const float expectedScale = inputTensorInfo.GetQuantizationScale() * weightScales[i];
            VerifyBiasQuantizationScale(biasScales[i], expectedScale);
        }
    }
    else
    {
        // Validate per-tensor quantization scale
        const float expectedScale = inputTensorInfo.GetQuantizationScale() * weightsTensorInfo.GetQuantizationScale();
        VerifyBiasQuantizationScale(biasTensor.GetQuantizationScale(), expectedScale);
    }
}

//---------------------------------------------------------------
void ValidateTensors(const std::vector<ITensorHandle*>& vec,
    unsigned int numExpected,
    const std::string& descName,
    const std::string& varName)
{
    if (vec.empty() && numExpected > 0)
    {
        throw InvalidArgumentException(descName + ": Invalid empty " + varName + " array.");
    }

    for (unsigned int i = 0; i < numExpected; ++i)
    {
        if (!vec[i])
        {
            throw InvalidArgumentException(descName + ": Invalid NULL for " + varName + to_string(i));
        }
    }
}

//---------------------------------------------------------------
void ValidateBroadcastTensorShapesMatch(const TensorInfo& first,
                                        const TensorInfo& second,
                                        const TensorInfo& output,
                                        std::string const& descName,
                                        std::string const& firstName,
                                        std::string const& secondName)
{
    // Tensors must have the same number of dimensions in order to be explicit about which dimensions will get
    // broadcasted.
    if (first.GetNumDimensions() != second.GetNumDimensions())
    {
        throw InvalidArgumentException(descName  + ": Tensors "
            + firstName + " & " + secondName
            + " must have the same number of dimensions in order to be broadcasted");
    }
    uint32_t numDims = first.GetNumDimensions();
    std::vector<uint32_t> outputDims(numDims, 0u);
    for (uint32_t i = 0; i < numDims; i++)
    {
        const bool dimsNotEqual = first.GetShape()[i] != second.GetShape()[i];
        const bool dimsNotOne = (first.GetShape()[i] != 1) && (second.GetShape()[i] != 1);
        if (dimsNotEqual && dimsNotOne)
        {
            throw InvalidArgumentException("Broadcasting is not possible for incompatible shapes");
        }
        outputDims[i] = std::max(first.GetShape()[i], second.GetShape()[i]);
    }
    TensorShape broadcastShape = TensorShape(armnn::numeric_cast<unsigned int>(outputDims.size()), outputDims.data());
    if (broadcastShape != output.GetShape())
    {
        throw InvalidArgumentException(descName + ": The tensor shape resulting from adding "
                                       + firstName + " & " + secondName
                                       + " does not match the output shape");
    }
}

//---------------------------------------------------------------
void ValidateDataTypes(const TensorInfo& info,
                       const std::vector<armnn::DataType>& supportedTypes,
                       std::string const& descName)
{
    auto iterator = std::find(supportedTypes.begin(), supportedTypes.end(), info.GetDataType());
    if (iterator == supportedTypes.end())
    {
        throw InvalidArgumentException(descName  + ": " + " Tensor type is not supported.");
    }
}

//---------------------------------------------------------------
void ValidateTensorDataTypesMatch(const TensorInfo& first,
                                  const TensorInfo& second,
                                  std::string const& descName,
                                  std::string const& firstName,
                                  std::string const& secondName)
{
    if (first.GetDataType() != second.GetDataType())
    {
        throw InvalidArgumentException(descName + ": " + firstName + " & " + secondName +
                                       " must have identical data types.");
    }
}

//---------------------------------------------------------------
void ValidateTensorNumElementsMatch(const TensorInfo& first,
                                    const TensorInfo& second,
                                    std::string const& descName,
                                    std::string const& firstName,
                                    std::string const& secondName)
{
    if (first.GetNumElements() != second.GetNumElements())
    {
        throw InvalidArgumentException(descName + ": " + firstName + " & " + secondName +
                                       " must have the same number of elements.");
    }
}

void ValidateWeightDataType(const TensorInfo& inputInfo,
                            const TensorInfo& weightInfo,
                            const std::string& descName)
{
    const DataType inputType = inputInfo.GetDataType();
    if (IsQuantized8BitType(inputType))
    {
        const std::vector<DataType> validTypes =
        {
            DataType::QAsymmS8,
            DataType::QAsymmU8,
            DataType::QSymmS8
        };

        ValidateDataTypes(weightInfo, validTypes, descName);
    }
    else
    {
        ValidateTensorDataTypesMatch(inputInfo, weightInfo, descName, "input", "weight");
    }
}

void ValidatePerAxisQuantizationDimension(const TensorInfo& tensorInfo,
                                          const std::string& descName,
                                          const std::string& tensorName)
{
    const Optional<unsigned int>& quantizationDim = tensorInfo.GetQuantizationDim();
    if (!quantizationDim.has_value())
    {
        throw InvalidArgumentException(fmt::format("{0}: Quantization dimension for per-axis quantization "
                                                   "not set on tensor {1}.", descName, tensorName));
    }
}

void ValidatePerAxisQuantizationOffset(const TensorInfo& tensorInfo,
                                       const std::string& descName,
                                       const std::string& tensorName)
{
    int32_t quantizationOffset = tensorInfo.GetQuantizationOffset();
    if (quantizationOffset != 0)
    {
        throw InvalidArgumentException(fmt::format(
            "{0}: Quantization offset for per-axis quantization expected to be 0 on tensor {1}, but got: {2}",
            descName, tensorName, quantizationOffset));
    }
}

void ValidatePerAxisQuantization(const TensorInfo& inputInfo,
                                 const TensorInfo& outputInfo,
                                 const TensorInfo& weightInfo,
                                 const Optional<TensorInfo>& optionalBiasInfo,
                                 const std::string& descName)
{
    if (weightInfo.HasPerAxisQuantization())
    {
        const DataType inputDataType  = inputInfo.GetDataType();
        const DataType outputDataType = outputInfo.GetDataType();

        const bool canHavePerAxisQuantization = (IsQuantized8BitType(inputDataType)) && inputDataType == outputDataType;

        if (!canHavePerAxisQuantization)
        {
            throw InvalidArgumentException(fmt::format(
                "{0}: Per-axis quantization parameters set on tensor {1}, but data type does not support "
                "per-axis quantization.", descName, "weight"));
        }


        ValidPerAxisQuantizedDataType(weightInfo, descName, "weight");
        ValidatePerAxisQuantizationDimension(weightInfo, descName, "weight");
        ValidatePerAxisQuantizationOffset(weightInfo, descName, "weight");

        if (optionalBiasInfo.has_value())
        {
            const TensorInfo& biasInfo = optionalBiasInfo.value();
            if (!biasInfo.HasPerAxisQuantization())
            {
                throw InvalidArgumentException(fmt::format(
                        "{}: Per-axis quantization parameters not set on bias tensor, "
                        "despite being set on weight tensor.", descName));
            }

            ValidateTensorDataType(biasInfo, DataType::Signed32, descName, "bias");
            ValidatePerAxisQuantizationDimension(biasInfo, descName, "bias");
            ValidatePerAxisQuantizationOffset(biasInfo, descName, "bias");
        }
    }
}

} // anonymous namespace

void QueueDescriptor::ValidateInputsOutputs(const std::string& descName,
    unsigned int numExpectedIn, unsigned int numExpectedOut) const
{
    ValidateTensors(m_Inputs, numExpectedIn, descName, "input");
    ValidateTensors(m_Outputs, numExpectedOut, descName, "output");
}

//---------------------------------------------------------------
void MapQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"MapQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 0);

    for (unsigned int i = 0; i < m_Inputs.size(); ++i)
    {
        if (!m_Inputs[i])
        {
            throw InvalidArgumentException(
                fmt::format("{}: Invalid NULL input {}.", descriptorName, static_cast<int>(i)));
        }
    }
}

//---------------------------------------------------------------
void UnmapQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"UnmapQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 0);

    for (unsigned int i = 0; i < m_Inputs.size(); ++i)
    {
        if (!m_Inputs[i])
        {
            throw InvalidArgumentException(
                fmt::format("{}: Invalid NULL input {}.", descriptorName, static_cast<int>(i)));
        }
    }
}

//---------------------------------------------------------------
void MemCopyQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"MemCopyQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName , 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorNumElementsMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");

    if (m_Inputs.size() != m_Outputs.size())
    {
        throw InvalidArgumentException(fmt::format(
            "{0}: Number of inputs ({1}) does not match the number of outputs ({2}).",
            descriptorName, m_Inputs.size(), m_Outputs.size()));
    }

    for (unsigned int i = 0; i < m_Inputs.size(); ++i)
    {
        if (!m_Inputs[i])
        {
            throw InvalidArgumentException(fmt::format(
                "{0}: Invalid NULL input {1}.", descriptorName, i));
        }

        if (!m_Outputs[i])
        {
            throw InvalidArgumentException(fmt::format("{0}: Invalid NULL output {1}", descriptorName, i));
        }
    }
}

//---------------------------------------------------------------
void MemImportQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    ValidateNumInputs(workloadInfo, "MemImportQueueDescriptor", 1);
    ValidateNumOutputs(workloadInfo, "MemImportQueueDescriptor" , 1);

    if (workloadInfo.m_InputTensorInfos.size() != 1)
    {
        throw InvalidArgumentException(fmt::format("Number of input infos ({}) is not 1.",
                                                   workloadInfo.m_InputTensorInfos.size()));

    }

    if (workloadInfo.m_InputTensorInfos.size() != workloadInfo.m_OutputTensorInfos.size())
    {
        throw InvalidArgumentException(fmt::format(
            "Number of input infos ({0}) does not match the number of output infos ({1})",
            workloadInfo.m_InputTensorInfos.size(), workloadInfo.m_OutputTensorInfos.size()));
    }

    for (std::size_t i = 0; i < workloadInfo.m_InputTensorInfos.size(); ++i)
    {
        if (workloadInfo.m_InputTensorInfos[i].GetNumElements() !=
            workloadInfo.m_OutputTensorInfos[i].GetNumElements())
        {
            throw InvalidArgumentException(fmt::format(
                "Number of elements for tensor input and output {} does not match", i ));
        }
    }

    if (m_Inputs.size() != 1)
    {
        throw InvalidArgumentException(fmt::format("Number of inputs ({}) is not 1.", m_Inputs.size()));
    }

    if (m_Inputs.size() != m_Outputs.size())
    {
        throw InvalidArgumentException(fmt::format(
            "Number of inputs ({0}) does not match the number of outputs ({1})",
            m_Inputs.size(), m_Outputs.size()));
    }

    for (unsigned int i = 0; i < m_Inputs.size(); ++i)
    {
        if (!m_Inputs[i])
        {
            throw InvalidArgumentException(fmt::format("Invalid null input {}", i));
        }

        if (!m_Outputs[i])
        {
            throw InvalidArgumentException(fmt::format("Invalid null output {}", i));
        }
    }
}

//---------------------------------------------------------------
void MemSyncQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    ValidateNumInputs(workloadInfo, "MemSyncQueueDescriptor", 1);
    ValidateNumOutputs(workloadInfo, "MemSyncQueueDescriptor" , 1);

    if (m_Inputs.size() != 1)
    {
        throw InvalidArgumentException(fmt::format("Number of inputs ({}) is not 1.", m_Inputs.size()));
    }

    if (m_Outputs.size() != 0)
    {
        throw InvalidArgumentException(fmt::format("Number of outputs ({}) is not 0.", m_Outputs.size()));
    }

    if (!m_Inputs[0])
    {
        throw InvalidArgumentException(fmt::format("Invalid null input 0"));
    }
}

//---------------------------------------------------------------
void ActivationQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"ActivationQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
    ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void ArgMinMaxQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"ArgMinMaxQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    if (outputTensorInfo.GetDataType() != DataType::Signed32 &&
        outputTensorInfo.GetDataType() != DataType::Signed64)
    {
        throw InvalidArgumentException(descriptorName + ": Output of ArgMinMax layer must be Int32 or Int64.");
    }

    std::vector<DataType> supportedInputTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16,
        DataType::Signed32,
        DataType::Signed64
    };

    ValidateDataTypes(inputTensorInfo, supportedInputTypes, descriptorName);

    auto inputShape = inputTensorInfo.GetShape();
    auto outputShape = outputTensorInfo.GetShape();

    auto inputNumDimensions = inputShape.GetNumDimensions();
    auto unsignedAxis = armnnUtils::GetUnsignedAxis(inputNumDimensions, m_Parameters.m_Axis);

    const std::string outputShapeError{": Output tensor shape does not match shape inferred from input tensor."};

    // 1D input shape results in scalar output shape
    if (inputShape.GetNumDimensions() == 1)
    {
        if (outputShape.GetNumDimensions() != 1 && outputShape[0] != 1)
        {
            throw InvalidArgumentException(descriptorName + outputShapeError);
        }
    }
    else
    {
        for (unsigned int i = 0; i < unsignedAxis; ++i)
        {
            if (outputShape[i] != inputShape[i])
            {
                throw InvalidArgumentException(descriptorName + outputShapeError);
            }
        }

        for (auto i = unsignedAxis + 1; i < inputNumDimensions; ++i)
        {
            if (outputShape[i - 1] != inputShape[i])
            {
                throw InvalidArgumentException(descriptorName + outputShapeError);
            }
        }
    }
}

void CastQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"CastQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    std::vector<DataType> supportedTypes =
    {
            DataType::BFloat16,
            DataType::Float16,
            DataType::Float32,
            DataType::QAsymmS8,
            DataType::QAsymmU8,
            DataType::QSymmS8,
            DataType::QSymmS16,
            DataType::Signed32,
            DataType::Signed64
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
    ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void SoftmaxQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"SoftmaxQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
    ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void SplitterQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"SplitterQueueDescriptor"};

    ValidateNumInputs(workloadInfo, descriptorName, 1);

    // Check the supported data types
    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::Float16,
        DataType::Boolean,
        DataType::Signed32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
    for (unsigned long i = 0ul; i < workloadInfo.m_OutputTensorInfos.size(); ++i)
    {
        const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[i];
        ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);

        const std::string outputName = "output_" + std::to_string(i);
        ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", outputName);
    }

    if (workloadInfo.m_OutputTensorInfos.size() <= 0)
    {
        throw InvalidArgumentException(descriptorName + ": At least one output needs to be provided.");
    }

    if (workloadInfo.m_OutputTensorInfos.size() != m_ViewOrigins.size())
    {
        throw InvalidArgumentException(
            descriptorName + ": Number of split windows "
            "has to match number of workloadInfo.m_OutputTensorInfos. "
            "Number of windows: " +
            to_string(m_ViewOrigins.size()) +
            ". Number of workloadInfo.m_OutputTensorInfos: " + to_string(workloadInfo.m_OutputTensorInfos.size()));
    }

    //The dimensionality of all the windows has to match the dimensionality (not shape) of the input.
    std::size_t inputDims = workloadInfo.m_InputTensorInfos[0].GetNumDimensions();
    for(unsigned int w = 0; w < m_ViewOrigins.size(); ++w )
    {
        //Checks that the dimensionality of input is same as the split windows.
        ViewOrigin const& e = m_ViewOrigins[w];
        if (e.m_Origin.size() != inputDims)
        {
            throw InvalidArgumentException(descriptorName + ": Window origin have to "
                                           "have the same dimensionality as the input tensor. "
                                           "Window origin (index: " +
                                           to_string(w) + ") has " + to_string(e.m_Origin.size()) +
                                           " dimensions, the input "
                                           "tensor has " +
                                           to_string(inputDims) + " dimensions.");
        }
        for (unsigned int i = 0; i < e.m_Origin.size(); ++i)
        {
            if (e.m_Origin[i] + workloadInfo.m_OutputTensorInfos[w].GetShape()[i] >
                workloadInfo.m_InputTensorInfos[0].GetShape()[i])
            {
                throw InvalidArgumentException(descriptorName + ": Window extent coordinates have to "
                                               "be smaller or equal than the size of the input in that coord.");
            }
        }
    }
}

void ConcatQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"ConcatQueueDescriptor"};

    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    if (m_Inputs.size() <= 0)
    {
        throw InvalidArgumentException(descriptorName + ": At least one input needs to be provided.");
    }
    if (m_Outputs.size() <= 0)
    {
        throw InvalidArgumentException(descriptorName + ": At least one output needs to be provided.");
    }

    if (workloadInfo.m_InputTensorInfos.size() <= 0)
    {
        throw InvalidArgumentException(descriptorName + ": At least one TensorInfo input needs to be provided.");
    }
    if (workloadInfo.m_OutputTensorInfos.size() <= 0)
    {
        throw InvalidArgumentException(descriptorName + ": At least one TensorInfo output needs to be provided.");
    }

    if(m_Parameters.GetConcatAxis() > workloadInfo.m_InputTensorInfos[0].GetShape().GetNumDimensions())
    {
        throw InvalidArgumentException(descriptorName + ": Invalid concatenation axis provided.");
    }

    if (workloadInfo.m_InputTensorInfos[0].GetShape().GetNumDimensions() - m_Parameters.GetConcatAxis() == 1)
    {
        return;
    }

    if (workloadInfo.m_InputTensorInfos.size() != m_ViewOrigins.size())
    {
        throw InvalidArgumentException(
            descriptorName + ": Number of split windows "
            "has to match number of workloadInfo.m_InputTensorInfos. "
            "Number of windows: " +
            to_string(m_ViewOrigins.size()) +
            ". Number of workloadInfo.m_InputTensorInfos: " + to_string(workloadInfo.m_InputTensorInfos.size()));
    }

    //The dimensionality of all the windows has to match the dimensionality (not shape) of the output.
    std::size_t outputDims = workloadInfo.m_OutputTensorInfos[0].GetNumDimensions();
    for(unsigned int w = 0; w < m_ViewOrigins.size(); ++w )
    {
        //Checks that the dimensionality of output is same as the split windows.
        ViewOrigin const& e = m_ViewOrigins[w];
        if (e.m_Origin.size() != outputDims)
        {
            throw InvalidArgumentException(descriptorName + ": Window origin have to "
                                           "have the same dimensionality as the output tensor. "
                                           "Window origin (index: " +
                                           to_string(w) + ") has " + to_string(e.m_Origin.size()) +
                                           " dimensions, the output "
                                           "tensor has " +
                                           to_string(outputDims) + " dimensions.");
        }
        //Checks that the merge windows are within the output tensor.
        for (unsigned int i = 0; i < e.m_Origin.size(); ++i)
        {
            if (e.m_Origin[i] + workloadInfo.m_InputTensorInfos[w].GetShape()[i]
                > workloadInfo.m_OutputTensorInfos[0].GetShape()[i])
            {
                throw InvalidArgumentException(descriptorName + ": Window extent coordinates have to "
                                               "be smaller or equal than the size of the output in that coord.");
            }
        }
    }

    // Check the supported data types
    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::Float16,
        DataType::Boolean,
        DataType::Signed32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
    for (unsigned long i = 0ul; i < workloadInfo.m_InputTensorInfos.size(); ++i)
    {
        const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[i];
        ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);

        const std::string inputName = "input_" + std::to_string(i);
        ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, inputName, "output");
    }
}

void StackQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"StackQueueDescriptor"};

    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    if (m_Parameters.m_NumInputs != workloadInfo.m_InputTensorInfos.size())
    {
        throw InvalidArgumentException(descriptorName + ": Must have the defined number of input tensors.");
    }

    // All inputs must have the same shape, which is defined in parameters
    const TensorShape& inputShape = m_Parameters.m_InputShape;
    for (unsigned int i = 0; i < workloadInfo.m_InputTensorInfos.size(); ++i)
    {
        if (workloadInfo.m_InputTensorInfos[i].GetShape() != inputShape)
        {
            throw InvalidArgumentException(descriptorName + ": All input tensor shapes must match the defined shape.");
        }
    }

    if (inputShape.GetNumDimensions() > 4)
    {
        throw InvalidArgumentException(descriptorName + ": Input tensor may have up to 4 dimensions.");
    }

    // m_Axis is 0-based and may take values from 0 to the number of input dimensions (inclusive),
    // since the output tensor has an additional dimension.
    if (m_Parameters.m_Axis > inputShape.GetNumDimensions())
    {
        throw InvalidArgumentException(descriptorName + ": Axis may not be greater "
                                       "than the number of input dimensions.");
    }

    // Output shape must be as inferred from the input shape
    const TensorShape& outputShape = workloadInfo.m_OutputTensorInfos[0].GetShape();
    for (unsigned int i = 0; i < m_Parameters.m_Axis; ++i)
    {
        if (outputShape[i] != inputShape[i])
        {
            throw InvalidArgumentException(descriptorName + ": Output tensor must "
                                           "match shape inferred from input tensor.");
        }
    }

    if (outputShape[m_Parameters.m_Axis] != m_Parameters.m_NumInputs)
    {
        throw InvalidArgumentException(descriptorName + ": Output tensor must "
                                       "match shape inferred from input tensor.");
    }

    for (unsigned int i = m_Parameters.m_Axis + 1; i < inputShape.GetNumDimensions() + 1; ++i)
    {
        if (outputShape[i] != inputShape[i-1])
        {
            throw InvalidArgumentException(descriptorName + ": Output tensor must "
                                           "match shape inferred from input tensor.");
        }
    }

    if (outputShape.GetNumDimensions() > 5)
    {
        throw InvalidArgumentException(descriptorName + ": Output tensor may have up to 5 dimensions.");
    }

    // Check the supported data types
    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::Float16,
        DataType::Boolean,
        DataType::Signed32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(workloadInfo.m_InputTensorInfos[0], supportedTypes, descriptorName);

    for (unsigned int i = 1ul; i < workloadInfo.m_InputTensorInfos.size(); ++i)
    {
        ValidateTensorDataTypesMatch(workloadInfo.m_InputTensorInfos[0],
                                     workloadInfo.m_InputTensorInfos[i],
                                     descriptorName,
                                     "input_0",
                                     "input_" + std::to_string(i));
    }

    ValidateTensorDataTypesMatch(workloadInfo.m_InputTensorInfos[0],
                                 workloadInfo.m_OutputTensorInfos[0],
                                 descriptorName,
                                 "input_0",
                                 "output");
}

void FillQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"FillQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorNumDimensions(inputTensorInfo, descriptorName, 1, "input");

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::Float16,
        DataType::Signed32
    };

    ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
}

void FullyConnectedQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"FullyConnectedQueueDescriptor"};

    uint32_t numInputs = 2;
    if (m_Parameters.m_BiasEnabled)
    {
        numInputs = 3;
    }

    ValidateNumInputs(workloadInfo, descriptorName, numInputs);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 2, "output");

    if (!(inputTensorInfo.GetNumDimensions() == 2 || inputTensorInfo.GetNumDimensions() == 4))
    {
        throw InvalidArgumentException(descriptorName + ": Input tensor must have 2 or 4 dimensions.");
    }

    TensorInfo weightTensorInfo = workloadInfo.m_InputTensorInfos[1];
    ValidateTensorNumDimensions(weightTensorInfo, descriptorName, 2, "weight");

    if (m_Parameters.m_BiasEnabled)
    {
        TensorInfo biasTensorInfo = workloadInfo.m_InputTensorInfos[2];
        // Validates type and quantization values.
        ValidateBiasTensorQuantization(biasTensorInfo, inputTensorInfo, weightTensorInfo, descriptorName);
        ValidateTensorDataType(biasTensorInfo, GetBiasDataType(inputTensorInfo.GetDataType()), descriptorName, "bias");
        ValidateTensorNumDimensions(biasTensorInfo, descriptorName, 1, "bias");
    }

    // Check the supported data types
    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::Float16,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);

    // For FullyConnected, we allow to have BFloat16 input with Float32 output for optimization.
    if (inputTensorInfo.GetDataType() == DataType::BFloat16)
    {
        if (outputTensorInfo.GetDataType() != DataType::BFloat16 && outputTensorInfo.GetDataType() != DataType::Float32)
        {
            throw InvalidArgumentException(descriptorName  + ": " + " Output tensor type must be BFloat16 or Float32 "
                                           "for BFloat16 input.");
        }
    }
    else
    {
        ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
    }
}

void NormalizationQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"NormalizationQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    // Check the supported data types
    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);

    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");

    ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void AdditionQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"AdditionQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 2);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::Float16,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16,
        DataType::Signed32
    };

    ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
    ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
    ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);

    ValidateTensorDataTypesMatch(inputTensorInfo0, inputTensorInfo1, descriptorName, "input_0", "input_1");
    ValidateTensorDataTypesMatch(inputTensorInfo1, outputTensorInfo, descriptorName, "input_1", "output");

    ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
                                       inputTensorInfo1,
                                       outputTensorInfo,
                                       descriptorName,
                                       "input_0",
                                       "input_1");
}

void MultiplicationQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"MultiplicationQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 2);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16,
        DataType::Signed32
    };

    ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
    ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
    ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);

    ValidateTensorDataTypesMatch(inputTensorInfo0, inputTensorInfo1, descriptorName, "input_0", "input_1");
    ValidateTensorDataTypesMatch(inputTensorInfo1, outputTensorInfo, descriptorName, "input_1", "output");

    ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
                                       inputTensorInfo1,
                                       outputTensorInfo,
                                       descriptorName,
                                       "input_0",
                                       "input_1");
}

void BatchNormalizationQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"BatchNormalizationQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputTensorInfo,  supportedTypes, descriptorName);
    ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);

    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
    ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");

    ValidatePointer(m_Mean,     descriptorName, "mean");
    ValidatePointer(m_Variance, descriptorName, "variance");
    ValidatePointer(m_Beta,     descriptorName, "beta");
    ValidatePointer(m_Gamma,    descriptorName, "gamma");

    const TensorInfo& mean     = m_Mean->GetTensorInfo();
    const TensorInfo& variance = m_Variance->GetTensorInfo();
    const TensorInfo& beta     = m_Beta->GetTensorInfo();
    const TensorInfo& gamma    = m_Gamma->GetTensorInfo();

    ValidateTensorNumDimensions(mean,     descriptorName, 1, "mean");
    ValidateTensorNumDimensions(variance, descriptorName, 1, "variance");
    ValidateTensorNumDimensions(beta,     descriptorName, 1, "beta");
    ValidateTensorNumDimensions(gamma,    descriptorName, 1, "gamma");

    ValidateTensorShapesMatch(mean, variance, descriptorName, "mean", "variance");
    ValidateTensorShapesMatch(mean, beta,     descriptorName, "mean", "beta");
    ValidateTensorShapesMatch(mean, gamma,    descriptorName, "mean", "gamma");
}

void Convolution2dQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"Convolution2dQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorNumDimensions(inputTensorInfo,  descriptorName, 4, "input");
    ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 4, "output");

    ValidatePointer(m_Weight, descriptorName, "weight");

    const TensorInfo& weightTensorInfo = m_Weight->GetTensorInfo();
    ValidateTensorNumDimensions(weightTensorInfo, descriptorName, 4, "weight");

    ValidateWeightDataType(inputTensorInfo, weightTensorInfo, descriptorName);

    Optional<TensorInfo> optionalBiasTensorInfo;
    if (m_Parameters.m_BiasEnabled)
    {
        ValidatePointer(m_Bias, descriptorName, "bias");

        optionalBiasTensorInfo = MakeOptional<TensorInfo>(m_Bias->GetTensorInfo());
        const TensorInfo& biasTensorInfo = optionalBiasTensorInfo.value();

        ValidateTensorDataType(biasTensorInfo, GetBiasDataType(inputTensorInfo.GetDataType()), descriptorName, "bias");
        ValidateBiasTensorQuantization(biasTensorInfo, inputTensorInfo, weightTensorInfo, descriptorName);
    }

    if (m_Parameters.m_StrideX <= 0 || m_Parameters.m_StrideY <= 0  )
    {
        throw InvalidArgumentException(
            fmt::format("{}: strideX (provided {}) and strideY (provided {}) "
                        "cannot be either negative or 0.",
                        descriptorName, m_Parameters.m_StrideX, m_Parameters.m_StrideY));
    }

    ValidatePerAxisQuantization(inputTensorInfo,
                                outputTensorInfo,
                                weightTensorInfo,
                                optionalBiasTensorInfo,
                                descriptorName);

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16,
        DataType::QSymmS8
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);

    // For Convolution2d, we allow to have BFloat16 input with Float32 output for optimization.
    if (inputTensorInfo.GetDataType() == DataType::BFloat16)
    {
        if (outputTensorInfo.GetDataType() != DataType::BFloat16 && outputTensorInfo.GetDataType() != DataType::Float32)
        {
            throw InvalidArgumentException(descriptorName  + ": " + " Output tensor type must be BFloat16 or Float32 "
                                           "for BFloat16 input.");
        }
    }
    else
    {
        ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
    }
}

void Convolution3dQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"Convolution3dQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorNumDimensions(inputTensorInfo,  descriptorName, 5, "input");
    ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 5, "output");

    ValidatePointer(m_Weight, descriptorName, "weight");

    const TensorInfo& weightTensorInfo = m_Weight->GetTensorInfo();
    ValidateTensorNumDimensions(weightTensorInfo, descriptorName, 5, "weight");

    ValidateWeightDataType(inputTensorInfo, weightTensorInfo, descriptorName);

    Optional<TensorInfo> optionalBiasTensorInfo;
    if (m_Parameters.m_BiasEnabled)
    {
        ValidatePointer(m_Bias, descriptorName, "bias");

        optionalBiasTensorInfo = MakeOptional<TensorInfo>(m_Bias->GetTensorInfo());
        const TensorInfo& biasTensorInfo = optionalBiasTensorInfo.value();

        ValidateTensorDataType(biasTensorInfo, GetBiasDataType(inputTensorInfo.GetDataType()), descriptorName, "bias");
        ValidateBiasTensorQuantization(biasTensorInfo, inputTensorInfo, weightTensorInfo, descriptorName);
    }

    if (m_Parameters.m_StrideX <= 0 || m_Parameters.m_StrideY <= 0 || m_Parameters.m_StrideZ <= 0 )
    {
        throw InvalidArgumentException(
                fmt::format("{}: strideX (provided {}), strideY (provided {}) or strideZ (provided {})"
                            "cannot be either negative or 0.",
                            descriptorName, m_Parameters.m_StrideX, m_Parameters.m_StrideY, m_Parameters.m_StrideZ));
    }

    ValidatePerAxisQuantization(inputTensorInfo,
                                outputTensorInfo,
                                weightTensorInfo,
                                optionalBiasTensorInfo,
                                descriptorName);

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16,
        DataType::QSymmS8
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void DepthwiseConvolution2dQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"DepthwiseConvolution2dQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorNumDimensions(inputTensorInfo,  descriptorName, 4, "input");
    ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 4, "output");

    ValidatePointer(m_Weight, descriptorName, "weight");

    const TensorInfo& weightTensorInfo = m_Weight->GetTensorInfo();
    ValidateTensorNumDimensions(weightTensorInfo, descriptorName, 4, "weight");

    if (m_Parameters.m_DilationX < 1 || m_Parameters.m_DilationY < 1 )
    {
        throw InvalidArgumentException(
            fmt::format("{}: dilationX (provided {}) and dilationY (provided {}) "
                        "cannot be smaller than 1.",
                        descriptorName, m_Parameters.m_DilationX, m_Parameters.m_DilationX));
    }

    if (m_Parameters.m_StrideX <= 0 || m_Parameters.m_StrideY <= 0  )
    {
        throw InvalidArgumentException(
            fmt::format("{}: strideX (provided {}) and strideY (provided {}) "
                        "cannot be either negative or 0.",
                        descriptorName, m_Parameters.m_StrideX, m_Parameters.m_StrideY));
    }

    const unsigned int channelIndex = (m_Parameters.m_DataLayout == DataLayout::NCHW) ? 1 : 3;

    // Expected weight shape: [ 1, H, W, I*M ] - This shape does NOT depend on the data layout
    // inputChannels * channelMultiplier should be equal to outputChannels.
    const unsigned int numWeightOutputChannels = weightTensorInfo.GetShape()[3]; // I*M=Cout
    const unsigned int numOutputChannels       = outputTensorInfo.GetShape()[channelIndex];
    if (numWeightOutputChannels != numOutputChannels)
    {
        throw InvalidArgumentException(fmt::format(
            "{0}: The weight format in armnn is expected to be [1, H, W, Cout]."
            "But 4th dimension is not equal to Cout. Cout = {1} Provided weight shape: [{2}, {3}, {4}, {5}]",
            descriptorName,
            numOutputChannels,
            weightTensorInfo.GetShape()[0],
            weightTensorInfo.GetShape()[1],
            weightTensorInfo.GetShape()[2],
            weightTensorInfo.GetShape()[3]));
    }
    if (weightTensorInfo.GetShape()[0] != 1)
    {
        throw InvalidArgumentException(fmt::format(
                "{0}: The weight format in armnn is expected to be [1, H, W, Cout]."
                "But first dimension is not equal to 1. Provided weight shape: [{1}, {2}, {3}, {4}]",
                descriptorName,
                weightTensorInfo.GetShape()[0],
                weightTensorInfo.GetShape()[1],
                weightTensorInfo.GetShape()[2],
                weightTensorInfo.GetShape()[3]));
    }

    ValidateWeightDataType(inputTensorInfo, weightTensorInfo, descriptorName);

    Optional<TensorInfo> optionalBiasTensorInfo;
    if (m_Parameters.m_BiasEnabled)
    {
        ValidatePointer(m_Bias, descriptorName, "bias");

        optionalBiasTensorInfo = MakeOptional<TensorInfo>(m_Bias->GetTensorInfo());
        const TensorInfo& biasTensorInfo = optionalBiasTensorInfo.value();

        ValidateBiasTensorQuantization(biasTensorInfo, inputTensorInfo, weightTensorInfo, descriptorName);
        ValidateTensorDataType(biasTensorInfo, GetBiasDataType(inputTensorInfo.GetDataType()), descriptorName, "bias");
    }
    ValidatePerAxisQuantization(inputTensorInfo,
                                outputTensorInfo,
                                weightTensorInfo,
                                optionalBiasTensorInfo,
                                descriptorName);

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void PermuteQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"PermuteQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const PermutationVector& mapping = m_Parameters.m_DimMappings;

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorNumDimensions(inputTensorInfo,  descriptorName, mapping.GetSize(), "input");
    ValidateTensorNumDimensions(outputTensorInfo, descriptorName, mapping.GetSize(), "output");

    for (unsigned int i = 0u; i < mapping.GetSize(); ++i)
    {
        if (inputTensorInfo.GetShape()[i] != outputTensorInfo.GetShape()[mapping[i]])
        {
            throw InvalidArgumentException(descriptorName + ": src dimension " + to_string(i) +
                                           " (=" + to_string(inputTensorInfo.GetShape()[i]) + ") " +
                                           "must match dst dimension " + to_string(mapping[i]) +
                                           " (=" + to_string(outputTensorInfo.GetShape()[mapping[i]]) + ")");
        }
    }

    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void Pooling2dQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"Pooling2dQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorNumDimensions(inputTensorInfo,  descriptorName, 4, "input");
    ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 4, "output");

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::Float16,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void ResizeBilinearQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"ResizeBilinearQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorNumDimensions(inputTensorInfo,  descriptorName, 4, "input");
    ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 4, "output");

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");

    // ResizeBilinear only changes width and height: batch and channel count must match.
    const unsigned int inputBatchSize  = inputTensorInfo.GetShape()[0];
    const unsigned int outputBatchSize = outputTensorInfo.GetShape()[0];
    if (inputBatchSize != outputBatchSize)
    {
        throw InvalidArgumentException(
            fmt::format("{}: Input batch size ({}) does not match output batch size ({})",
                        descriptorName, inputBatchSize, outputBatchSize));
    }

    DataLayoutIndexed dimensionIndices(m_Parameters.m_DataLayout);
    const unsigned int inputChannelCount  = inputTensorInfo.GetShape()[dimensionIndices.GetChannelsIndex()];
    const unsigned int outputChannelCount = outputTensorInfo.GetShape()[dimensionIndices.GetChannelsIndex()];
    if (inputChannelCount != outputChannelCount)
    {
        throw InvalidArgumentException(
            fmt::format("{}: Input channel count ({}) does not match output channel count ({})",
                        descriptorName, inputChannelCount, outputChannelCount));
    }
}

void ResizeQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"ResizeQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorNumDimensions(inputTensorInfo,  descriptorName, 4, "input");
    ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 4, "output");

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");

    // Resize only changes width and height: batch and channel count must match.
    const unsigned int inputBatchSize  = inputTensorInfo.GetShape()[0];
    const unsigned int outputBatchSize = outputTensorInfo.GetShape()[0];
    if (inputBatchSize != outputBatchSize)
    {
        throw InvalidArgumentException(
                fmt::format("{}: Input batch size ({}) does not match output batch size ({})",
                            descriptorName, inputBatchSize, outputBatchSize));
    }

    DataLayoutIndexed dimensionIndices(m_Parameters.m_DataLayout);
    const unsigned int inputChannelCount  = inputTensorInfo.GetShape()[dimensionIndices.GetChannelsIndex()];
    const unsigned int outputChannelCount = outputTensorInfo.GetShape()[dimensionIndices.GetChannelsIndex()];
    if (inputChannelCount != outputChannelCount)
    {
        throw InvalidArgumentException(
                fmt::format("{}: Input channel count ({}) does not match output channel count ({})",
                            descriptorName, inputChannelCount, outputChannelCount));
    }
}

void FakeQuantizationQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"FakeQuantizationQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorNumDimensions(inputTensorInfo,  descriptorName, 2, "input");
    ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 2, "output");

    ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo,  descriptorName, "input", "output");

    if (m_Parameters.m_Min > m_Parameters.m_Max)
    {
        throw InvalidArgumentException(descriptorName + ": min cannot be greater than max");
    }
}

void InstanceNormalizationQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"InstanceNormalizationQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    if (inputTensorInfo.GetNumDimensions() > 4)
    {
        throw InvalidArgumentException(descriptorName + ": Input tensors with rank greater than 4 are not supported.");
    }

    ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");

    // Check the supported data types
    std::vector<DataType> supportedTypes =
        {
            DataType::BFloat16,
            DataType::Float32,
            DataType::Float16
        };

    ValidateDataTypes(inputTensorInfo,  supportedTypes, descriptorName);
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void L2NormalizationQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"L2NormalizationQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    if (inputTensorInfo.GetNumDimensions() > 4)
    {
        throw InvalidArgumentException(descriptorName + ": Input tensors with rank greater than 4 are not supported.");
    }

    ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");

    // Check the supported data types
    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::Float16,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputTensorInfo,  supportedTypes, descriptorName);
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void LogSoftmaxQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"LogSoftmaxQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::Float16,
    };

    ValidateDataTypes(inputTensorInfo,  supportedTypes, descriptorName);
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void ConstantQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"ConstantQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 0);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    if (!m_LayerOutput)
    {
        throw InvalidArgumentException(descriptorName + ": No const input specified.");
    }

    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];
    ValidateTensorShapesMatch(m_LayerOutput->GetTensorInfo(), outputTensorInfo, descriptorName, "constant", "output");

    // Check the supported data types
    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::Float16,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS8,
        DataType::QSymmS16,
        DataType::Signed32
    };

    ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
}

void ReshapeQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"ReshapeQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorNumElementsMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");

    // Check the supported data types
    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::Float16,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16,
        DataType::Signed32,
        DataType::Boolean
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void SpaceToBatchNdQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"SpaceToBatchNdQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorNumDimensions(inputTensorInfo,  descriptorName, 4, "input");
    ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 4, "output");

    if (m_Parameters.m_BlockShape.size() != 2)
    {
        throw InvalidArgumentException(descriptorName + ": Block Shape must contain 2 spatial dimensions.");
    }

    if (m_Parameters.m_BlockShape.size() != m_Parameters.m_PadList.size())
    {
        throw InvalidArgumentException(descriptorName + ": Pad List must contain the same number of "
                                       "dimensions as Block Shape.");
    }

    const TensorShape& inputShape = inputTensorInfo.GetShape();

    std::pair<unsigned int, unsigned int> heightPad = m_Parameters.m_PadList[0];
    std::pair<unsigned int, unsigned int> widthPad  = m_Parameters.m_PadList[1];

    DataLayoutIndexed dimensionIndices(m_Parameters.m_DataLayout);

    const unsigned int inputWidth  = inputShape[dimensionIndices.GetWidthIndex()] +
                                     widthPad.first + widthPad.second;
    const unsigned int inputHeight = inputShape[dimensionIndices.GetHeightIndex()] +
                                     heightPad.first + heightPad.second;

    const unsigned int numInputElements  = inputShape[0] * inputHeight * inputWidth *
                                           inputShape[dimensionIndices.GetChannelsIndex()];
    const unsigned int numOutputElements = outputTensorInfo.GetNumElements();

    if (numOutputElements != numInputElements)
    {
        throw InvalidArgumentException(descriptorName + ": Input tensor has " +
            to_string(numInputElements) + " after padding but output tensor has " +
            to_string(numOutputElements) + " elements.");
    }

    if (inputHeight % m_Parameters.m_BlockShape[0] != 0 || inputWidth % m_Parameters.m_BlockShape[1] != 0)
    {
        throw InvalidArgumentException(descriptorName + ": Input shape after padding must be "
                                       "divisible by Block Shape in all spatial dimensions");
    }

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void SpaceToDepthQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"SpaceToDepthQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorNumDimensions(inputTensorInfo,  descriptorName, 4, "input");
    ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 4, "output");

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::Float16,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputTensorInfo,  supportedTypes, descriptorName);
    ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);

    ValidateTensorNumElementsMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");

    if (m_Parameters.m_BlockSize == 0)
    {
        throw InvalidArgumentException(descriptorName + ": Block size cannot be 0.");
    }

    DataLayoutIndexed dimensionIndices(m_Parameters.m_DataLayout);
    const unsigned int wIndex = dimensionIndices.GetWidthIndex();
    const unsigned int hIndex = dimensionIndices.GetHeightIndex();
    const unsigned int cIndex = dimensionIndices.GetChannelsIndex();

    const TensorShape& inputShape = inputTensorInfo.GetShape();
    if (inputShape[hIndex] % m_Parameters.m_BlockSize != 0 || inputShape[wIndex]  % m_Parameters.m_BlockSize != 0)
    {
        throw InvalidArgumentException(descriptorName + ": Input shape must be divisible "
                                       "by block size in all spatial dimensions");
    }

    const TensorShape& outputShape = outputTensorInfo.GetShape();
    if (outputShape[cIndex] % (m_Parameters.m_BlockSize * m_Parameters.m_BlockSize) != 0)
    {
        throw InvalidArgumentException(descriptorName + ": The depth of the output tensor"
                                       "must be divisible by the square of block size." );
    }
}

void FloorQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"FloorQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::Float16,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputTensorInfo,  supportedTypes, descriptorName);
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
    ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
    ValidateTensorQuantizationSpace(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void LstmQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    // ported from android/ml/nn/common/operations/LSTM.cpp CheckInputTensorDimensions()

    const std::string descriptorName{"LstmQueueDescriptor"};

    // check dimensions of all inputs and outputs
    if (workloadInfo.m_InputTensorInfos.size() != 3)
    {
        throw InvalidArgumentException(descriptorName + ": Invalid number of inputs.");
    }
    if (workloadInfo.m_OutputTensorInfos.size() != 4)
    {
        throw InvalidArgumentException(descriptorName + ": Invalid number of outputs.");
    }

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QSymmS16
    };

    // check for supported type of one input and match them with all the other input and output
    ValidateDataTypes(workloadInfo.m_InputTensorInfos[0], supportedTypes, descriptorName);

    // type matches all other inputs
    for (uint32_t i = 1u; i < workloadInfo.m_InputTensorInfos.size(); ++i)
    {
        ValidateTensorDataTypesMatch(workloadInfo.m_InputTensorInfos[0],
                                     workloadInfo.m_InputTensorInfos[i],
                                     descriptorName,
                                     "input_0",
                                     "input_" + std::to_string(i));
    }
    // type matches all other outputs
    for (uint32_t i = 0u; i < workloadInfo.m_OutputTensorInfos.size(); ++i)
    {
        ValidateTensorDataTypesMatch(workloadInfo.m_InputTensorInfos[0],
                                     workloadInfo.m_OutputTensorInfos[i],
                                     "LstmQueueDescriptor",
                                     "input_0",
                                     "output_" + std::to_string(i));
    }

    // Making sure clipping parameters have valid values.
    // == 0 means no clipping
    //  > 0 means clipping
    if (m_Parameters.m_ClippingThresCell < 0.0f)
    {
        throw InvalidArgumentException(descriptorName + ": negative cell clipping threshold is invalid");
    }
    if (m_Parameters.m_ClippingThresProj < 0.0f)
    {
        throw InvalidArgumentException(descriptorName + ": negative projection clipping threshold is invalid");
    }

    // Inferring batch size, number of outputs and number of cells from the inputs.
    const uint32_t n_input = workloadInfo.m_InputTensorInfos[0].GetShape()[1];
    const uint32_t n_batch = workloadInfo.m_InputTensorInfos[0].GetShape()[0];
    ValidatePointer(m_InputToOutputWeights, "Null pointer check", "InputToOutputWeights");
    const uint32_t n_cell = m_InputToOutputWeights->GetShape()[0];
    ValidatePointer(m_RecurrentToOutputWeights, "Null pointer check", "RecurrentToOutputWeights");
    const uint32_t n_output = m_RecurrentToOutputWeights->GetShape()[1];

    // input tensor
    ValidateTensorNumDimNumElem(workloadInfo.m_InputTensorInfos[0], 2, (n_batch * n_input),
                                descriptorName + " input_0");
    // outputStateInTensor
    ValidateTensorNumDimNumElem(workloadInfo.m_InputTensorInfos[1], 2, (n_batch * n_output),
                                descriptorName + " input_1");
    // outputStateInTensor
    ValidateTensorNumDimNumElem(workloadInfo.m_InputTensorInfos[2], 2, (n_batch * n_cell),
                                descriptorName + " input_2");
    // scratchBufferTensor
    unsigned int scratchBufferSize = m_Parameters.m_CifgEnabled ? n_cell * 3 : n_cell * 4;
    ValidateTensorNumDimNumElem(workloadInfo.m_OutputTensorInfos[0], 2, (n_batch * scratchBufferSize),
                                descriptorName + " output_0");
    // outputStateOutTensor
    ValidateTensorNumDimNumElem(workloadInfo.m_OutputTensorInfos[1], 2, (n_batch * n_output),
                                descriptorName + " output_1");
    // cellStateOutTensor
    ValidateTensorNumDimNumElem(workloadInfo.m_OutputTensorInfos[2], 2, (n_batch * n_cell),
                                descriptorName + " output_2");
    // outputTensor
    ValidateTensorNumDimNumElem(workloadInfo.m_OutputTensorInfos[3], 2, (n_batch * n_output),
                                descriptorName + " output_3");

    // check that dimensions of inputs/outputs and QueueDescriptor data match with each other
    if ( m_InputToInputWeights )
    {
        ValidateTensorNumDimNumElem(m_InputToInputWeights->GetTensorInfo(), 2,
                                      (n_cell * n_input), "InputLayerNormWeights");
    }

    ValidatePointer(m_InputToForgetWeights, "Null pointer check", "InputToForgetWeights");
    ValidateTensorNumDimNumElem(m_InputToForgetWeights->GetTensorInfo(), 2,
                                  (n_cell * n_input), "InputToForgetWeights");

    ValidatePointer(m_InputToCellWeights, "Null pointer check", "InputToCellWeights");
    ValidateTensorNumDimNumElem(m_InputToCellWeights->GetTensorInfo(), 2,
                                  (n_cell * n_input), "InputToCellWeights");

    if ( m_RecurrentToInputWeights )
    {
        ValidateTensorNumDimNumElem(m_RecurrentToInputWeights->GetTensorInfo(), 2,
                                      (n_cell * n_output), "RecurrentToInputWeights");
    }

    ValidatePointer(m_RecurrentToForgetWeights, "Null pointer check", "RecurrentToForgetWeights");
    ValidateTensorNumDimNumElem(m_RecurrentToForgetWeights->GetTensorInfo(), 2,
                                  (n_cell * n_output), "RecurrentToForgetWeights");

    ValidatePointer(m_RecurrentToCellWeights, "Null pointer check", "RecurrentToCellWeights");
    ValidateTensorNumDimNumElem(m_RecurrentToCellWeights->GetTensorInfo(), 2,
                                  (n_cell * n_output), "RecurrentToCellWeights");

    // Make sure the input-gate's parameters are either both present (regular
    // LSTM) or not at all (CIFG-LSTM). And CifgEnable is set accordingly.
    bool cifg_weights_all_or_none = ((m_InputToInputWeights && m_RecurrentToInputWeights &&
                                     !m_Parameters.m_CifgEnabled) ||
                                     (!m_InputToInputWeights && !m_RecurrentToInputWeights &&
                                     m_Parameters.m_CifgEnabled));
    if (!cifg_weights_all_or_none)
    {
        throw InvalidArgumentException(descriptorName + ": Input-Gate's parameters InputToInputWeights and "
                                       "RecurrentToInputWeights must either both be present (regular LSTM) "
                                       "or both not present (CIFG-LSTM). In addition CifgEnable must be set "
                                       "accordingly.");
    }

    if ( m_CellToInputWeights )
    {
        ValidateTensorNumDimNumElem(m_CellToInputWeights->GetTensorInfo(), 1,
                                      n_cell, "CellToInputWeights");
    }
    if ( m_CellToForgetWeights )
    {
        ValidateTensorNumDimNumElem(m_CellToForgetWeights->GetTensorInfo(), 1,
                                      n_cell, "CellToForgetWeights");
    }
    if ( m_CellToOutputWeights )
    {
        ValidateTensorNumDimNumElem(m_CellToOutputWeights->GetTensorInfo(), 1,
                                      n_cell, "CellToOutputWeights");
    }

    // Making sure the peephole weights are there all or none. And PeepholeEnable is set accordingly.
    bool peephole_weights_all_or_none =
            (((m_CellToInputWeights || m_Parameters.m_CifgEnabled) &&  m_CellToForgetWeights
            && m_CellToOutputWeights && m_Parameters.m_PeepholeEnabled)
            || ( !m_CellToInputWeights && !m_CellToForgetWeights
            && !m_CellToOutputWeights && !m_Parameters.m_PeepholeEnabled));
    if (!peephole_weights_all_or_none)
    {
        throw InvalidArgumentException(descriptorName + ": Invalid combination of peephole parameters.");
    }

    // Make sure the input gate bias is present only when not a CIFG-LSTM.
    if (m_Parameters.m_CifgEnabled)
    {
        if (m_InputGateBias)
        {
            throw InvalidArgumentException(descriptorName + ": InputGateBias is present and CIFG-LSTM is enabled.");
        }
    }
    else
    {
        if (!m_InputGateBias)
        {
            throw InvalidArgumentException(descriptorName + ": If CIFG-LSTM is disabled InputGateBias "
                                           "must be present.");
        }
        ValidateTensorNumDimNumElem(m_InputGateBias->GetTensorInfo(), 1,
                                      n_cell, "InputGateBias");
    }

    ValidatePointer(m_ForgetGateBias, "Null pointer check", "ForgetGateBias");
    ValidateTensorNumDimNumElem(m_ForgetGateBias->GetTensorInfo(), 1, n_cell, "ForgetGateBias");

    ValidatePointer(m_CellBias, "Null pointer check", "CellBias");
    ValidateTensorNumDimNumElem(m_CellBias->GetTensorInfo(), 1, n_cell, "CellBias");

    ValidatePointer(m_OutputGateBias, "Null pointer check", "OutputGateBias");
    ValidateTensorNumDimNumElem(m_OutputGateBias->GetTensorInfo(), 1, n_cell, "OutputGateBias");

    if (m_ProjectionWeights)
    {
        ValidateTensorNumDimNumElem(m_ProjectionWeights->GetTensorInfo(), 2,
                                      (n_cell * n_output), "ProjectionWeights");
    }
    if (m_ProjectionBias)
    {
        ValidateTensorNumDimNumElem(m_ProjectionBias->GetTensorInfo(), 1, n_output, "ProjectionBias");
    }

    // Making sure the projection tensors are consistent:
    // 1) If projection weight is not present, then projection bias should not be
    // present.
    // 2) If projection weight is present, then projection bias is optional.
    bool projecton_tensors_consistent = ((!m_ProjectionWeights && !m_ProjectionBias &&
                                        !m_Parameters.m_ProjectionEnabled)
                                        || (m_ProjectionWeights && !m_ProjectionBias &&
                                        m_Parameters.m_ProjectionEnabled)
                                        || (m_ProjectionWeights && m_ProjectionBias &&
                                        m_Parameters.m_ProjectionEnabled));
    if (!projecton_tensors_consistent)
    {
        throw InvalidArgumentException(descriptorName + ": Projection tensors are inconsistent.");
    }

    // The four layer normalization weights either all have values or none of them have values. Additionally, if
    // CIFG is used, input layer normalization weights tensor is omitted and the other layer normalization weights
    // either all have values or none of them have values. Layer normalization is used when the values of all the
    // layer normalization weights are present
    if (m_InputLayerNormWeights)
    {
        ValidateTensorNumDimNumElem(m_InputLayerNormWeights->GetTensorInfo(), 1, n_cell, "InputLayerNormWeights");
    }
    if (m_ForgetLayerNormWeights)
    {
        ValidateTensorNumDimNumElem(m_ForgetLayerNormWeights->GetTensorInfo(), 1, n_cell, "ForgetLayerNormWeights");
    }
    if (m_CellLayerNormWeights)
    {
        ValidateTensorNumDimNumElem(m_CellLayerNormWeights->GetTensorInfo(), 1, n_cell, "CellLayerNormWeights");
    }
    if (m_OutputLayerNormWeights)
    {
        ValidateTensorNumDimNumElem(m_OutputLayerNormWeights->GetTensorInfo(), 1, n_cell, "OutputLayerNormWeights");
    }

    if (m_Parameters.m_LayerNormEnabled)
    {
        if (!m_Parameters.m_CifgEnabled)
        {
            if (!m_InputLayerNormWeights)
            {
                throw InvalidArgumentException(descriptorName + ": Layer normalisation is enabled and CIFG-LSTM is "
                                               "disabled but InputLayerNormWeights are not present");
            }
            ValidateTensorNumDimNumElem(m_InputLayerNormWeights->GetTensorInfo(),
                                          1, n_cell, "InputLayerNormWeights");
        }
        else if (m_InputLayerNormWeights)
        {
            throw InvalidArgumentException(descriptorName + ":InputLayerNormWeights are present while CIFG is "
                                           "enabled");
        }

        ValidatePointer(m_ForgetLayerNormWeights, "Null pointer check layer normalisation enabled",
                        "ForgetLayerNormWeights");
        ValidateTensorNumDimNumElem(m_ForgetLayerNormWeights->GetTensorInfo(), 1, n_cell, "ForgetLayerNormWeights");

        ValidatePointer(m_OutputLayerNormWeights, "Null pointer check layer normalisation enabled",
                        "OutputLayerNormWeights");
        ValidateTensorNumDimNumElem(m_OutputLayerNormWeights->GetTensorInfo(), 1, n_cell, "OutputLayerNormWeights");

        ValidatePointer(m_CellLayerNormWeights, "Null pointer check layer normalisation enabled",
                        "CellLayerNormWeights");
        ValidateTensorNumDimNumElem(m_CellLayerNormWeights->GetTensorInfo(), 1, n_cell, "CellLayerNormWeights");
    }
    else if (m_InputLayerNormWeights || m_ForgetLayerNormWeights || m_OutputLayerNormWeights || m_CellLayerNormWeights)
    {
        throw InvalidArgumentException(descriptorName + ": Layer normalisation is disabled but one or more layer "
                                       "normalisation weights are present.");
    }
}

void ConvertBf16ToFp32QueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"ConvertBf16ToFp32QueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    if (inputTensorInfo.GetDataType() != DataType::BFloat16)
    {
        throw InvalidArgumentException(descriptorName + ": Input tensor type must be BFloat16.");
    }

    if (outputTensorInfo.GetDataType() != DataType::Float32)
    {
        throw InvalidArgumentException(descriptorName + ": Output tensor type must be Float32.");
    }

    ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void ConvertFp32ToBf16QueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"ConvertFp32ToBf16QueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    if (inputTensorInfo.GetDataType() != DataType::Float32)
    {
        throw InvalidArgumentException(descriptorName + ": Input tensor type must be Float32.");
    }

    if (outputTensorInfo.GetDataType() != DataType::BFloat16)
    {
        throw InvalidArgumentException(descriptorName + ": Output tensor type must be BFloat16.");
    }

    ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void ConvertFp32ToFp16QueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"ConvertFp32ToFp16QueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    if (inputTensorInfo.GetDataType() != DataType::Float32)
    {
        throw InvalidArgumentException(descriptorName + ": Input tensor type must be Float32.");
    }

    if (outputTensorInfo.GetDataType() != DataType::Float16)
    {
        throw InvalidArgumentException(descriptorName + ": Output tensor type must be Float16.");
    }

    ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void ConvertFp16ToFp32QueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"ConvertFp16ToFp32QueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    if (inputTensorInfo.GetDataType() != DataType::Float16)
    {
        throw InvalidArgumentException(descriptorName + ": Input tensor type must be Float16.");
    }

    if (outputTensorInfo.GetDataType() != DataType::Float32)
    {
        throw InvalidArgumentException(descriptorName + ": Output tensor type must be Float32.");
    }

    ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void DivisionQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"DivisionQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 2);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16,
        DataType::Signed32
    };

    ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
    ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
    ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);

    ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
                                       inputTensorInfo1,
                                       outputTensorInfo,
                                       descriptorName,
                                       "input_0",
                                       "input_1");
}

void SubtractionQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"SubtractionQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 2);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16,
        DataType::Signed32,
    };

    ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
    ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
    ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);

    ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
                                       inputTensorInfo1,
                                       outputTensorInfo,
                                       descriptorName,
                                       "input_0",
                                       "input_1");
}

void MaximumQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"MaximumQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 2);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16,
        DataType::Signed32
    };

    ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
    ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
    ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);

    ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
                                       inputTensorInfo1,
                                       outputTensorInfo,
                                       descriptorName,
                                       "input_0",
                                       "input_1");
}

void MeanQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"MeanQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::Float16,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    // First check if input tensor data type is supported, then
    // check if this data type matches the output tensor data type
    ValidateDataTypes(inputTensorInfo,  supportedTypes, descriptorName);
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");

    if (m_Parameters.m_KeepDims)
    {
        ValidateTensorNumDimensions(outputTensorInfo, descriptorName, inputTensorInfo.GetNumDimensions(), "output");
    }
    else if (m_Parameters.m_Axis.empty())
    {
        ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 1, "output");
    }
    else
    {
        unsigned int outputDim =
            inputTensorInfo.GetNumDimensions() - armnn::numeric_cast<unsigned int>(m_Parameters.m_Axis.size());
        ValidateTensorNumDimensions(outputTensorInfo,
                                    descriptorName,
                                    outputDim > 0 ? outputDim : 1,
                                    "output");
    }
}

void PadQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"PadQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    // input and output should have the same number of dimensions
    ValidateTensorNumDimensions(outputTensorInfo, descriptorName, inputTensorInfo.GetNumDimensions(), "output");

    // there should be entry in the pad list for each dimension in the input tensor
    if (m_Parameters.m_PadList.size() != inputTensorInfo.GetNumDimensions()) {
        throw InvalidArgumentException(descriptorName + ":Pad List should contain the same number of entries "
                                       "as there are dimensions in the input tensor that is " +
                                       std::to_string(inputTensorInfo.GetNumDimensions()) + " entries " +
                                       " not " + std::to_string(m_Parameters.m_PadList.size()) + " entries.");
    }
}

void QuantizeQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"QuantizeQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::Float16,
        DataType::QSymmS8,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);

    if (!IsQuantizedType(outputTensorInfo.GetDataType()))
    {
        throw InvalidArgumentException(descriptorName + ": Output of quantized layer must be quantized type.");
    }
}

void BatchToSpaceNdQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"BatchToSpaceNdQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::Float16,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void StridedSliceQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"StridedSliceQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");

    ValidateTensorQuantizationSpace(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");

    const uint32_t rank = inputTensorInfo.GetNumDimensions();
    if (rank > 4)
    {
        throw InvalidArgumentException(descriptorName + ": Input tensors with rank greater than 4 are not supported.");
    }

    // Begin, End & Stride length must be of rank(input0)
    if (m_Parameters.m_Begin.size() != rank)
    {
        throw InvalidArgumentException(descriptorName + ": Begin length must be of rank " + std::to_string(rank));
    }

    if (m_Parameters.m_End.size() != rank)
    {
        throw InvalidArgumentException(descriptorName + ": End length must be of rank " + std::to_string(rank));
    }

    if (m_Parameters.m_Stride.size() != rank)
    {
        throw InvalidArgumentException(descriptorName + ": Stride length must be of rank " + std::to_string(rank));
    }

    // Stride entries must be non-zero
    for (auto& stride : m_Parameters.m_Stride)
    {
        if (stride == 0)
        {
            throw InvalidArgumentException(descriptorName + ": Stride entries must be non-zero.");
        }
    }
}

void MinimumQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"MinimumQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 2);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16,
        DataType::Signed32
    };

    ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
    ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);
    ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);

    ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
                                       inputTensorInfo1,
                                       outputTensorInfo,
                                       descriptorName,
                                       "input_0",
                                       "input_1");
}

void DebugQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"DebugQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);
}

void EqualQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"EqualQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 2);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
                                       inputTensorInfo1,
                                       outputTensorInfo,
                                       descriptorName,
                                       "input_0",
                                       "input_1");

    if (outputTensorInfo.GetDataType() != DataType::Boolean)
    {
        throw InvalidArgumentException(descriptorName + ": Output tensor type must be Boolean.");
    }
}

void GreaterQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"GreaterQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 2);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
                                       inputTensorInfo1,
                                       outputTensorInfo,
                                       descriptorName,
                                       "input_0",
                                       "input_1");

    if (outputTensorInfo.GetDataType() != DataType::Boolean)
    {
        throw InvalidArgumentException(descriptorName + ": Output tensor type must be Boolean.");
    }
}

void RsqrtQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"RsqrtQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void GatherQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"GatherQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 2);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& indicesTensorInfo = workloadInfo.m_InputTensorInfos[1];
    if (indicesTensorInfo.GetDataType() != DataType::Signed32)
    {
        throw InvalidArgumentException(descriptorName + ": Indices tensor type must be Int32.");
    }

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16,
        DataType::Signed32,
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);

    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");

    unsigned int outputDim  = inputTensorInfo.GetNumDimensions() + indicesTensorInfo.GetNumDimensions() - 1;
    ValidateTensorNumDimensions(outputTensorInfo, descriptorName, outputDim, "output");
}

void DetectionPostProcessQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string& descriptorName{"DetectionPostProcessQueueDescriptor"};

    ValidateNumInputs(workloadInfo, descriptorName, 2);

    if (workloadInfo.m_OutputTensorInfos.size() != 4)
    {
        throw InvalidArgumentException(descriptorName + ": Requires exactly four outputs. " +
                                       to_string(workloadInfo.m_OutputTensorInfos.size()) + " has been provided.");
    }

    if (m_Anchors == nullptr)
    {
        throw InvalidArgumentException(descriptorName + ": Anchors tensor descriptor is missing.");
    }

    const TensorInfo& boxEncodingsInfo =  workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& scoresInfo       =  workloadInfo.m_InputTensorInfos[1];
    const TensorInfo& anchorsInfo      = m_Anchors->GetTensorInfo();

    const TensorInfo& detectionBoxesInfo   = workloadInfo.m_OutputTensorInfos[0];
    const TensorInfo& detectionClassesInfo = workloadInfo.m_OutputTensorInfos[1];
    const TensorInfo& detectionScoresInfo  = workloadInfo.m_OutputTensorInfos[2];
    const TensorInfo& numDetectionsInfo    = workloadInfo.m_OutputTensorInfos[3];

    ValidateTensorNumDimensions(boxEncodingsInfo, descriptorName, 3, "box encodings");
    ValidateTensorNumDimensions(scoresInfo, descriptorName, 3, "scores");
    ValidateTensorNumDimensions(anchorsInfo, descriptorName, 2, "anchors");

    const std::vector<DataType> supportedInputTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::Float16,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(boxEncodingsInfo, supportedInputTypes, descriptorName);
    ValidateDataTypes(scoresInfo, supportedInputTypes, descriptorName);
    ValidateDataTypes(anchorsInfo, supportedInputTypes, descriptorName);

    ValidateTensorNumDimensions(detectionBoxesInfo, descriptorName, 3, "detection boxes");
    ValidateTensorNumDimensions(detectionScoresInfo, descriptorName, 2, "detection scores");
    ValidateTensorNumDimensions(detectionClassesInfo, descriptorName, 2, "detection classes");
    ValidateTensorNumDimensions(numDetectionsInfo, descriptorName, 1, "num detections");

    // NOTE: Output is always Float32 regardless of input type
    ValidateTensorDataType(detectionBoxesInfo, DataType::Float32, descriptorName, "detection boxes");
    ValidateTensorDataType(detectionScoresInfo, DataType::Float32, descriptorName, "detection scores");
    ValidateTensorDataType(detectionClassesInfo, DataType::Float32, descriptorName, "detection classes");
    ValidateTensorDataType(numDetectionsInfo, DataType::Float32, descriptorName, "num detections");

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

    if (scoresInfo.GetShape()[2] != m_Parameters.m_NumClasses + 1)
    {
        throw InvalidArgumentException(descriptorName + ": Number of classes with background "
                                       "should be equal to number of classes + 1.");
    }
}

void DequantizeQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string& descriptorName{"DequantizeQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    if (!IsQuantizedType(inputTensorInfo.GetDataType()))
    {
        throw InvalidArgumentException(descriptorName + ": Input to dequantize layer must be quantized type.");
    }

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::Float16
    };

    ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);
}

void MergeQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string& descriptorName{"MergeQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 2);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorShapesMatch(inputTensorInfo0, inputTensorInfo1, descriptorName, "input_0", "input_1");
    ValidateTensorShapesMatch(inputTensorInfo0, outputTensorInfo, descriptorName, "input_0", "output");

    ValidateTensorDataTypesMatch(inputTensorInfo0, inputTensorInfo1, descriptorName, "input_0", "input_1");
    ValidateTensorDataTypesMatch(inputTensorInfo0, outputTensorInfo, descriptorName, "input_0", "output");
}

void ShapeQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string& descriptorName{"ShapeQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QAsymmS8,
        DataType::QSymmS8,
        DataType::QSymmS16,
        DataType::Signed32
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
    ValidateDataTypes(outputTensorInfo, {DataType::Signed32}, descriptorName);
}

void SwitchQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string& descriptorName{"SwitchQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 2);
    ValidateNumOutputs(workloadInfo, descriptorName, 2);

    const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];

    const TensorInfo& outputTensorInfo0 = workloadInfo.m_OutputTensorInfos[0];
    const TensorInfo& outputTensorInfo1 = workloadInfo.m_OutputTensorInfos[1];

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputTensorInfo0, supportedTypes, descriptorName);
    ValidateDataTypes(inputTensorInfo1, supportedTypes, descriptorName);

    ValidateDataTypes(outputTensorInfo0, supportedTypes, descriptorName);
    ValidateDataTypes(outputTensorInfo1, supportedTypes, descriptorName);

    ValidateTensorShapesMatch(inputTensorInfo0,
                              outputTensorInfo0,
                              descriptorName,
                              "input_0",
                              "output_0");

    ValidateTensorShapesMatch(inputTensorInfo0,
                              outputTensorInfo1,
                              descriptorName,
                              "input_0",
                              "output_1");
}

void PreCompiledQueueDescriptor::Validate(const WorkloadInfo& /*workloadInfo*/) const
{
    // This is internally generated so it should not need validation.
}

void PreluQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string& descriptorName{"PreluQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 2);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& alphaTensorInfo  = workloadInfo.m_InputTensorInfos[1];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    std::vector<DataType> supportedTypes
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
    ValidateDataTypes(alphaTensorInfo, supportedTypes, descriptorName);

    ValidateDataTypes(outputTensorInfo, supportedTypes, descriptorName);

    ValidateTensorDataTypesMatch(inputTensorInfo, alphaTensorInfo,  descriptorName, "input", "alpha");
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "ouptut");

    ValidateBroadcastTensorShapesMatch(inputTensorInfo,
                                       alphaTensorInfo,
                                       outputTensorInfo,
                                       descriptorName,
                                       "input",
                                       "alpha");
}

void TransposeConvolution2dQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"TransposeConvolution2dQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorNumDimensions(inputTensorInfo,  descriptorName, 4, "input");
    ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 4, "output");

    ValidatePointer(m_Weight, descriptorName, "weight");

    const TensorInfo& weightTensorInfo = m_Weight->GetTensorInfo();
    ValidateTensorNumDimensions(weightTensorInfo, descriptorName, 4, "weight");

    ValidateWeightDataType(inputTensorInfo, weightTensorInfo, descriptorName);

    Optional<TensorInfo> optionalBiasTensorInfo;
    if (m_Parameters.m_BiasEnabled)
    {
        ValidatePointer(m_Bias, descriptorName, "bias");

        optionalBiasTensorInfo = MakeOptional<TensorInfo>(m_Bias->GetTensorInfo());
        const TensorInfo& biasTensorInfo = optionalBiasTensorInfo.value();

        ValidateTensorDataType(biasTensorInfo, GetBiasDataType(inputTensorInfo.GetDataType()), descriptorName, "bias");
        ValidateBiasTensorQuantization(biasTensorInfo, inputTensorInfo, weightTensorInfo, descriptorName);
    }

    ValidatePerAxisQuantization(inputTensorInfo,
                                outputTensorInfo,
                                weightTensorInfo,
                                optionalBiasTensorInfo,
                                descriptorName);

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::Float16,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void TransposeQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"TransposeQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const PermutationVector& mapping = m_Parameters.m_DimMappings;

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorNumDimensions(inputTensorInfo,  descriptorName, mapping.GetSize(), "input");
    ValidateTensorNumDimensions(outputTensorInfo, descriptorName, mapping.GetSize(), "output");

    for (unsigned int i = 0u; i < mapping.GetSize(); ++i)
    {
        if (inputTensorInfo.GetShape()[mapping[i]] != outputTensorInfo.GetShape()[i])
        {
            throw InvalidArgumentException(descriptorName + ": src dimension " + to_string(mapping[i]) +
                                           " (=" + to_string(inputTensorInfo.GetShape()[mapping[i]]) + ") " +
                                           "must match dst dimension " + to_string(i) +
                                           " (=" + to_string(outputTensorInfo.GetShape()[i]) + ")");
        }
    }

    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void ChannelShuffleQueueDescriptor::Validate(const WorkloadInfo &workloadInfo) const
{
    const std::string descriptorName{"TransposeQueueDescriptor"};

    ValidateNumInputs(workloadInfo, descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void QLstmQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"QLstmQueueDescriptor"};

    // Validate number of inputs/outputs
    ValidateNumInputs(workloadInfo,  descriptorName, 3);
    ValidateNumOutputs(workloadInfo, descriptorName, 3);

    // Input/output tensor info
    auto inputInfo = workloadInfo.m_InputTensorInfos[0];
    auto outputStateInInfo = workloadInfo.m_InputTensorInfos[1];
    auto cellStateInInfo = workloadInfo.m_InputTensorInfos[2];

    auto outputStateOutInfo = workloadInfo.m_OutputTensorInfos[0];
    auto cellStateOutInfo = workloadInfo.m_OutputTensorInfos[1];
    auto outputInfo = workloadInfo.m_OutputTensorInfos[2];

    // Supported types for various tensors in QLSTM
    std::vector<DataType> inputOutputSupportedTypes =
    {
        DataType::QAsymmS8
    };

    std::vector<DataType> cellStateSupportedTypes =
    {
        DataType::QSymmS16
    };

    std::vector<DataType> weightsSupportedTypes =
    {
        DataType::QSymmS8
    };

    std::vector<DataType> layerNormPeepholeWeightsSupportedTypes =
    {
        DataType::QSymmS16
    };

    std::vector<DataType> biasSupportedTypes =
    {
        DataType::Signed32
    };

    // Validate types of input/output tensors
    ValidateDataTypes(inputInfo, inputOutputSupportedTypes, descriptorName);
    ValidateDataTypes(outputStateInInfo, inputOutputSupportedTypes, descriptorName);
    ValidateDataTypes(cellStateInInfo, cellStateSupportedTypes, descriptorName);

    ValidateDataTypes(outputStateOutInfo, inputOutputSupportedTypes, descriptorName);
    ValidateDataTypes(cellStateOutInfo, cellStateSupportedTypes, descriptorName);
    ValidateDataTypes(outputInfo, inputOutputSupportedTypes, descriptorName);

    // Validate matching types of input/output tensors
    ValidateTensorDataTypesMatch(inputInfo, outputStateInInfo, descriptorName, "input", "outputStateIn");
    ValidateTensorDataTypesMatch(outputStateInInfo, outputStateOutInfo, descriptorName,
                                 "outputStateIn", "outputStateOut");
    ValidateTensorDataTypesMatch(cellStateInInfo, cellStateOutInfo, descriptorName, "cellStateIn", "cellStateOut");

    // Infer number of batches, number of units, input size and output size from tensor dimensions
    const uint32_t numBatches = inputInfo.GetShape()[0];
    const uint32_t inputSize  = inputInfo.GetShape()[1];
    const uint32_t outputSize = outputStateInInfo.GetShape()[1];
    const uint32_t numUnits = cellStateInInfo.GetShape()[1];

    // Validate number of dimensions and number of elements for input/output tensors
    ValidateTensorNumDimNumElem(inputInfo, 2, (numBatches * inputSize), descriptorName + " input");
    ValidateTensorNumDimNumElem(outputStateInInfo, 2, (numBatches * outputSize), descriptorName + " outputStateIn");
    ValidateTensorNumDimNumElem(cellStateInInfo, 2, (numBatches * numUnits), descriptorName + " cellStateIn");

    ValidateTensorNumDimNumElem(outputStateOutInfo, 2, (numBatches * outputSize), descriptorName + " outputStateOut");
    ValidateTensorNumDimNumElem(cellStateOutInfo, 2, (numBatches * numUnits), descriptorName + " cellStateOut");
    ValidateTensorNumDimNumElem(outputInfo, 2, (numBatches * outputSize), descriptorName + " output");

    // Validate number of dimensions and number of elements for MANDATORY weight tensors
    ValidatePointer(m_InputToForgetWeights, descriptorName, "InputToForgetWeights");
    auto inputToForgetWeightsInfo = m_InputToForgetWeights->GetTensorInfo();
    ValidateTensorNumDimNumElem(inputToForgetWeightsInfo, 2, (numUnits * inputSize), " InputToForgetWeights");

    ValidatePointer(m_InputToCellWeights, descriptorName, "InputToCellWeights");
    auto inputToCellWeightsInfo = m_InputToCellWeights->GetTensorInfo();
    ValidateTensorNumDimNumElem(inputToCellWeightsInfo, 2, (numUnits * inputSize), " InputToCellWeights");

    ValidatePointer(m_InputToOutputWeights, descriptorName, "InputToOutputWeights");
    auto inputToOutputWeightsInfo = m_InputToOutputWeights->GetTensorInfo();
    ValidateTensorNumDimNumElem(inputToOutputWeightsInfo, 2, (numUnits * inputSize), " InputToOutputWeights");

    ValidatePointer(m_RecurrentToForgetWeights, descriptorName, "RecurrentToForgetWeights");
    auto recurrentToForgetWeightsInfo = m_RecurrentToForgetWeights->GetTensorInfo();
    ValidateTensorNumDimNumElem(recurrentToForgetWeightsInfo, 2, (numUnits * outputSize),
                                " RecurrentToForgetWeights");

    ValidatePointer(m_RecurrentToCellWeights, descriptorName, "RecurrentToCellWeights");
    auto recurrentToCellWeightsInfo = m_RecurrentToCellWeights->GetTensorInfo();
    ValidateTensorNumDimNumElem(recurrentToCellWeightsInfo, 2, (numUnits * outputSize), " RecurrentToCellWeights");

    ValidatePointer(m_RecurrentToOutputWeights, descriptorName, "RecurrentToOutputWeights");
    auto recurrentToOutputWeightsInfo = m_RecurrentToOutputWeights->GetTensorInfo();
    ValidateTensorNumDimNumElem(recurrentToOutputWeightsInfo, 2, (numUnits * outputSize), " RecurrentToCellWeights");

    // Validate data types for MANDATORY weights tensors (all should match each other)
    ValidateDataTypes(inputToForgetWeightsInfo, weightsSupportedTypes, descriptorName);

    ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, inputToCellWeightsInfo, descriptorName,
                                 "inputToForgetWeights", "inputToCellWeights");
    ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, inputToOutputWeightsInfo, descriptorName,
                                 "inputToForgetWeights", "inputToOutputWeights");

    ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, recurrentToForgetWeightsInfo, descriptorName,
                                 "inputToForgetWeights", "recurrentToForgeteights");
    ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, recurrentToCellWeightsInfo, descriptorName,
                                 "inputToForgetWeights", "recurrentToCellWeights");
    ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, recurrentToOutputWeightsInfo, descriptorName,
                                 "inputToForgetWeights", "recurrentToOutputWeights");

    // Validate number of dimensions and number of elements for MANDATORY bias tensors
    ValidatePointer(m_ForgetGateBias, descriptorName, "ForgetGateBias");
    auto forgetGateBiasInfo = m_ForgetGateBias->GetTensorInfo();
    ValidateTensorNumDimNumElem(forgetGateBiasInfo, 1, numUnits, " ForgetGateBias");

    ValidatePointer(m_CellBias, descriptorName, "CellBias");
    auto cellBiasInfo = m_CellBias->GetTensorInfo();
    ValidateTensorNumDimNumElem(cellBiasInfo, 1, numUnits, " CellBias");

    ValidatePointer(m_OutputGateBias, descriptorName, "OutputGateBias");
    auto outputGateBiasInfo = m_OutputGateBias->GetTensorInfo();
    ValidateTensorNumDimNumElem(outputGateBiasInfo, 1, numUnits, " OutputGateBias");

    // Validate data types for MANDATORY bias tensors
    ValidateDataTypes(forgetGateBiasInfo, biasSupportedTypes, descriptorName);

    ValidateTensorDataTypesMatch(forgetGateBiasInfo, cellBiasInfo, descriptorName,
                                 "forgetGateBias", "cellBias");
    ValidateTensorDataTypesMatch(forgetGateBiasInfo, outputGateBiasInfo, descriptorName,
                                 "forgetGateBias", "outputGateBias");

    // Validate OPTIONAL params: CIFG (inputToInputWeights, recurrentToInputWeights, inputGateBias)
    const bool allCifgParamsPresentOrNot = ((m_InputToInputWeights && m_RecurrentToInputWeights && m_InputGateBias &&
                                             !m_Parameters.m_CifgEnabled) ||
                                            (!m_InputToInputWeights && !m_RecurrentToInputWeights &&
                                             !m_InputGateBias && m_Parameters.m_CifgEnabled));

    if (!allCifgParamsPresentOrNot)
    {
        throw InvalidArgumentException(descriptorName +
                ": InputToInputWeights, RecurrentToInputWeights and InputGateBias must either all be present "
                "(CIFG disabled) or not be present at all (CIFG enabled). m_Parameters.m_CifgEnabled should be "
                "set appropriately.");
    }

    if (!m_Parameters.m_CifgEnabled)
    {
        // Validate number of dimensions and number of elements
        auto inputToInputWeightsInfo = m_InputToInputWeights->GetTensorInfo();
        ValidateTensorNumDimNumElem(inputToInputWeightsInfo, 2, (numUnits * inputSize), " InputToInputWeights");

        auto recurrentToInputWeightsInfo = m_RecurrentToInputWeights->GetTensorInfo();
        ValidateTensorNumDimNumElem(recurrentToInputWeightsInfo, 2, (numUnits * outputSize),
                                    " RecurrentToInputWeights");

        auto inputGateBiasInfo = m_InputGateBias->GetTensorInfo();
        ValidateTensorNumDimNumElem(inputGateBiasInfo, 1, numUnits, " InputGateBias");

        // Validate data types
        ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, inputToInputWeightsInfo, descriptorName,
                                     "inputToForgetWeights", "inputToInputWeights");
        ValidateTensorDataTypesMatch(inputToForgetWeightsInfo, recurrentToInputWeightsInfo, descriptorName,
                                     "inputToForgetWeights", "recurrentToInputWeights");
        ValidateTensorDataTypesMatch(forgetGateBiasInfo, inputGateBiasInfo, descriptorName,
                                     "forgetGateBias", "inputGateBias");
    }

    // Validate OPTIONAL params: Peephole (cellToInputWeights, cellToForgetWeights, cellToOutputWeights)
    bool allPeepholeWeightsPresentOrNot =
            (((m_CellToInputWeights || m_Parameters.m_CifgEnabled) && m_CellToForgetWeights
              && m_CellToOutputWeights && m_Parameters.m_PeepholeEnabled)
             || (!m_CellToInputWeights && !m_CellToForgetWeights
                 && !m_CellToOutputWeights && !m_Parameters.m_PeepholeEnabled));

    if (!allPeepholeWeightsPresentOrNot)
    {
        throw InvalidArgumentException(descriptorName +
                ": CellToInputWeights, CellToForgetWeights and CellToOutputWeights should all be present (Peephole "
                "enabled) or not be present at all (Peephole disabled). CellToInputWeights should only be present "
                "when Peephole is enabled and CIFG is disabled. m_Parameters.m_PeepholeEnabled should be set "
                "appropriately.");
    }

    if (m_Parameters.m_PeepholeEnabled)
    {
        auto cellToForgetWeightsInfo = m_CellToForgetWeights->GetTensorInfo();
        ValidateTensorNumDimNumElem(cellToForgetWeightsInfo, 1, numUnits, " cellToForgetWeights");
        ValidateDataTypes(cellToForgetWeightsInfo, layerNormPeepholeWeightsSupportedTypes, descriptorName);

        auto cellToOutputWeightsInfo = m_CellToOutputWeights->GetTensorInfo();
        ValidateTensorNumDimNumElem(cellToOutputWeightsInfo, 1, numUnits, " cellToOutputWeights");
        ValidateTensorDataTypesMatch(cellToForgetWeightsInfo, cellToOutputWeightsInfo, descriptorName,
                                     "cellToForgetWeight", "cellToOutputWeights");

        if (!m_Parameters.m_CifgEnabled)
        {
            auto cellToInputWeightsInfo = m_CellToInputWeights->GetTensorInfo();
            ValidateTensorNumDimNumElem(cellToInputWeightsInfo, 1, numUnits, " cellToInputWeights");
            ValidateTensorDataTypesMatch(cellToForgetWeightsInfo, cellToInputWeightsInfo, descriptorName,
                                         "cellToForgetWeights", "cellToInputWeights");
        }
    }

    // Validate OPTIONAL params: Layer Norm Weights
    bool allLayerNormWeightsPresentOrNot =
            (((m_InputLayerNormWeights || m_Parameters.m_CifgEnabled) && m_ForgetLayerNormWeights
              && m_CellLayerNormWeights && m_OutputLayerNormWeights && m_Parameters.m_LayerNormEnabled)
             || (!m_InputLayerNormWeights && !m_ForgetLayerNormWeights && !m_CellLayerNormWeights
                 && !m_OutputLayerNormWeights && !m_Parameters.m_LayerNormEnabled));

    if (!allLayerNormWeightsPresentOrNot)
    {
        throw InvalidArgumentException(descriptorName +
                                       ": InputLayerNormWeights, ForgetLayerNormWeights, m_OutputLayerNormWeights "
                                       "and CellLayerNormWeights should all be present (Layer Norm enabled) or not "
                                       "be present at all (Layer Norm disabled). InputLayerNormWeights should "
                                       "only be present when Layer Norm is enabled and CIFG is disabled. "
                                       "m_Parameters.m_LayerNormEnabled should be set appropriately.");
    }

    if (m_Parameters.m_LayerNormEnabled)
    {
        auto forgetLayerNormWeightsInfo = m_ForgetLayerNormWeights->GetTensorInfo();
        ValidateTensorNumDimNumElem(forgetLayerNormWeightsInfo, 1, numUnits, " forgetLayerNormWeights");
        ValidateDataTypes(forgetLayerNormWeightsInfo, layerNormPeepholeWeightsSupportedTypes, descriptorName);

        auto cellLayerNormWeightsInfo = m_CellLayerNormWeights->GetTensorInfo();
        ValidateTensorNumDimNumElem(cellLayerNormWeightsInfo, 1, numUnits, " cellLayerNormWeights");
        ValidateTensorDataTypesMatch(forgetLayerNormWeightsInfo, cellLayerNormWeightsInfo, descriptorName,
                                     "forgetLayerNormWeights", "cellLayerNormWeights");

        auto outputLayerNormWeightsInfo = m_OutputLayerNormWeights->GetTensorInfo();
        ValidateTensorNumDimNumElem(outputLayerNormWeightsInfo, 1, numUnits, " outputLayerNormWeights");
        ValidateTensorDataTypesMatch(forgetLayerNormWeightsInfo, outputLayerNormWeightsInfo, descriptorName,
                                     "forgetLayerNormWeights", "outputLayerNormWeights");

        if (!m_Parameters.m_CifgEnabled)
        {
            auto inputLayerNormWeightsInfo = m_InputLayerNormWeights->GetTensorInfo();
            ValidateTensorNumDimNumElem(inputLayerNormWeightsInfo, 1, numUnits, " inputLayerNormWeights");
            ValidateTensorDataTypesMatch(forgetLayerNormWeightsInfo, inputLayerNormWeightsInfo, descriptorName,
                                         "forgetLayerNormWeights", "inputLayerNormWeights");
        }
    }

    // Validate OPTIONAL params: Projection (projectionWeights, projectionBias)
    bool correctProjectionTensorsPresent =
            ((!m_ProjectionWeights && !m_ProjectionBias && !m_Parameters.m_ProjectionEnabled) ||
            (m_ProjectionWeights && !m_ProjectionBias && m_Parameters.m_ProjectionEnabled) ||
            (m_ProjectionWeights && m_ProjectionBias && m_Parameters.m_ProjectionEnabled));

    if (!correctProjectionTensorsPresent)
    {
        throw InvalidArgumentException(descriptorName +
                                       ": If projection is enabled, ProjectionWeights should be present and "
                                       "ProjectionBias is optional. If projection is disabled, neither "
                                       "ProjectionWeights nor ProjectionBias should be present.");
    }

    if (m_Parameters.m_ProjectionEnabled)
    {
        auto projectionWeightsInfo = m_ProjectionWeights->GetTensorInfo();
        ValidateTensorNumDimNumElem(projectionWeightsInfo, 2, (numUnits * outputSize), "ProjectionWeights");
        ValidateDataTypes(projectionWeightsInfo, weightsSupportedTypes, descriptorName);

        if (m_ProjectionBias)
        {
            auto projectionBiasInfo = m_ProjectionBias->GetTensorInfo();
            ValidateTensorNumDimNumElem(projectionBiasInfo, 1, outputSize, "ProjectionBias");
            ValidateDataTypes(projectionBiasInfo, biasSupportedTypes, descriptorName);
        }

    }
    else if ((outputInfo.GetQuantizationScale() != m_Parameters.m_HiddenStateScale) &&
              outputInfo.GetQuantizationOffset() != m_Parameters.m_HiddenStateZeroPoint) {
        throw InvalidArgumentException(descriptorName +
                                       ": If projection is disabled, output quantization info (scale, offset) "
                                       "should match HiddenStateScale and HiddenStateZeroPoint.");
    }

}

void QuantizedLstmQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"QuantizedLstmQueueDescriptor"};

    // Validate number of inputs/outputs
    ValidateNumInputs(workloadInfo,  descriptorName, 3);
    ValidateNumOutputs(workloadInfo, descriptorName, 2);

    // Input/output tensor infos
    auto inputInfo = workloadInfo.m_InputTensorInfos[0];
    auto cellStateInInfo = workloadInfo.m_InputTensorInfos[1];
    auto outputStateInInfo = workloadInfo.m_InputTensorInfos[2];

    auto cellStateOutInfo = workloadInfo.m_OutputTensorInfos[0];
    auto outputStateOutInfo = workloadInfo.m_OutputTensorInfos[1];

    std::vector<DataType> inputOutputSupportedTypes =
    {
        DataType::QAsymmU8
    };

    std::vector<DataType> cellStateSupportedTypes =
    {
        DataType::QSymmS16
    };

    std::vector<DataType> weightsSupportedTypes =
    {
        DataType::QAsymmU8
    };

    std::vector<DataType> biasSupportedTypes =
    {
        DataType::Signed32
    };

    // Validate types of input/output tensors
    ValidateDataTypes(inputInfo, inputOutputSupportedTypes, descriptorName);
    ValidateDataTypes(cellStateInInfo, cellStateSupportedTypes, descriptorName);
    ValidateDataTypes(outputStateInInfo, inputOutputSupportedTypes, descriptorName);

    ValidateDataTypes(cellStateOutInfo, cellStateSupportedTypes, descriptorName);
    ValidateDataTypes(outputStateOutInfo, inputOutputSupportedTypes, descriptorName);

    // Validate matching types of input/output tensors
    ValidateTensorDataTypesMatch(inputInfo, outputStateInInfo, descriptorName, "input", "outputStateIn");
    ValidateTensorDataTypesMatch(outputStateInInfo, outputStateOutInfo, descriptorName,
                                 "outputStateIn", "outputStateOut");
    ValidateTensorDataTypesMatch(cellStateInInfo, cellStateOutInfo, descriptorName, "cellStateIn", "cellStateOut");

    // Validate matching quantization info for input/output tensors
    ValidateTensorQuantizationSpace(inputInfo, outputStateInInfo, descriptorName, "input", "outputStateIn");
    ValidateTensorQuantizationSpace(inputInfo, outputStateOutInfo, descriptorName, "input", "outputStateOut");
    ValidateTensorQuantizationSpace(cellStateInInfo, cellStateOutInfo, descriptorName, "cellStateIn", "cellStateOut");

    // Infer number of batches, input size and output size from tensor dimensions
    const uint32_t numBatches = inputInfo.GetShape()[0];
    const uint32_t inputSize  = inputInfo.GetShape()[1];
    const uint32_t outputSize = cellStateInInfo.GetShape()[1];

    // Validate number of dimensions and number of elements for input/output tensors
    ValidateTensorNumDimNumElem(inputInfo, 2, (numBatches * inputSize), descriptorName + " input");
    ValidateTensorNumDimNumElem(cellStateInInfo, 2, (numBatches * outputSize), descriptorName + " cellStateIn");
    ValidateTensorNumDimNumElem(outputStateInInfo, 2, (numBatches * outputSize), descriptorName + " outputStateIn");
    ValidateTensorNumDimNumElem(cellStateOutInfo, 2, (numBatches * outputSize), descriptorName + " cellStateOut");
    ValidateTensorNumDimNumElem(outputStateOutInfo, 2, (numBatches * outputSize), descriptorName + " outputStateOut");

    // Validate number of dimensions and number of elements for weights tensors
    ValidatePointer(m_InputToInputWeights, descriptorName, "InputToInputWeights");
    auto inputToInputWeightsInfo = m_InputToInputWeights->GetTensorInfo();
    ValidateTensorNumDimNumElem(inputToInputWeightsInfo, 2, (outputSize * inputSize), " InputToInputWeights");

    ValidatePointer(m_InputToForgetWeights, descriptorName, "InputToForgetWeights");
    auto inputToForgetWeightsInfo = m_InputToForgetWeights->GetTensorInfo();
    ValidateTensorNumDimNumElem(inputToForgetWeightsInfo, 2, (outputSize * inputSize), " InputToForgetWeights");

    ValidatePointer(m_InputToCellWeights, descriptorName, "InputToCellWeights");
    auto inputToCellWeightsInfo = m_InputToCellWeights->GetTensorInfo();
    ValidateTensorNumDimNumElem(inputToCellWeightsInfo, 2, (outputSize * inputSize), " InputToCellWeights");

    ValidatePointer(m_InputToOutputWeights, descriptorName, "InputToOutputWeights");
    auto inputToOutputWeightsInfo = m_InputToOutputWeights->GetTensorInfo();
    ValidateTensorNumDimNumElem(inputToOutputWeightsInfo, 2, (outputSize * inputSize), " InputToOutputWeights");

    ValidatePointer(m_RecurrentToInputWeights, descriptorName, "RecurrentToInputWeights");
    auto recurrentToInputWeightsInfo = m_RecurrentToInputWeights->GetTensorInfo();
    ValidateTensorNumDimNumElem(recurrentToInputWeightsInfo, 2, (outputSize * outputSize), " RecurrentToInputWeights");

    ValidatePointer(m_RecurrentToForgetWeights, descriptorName, "RecurrentToForgetWeights");
    auto recurrentToForgetWeightsInfo = m_RecurrentToForgetWeights->GetTensorInfo();
    ValidateTensorNumDimNumElem(recurrentToForgetWeightsInfo, 2, (outputSize * outputSize),
                                " RecurrentToForgetWeights");

    ValidatePointer(m_RecurrentToCellWeights, descriptorName, "RecurrentToCellWeights");
    auto recurrentToCellWeightsInfo = m_RecurrentToCellWeights->GetTensorInfo();
    ValidateTensorNumDimNumElem(recurrentToCellWeightsInfo, 2, (outputSize * outputSize), " RecurrentToCellWeights");

    ValidatePointer(m_RecurrentToOutputWeights, descriptorName, "RecurrentToOutputWeights");
    auto recurrentToOutputWeightsInfo = m_RecurrentToOutputWeights->GetTensorInfo();
    ValidateTensorNumDimNumElem(recurrentToOutputWeightsInfo, 2, (outputSize * outputSize), " RecurrentToCellWeights");

    // Validate data types for weights tensors (all should match each other)
    ValidateDataTypes(inputToInputWeightsInfo, weightsSupportedTypes, descriptorName);

    ValidateTensorDataTypesMatch(inputToInputWeightsInfo, inputToForgetWeightsInfo, descriptorName,
                                 "inputToInputWeights", "inputToForgetWeights");
    ValidateTensorDataTypesMatch(inputToInputWeightsInfo, inputToCellWeightsInfo, descriptorName,
                                 "inputToInputWeights", "inputToCellWeights");
    ValidateTensorDataTypesMatch(inputToInputWeightsInfo, inputToOutputWeightsInfo, descriptorName,
                                 "inputToInputWeights", "inputToOutputWeights");

    ValidateTensorDataTypesMatch(inputToInputWeightsInfo, recurrentToInputWeightsInfo, descriptorName,
                                 "inputToInputWeights", "recurrentToInputWeights");
    ValidateTensorDataTypesMatch(inputToInputWeightsInfo, recurrentToForgetWeightsInfo, descriptorName,
                                 "inputToInputWeights", "recurrentToForgeteights");
    ValidateTensorDataTypesMatch(inputToInputWeightsInfo, recurrentToCellWeightsInfo, descriptorName,
                                 "inputToInputWeights", "recurrentToCellWeights");
    ValidateTensorDataTypesMatch(inputToInputWeightsInfo, recurrentToOutputWeightsInfo, descriptorName,
                                 "inputToInputWeights", "recurrentToOutputWeights");

    // Validate matching quantization info for weight tensors (all should match each other)
    ValidateTensorQuantizationSpace(inputToInputWeightsInfo, inputToForgetWeightsInfo,
                                    descriptorName, "inputToInputWeights", "inputToForgetWeights");
    ValidateTensorQuantizationSpace(inputToInputWeightsInfo, inputToCellWeightsInfo,
                                    descriptorName, "inputToInputWeights", "inputToCellWeights");
    ValidateTensorQuantizationSpace(inputToInputWeightsInfo, inputToOutputWeightsInfo,
                                    descriptorName, "inputToInputWeights", "inputToOutputWeights");

    ValidateTensorQuantizationSpace(inputToInputWeightsInfo, recurrentToInputWeightsInfo,
                                    descriptorName, "inputToInputWeights", "recurrentToInputWeights");
    ValidateTensorQuantizationSpace(inputToInputWeightsInfo, recurrentToForgetWeightsInfo,
                                    descriptorName, "inputToInputWeights", "recurrentToForgetWeights");
    ValidateTensorQuantizationSpace(inputToInputWeightsInfo, recurrentToCellWeightsInfo,
                                    descriptorName, "inputToInputWeights", "recurrentToCellWeights");
    ValidateTensorQuantizationSpace(inputToInputWeightsInfo, recurrentToOutputWeightsInfo,
                                    descriptorName, "inputToInputWeights", "recurrentToOutputWeights");

    // Validate number of dimensions and number of elements in bias tensors
    ValidatePointer(m_InputGateBias, descriptorName, "InputGateBias");
    auto inputGateBiasInfo = m_InputGateBias->GetTensorInfo();
    ValidateTensorNumDimNumElem(inputGateBiasInfo, 1, outputSize, " InputGateBias");

    ValidatePointer(m_ForgetGateBias, descriptorName, "ForgetGateBias");
    auto forgetGateBiasInfo = m_ForgetGateBias->GetTensorInfo();
    ValidateTensorNumDimNumElem(forgetGateBiasInfo, 1, outputSize, " ForgetGateBias");

    ValidatePointer(m_CellBias, descriptorName, "CellBias");
    auto cellBiasInfo = m_CellBias->GetTensorInfo();
    ValidateTensorNumDimNumElem(cellBiasInfo, 1, outputSize, " CellBias");

    ValidatePointer(m_OutputGateBias, descriptorName, "OutputGateBias");
    auto outputGateBiasInfo = m_OutputGateBias->GetTensorInfo();
    ValidateTensorNumDimNumElem(outputGateBiasInfo, 1, outputSize, " OutputGateBias");

    // Validate data types for bias tensors (all should match each other)
    ValidateDataTypes(inputGateBiasInfo, biasSupportedTypes, descriptorName);

    ValidateTensorDataTypesMatch(inputGateBiasInfo, forgetGateBiasInfo, descriptorName,
                                 "inputGateBias", "forgetGateBias");
    ValidateTensorDataTypesMatch(inputGateBiasInfo, cellBiasInfo, descriptorName,
                                 "inputGateBias", "cellBias");
    ValidateTensorDataTypesMatch(inputGateBiasInfo, outputGateBiasInfo, descriptorName,
                                 "inputGateBias", "outputGateBias");

    // Validate bias tensor quantization info
    ValidateBiasTensorQuantization(inputGateBiasInfo, inputInfo, inputToInputWeightsInfo, descriptorName);
    ValidateBiasTensorQuantization(forgetGateBiasInfo, inputInfo, inputToInputWeightsInfo, descriptorName);
    ValidateBiasTensorQuantization(cellBiasInfo, inputInfo, inputToInputWeightsInfo, descriptorName);
    ValidateBiasTensorQuantization(outputGateBiasInfo, inputInfo, inputToInputWeightsInfo, descriptorName);
}

void AbsQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"AbsQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16,
        DataType::Signed32
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void SliceQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"SliceQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");

    const unsigned int rank = inputTensorInfo.GetNumDimensions();
    if (rank > 4)
    {
        throw InvalidArgumentException(descriptorName + ": Input tensors with rank greater than 4 are not supported.");
    }

    ValidateTensorNumDimensions(outputTensorInfo, descriptorName, rank, "output");

    // Check if m_Begin and m_Size have the expected length
    if (m_Parameters.m_Begin.size() != rank)
    {
        throw InvalidArgumentException(descriptorName +
            ": Length of begin offset descriptor must equal rank " + std::to_string(rank));
    }
    if (m_Parameters.m_Size.size() != rank)
    {
        throw InvalidArgumentException(descriptorName +
            ": Length of size descriptor must equal rank " + std::to_string(rank));
    }

    // Check if the shape of the output tensor matches m_Size
    const TensorShape& outputShape = outputTensorInfo.GetShape();
    for (unsigned int i = 0u; i < rank; ++i)
    {
        if (m_Parameters.m_Size[i] != outputShape[i])
        {
            throw InvalidArgumentException(descriptorName + ": Size descriptor does not match output tensor.");
        }
    }

    // Check if the sum of begin offset and size in a given dimension
    // does not exceed the size of corresponding input
    const TensorShape& inputShape  = inputTensorInfo.GetShape();
    for(unsigned int i = 0u; i < rank; ++i)
    {
        if (m_Parameters.m_Begin[i] + m_Parameters.m_Size[i] > inputShape[i])
        {
            throw InvalidArgumentException(descriptorName + ": Sum of begin offset and size for dimension " +
                std::to_string(i) + " exceeds input size.");
        }
    }
}

void DepthToSpaceQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"DepthToSpaceQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorNumDimensions(inputInfo,  descriptorName, 4, "input");
    ValidateTensorNumDimensions(outputInfo, descriptorName, 4, "output");

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float32,
        DataType::Float16,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16
    };

    ValidateDataTypes(inputInfo,  supportedTypes, descriptorName);
    ValidateDataTypes(outputInfo, supportedTypes, descriptorName);

    ValidateTensorNumElementsMatch(inputInfo, outputInfo, descriptorName, "input", "output");

    if (m_Parameters.m_BlockSize == 0)
    {
        throw InvalidArgumentException(descriptorName + ": Block size cannot be 0.");
    }

    DataLayoutIndexed dimensionIndices(m_Parameters.m_DataLayout);
    const unsigned int wIndex = dimensionIndices.GetWidthIndex();
    const unsigned int hIndex = dimensionIndices.GetHeightIndex();
    const unsigned int cIndex = dimensionIndices.GetChannelsIndex();

    const TensorShape& outputShape = outputInfo.GetShape();
    if (outputShape[hIndex] % m_Parameters.m_BlockSize != 0 || outputShape[wIndex]  % m_Parameters.m_BlockSize != 0)
    {
        throw InvalidArgumentException(descriptorName + ": Output width and height shape"
                                       "must be divisible by block size.");
    }

    const TensorShape& inputShape = inputInfo.GetShape();
    if (inputShape[cIndex] % (m_Parameters.m_BlockSize * m_Parameters.m_BlockSize) != 0)
    {
        throw InvalidArgumentException(descriptorName + ": The depth of the input tensor"
                                       "must be divisible by the square of block size." );
    }
}

void ComparisonQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"ComparisonQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 2);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
                                       inputTensorInfo1,
                                       outputTensorInfo,
                                       descriptorName,
                                       "input_0",
                                       "input_1");

    if (outputTensorInfo.GetDataType() != DataType::Boolean)
    {
        throw InvalidArgumentException(descriptorName + ": Output tensor type must be Boolean.");
    }
}

void ElementwiseUnaryQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"ElementwiseUnaryQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorShapesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16,
        DataType::Signed32
    };

    std::vector<DataType> logicalSupportedTypes =
    {
        DataType::Boolean
    };

    if (m_Parameters.m_Operation == UnaryOperation::LogicalNot)
    {
        ValidateDataTypes(inputTensorInfo, logicalSupportedTypes, descriptorName);
    }
    else
    {
        ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
    }


    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void RankQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"RankQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateTensorNumDimensions(outputTensorInfo, descriptorName, 1, "output");
    ValidateTensorNumElements(outputTensorInfo, descriptorName, 1, "output");

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS8,
        DataType::QSymmS16,
        DataType::Signed32
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
    ValidateDataTypes(outputTensorInfo, { DataType::Signed32 }, descriptorName);
}

void LogicalBinaryQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"LogicalBinaryQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 2);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo0 = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& inputTensorInfo1 = workloadInfo.m_InputTensorInfos[1];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    ValidateBroadcastTensorShapesMatch(inputTensorInfo0,
                                       inputTensorInfo1,
                                       outputTensorInfo,
                                       descriptorName,
                                       "input_0",
                                       "input_1");

    if (inputTensorInfo0.GetDataType() != DataType::Boolean)
    {
        throw InvalidArgumentException(descriptorName + ": Input tensor 0 type must be Boolean.");
    }

    if (inputTensorInfo1.GetDataType() != DataType::Boolean)
    {
        throw InvalidArgumentException(descriptorName + ": Input tensor 1 type must be Boolean.");
    }

    if (outputTensorInfo.GetDataType() != DataType::Boolean)
    {
        throw InvalidArgumentException(descriptorName + ": Output tensor type must be Boolean.");
    }
}

void ReduceQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    const std::string descriptorName{"ReduceQueueDescriptor"};

    ValidateNumInputs(workloadInfo,  descriptorName, 1);
    ValidateNumOutputs(workloadInfo, descriptorName, 1);

    const TensorInfo& inputTensorInfo  = workloadInfo.m_InputTensorInfos[0];
    const TensorInfo& outputTensorInfo = workloadInfo.m_OutputTensorInfos[0];

    std::vector<DataType> supportedTypes =
    {
        DataType::BFloat16,
        DataType::Float16,
        DataType::Float32,
        DataType::QAsymmS8,
        DataType::QAsymmU8,
        DataType::QSymmS16,
        DataType::Signed32
    };

    ValidateDataTypes(inputTensorInfo, supportedTypes, descriptorName);
    ValidateTensorDataTypesMatch(inputTensorInfo, outputTensorInfo, descriptorName, "input", "output");
}

void UnidirectionalSequenceLstmQueueDescriptor::Validate(const WorkloadInfo& workloadInfo) const
{
    // Modified from LstmQueueDescriptor::Validate to support UnidirectionalSequenceLstm

    const std::string descriptorName{"UnidirectionalSequenceLstmQueueDescriptor"};

    // check dimensions of all inputs and outputs
    if (workloadInfo.m_InputTensorInfos.size() != 3)
    {
        throw InvalidArgumentException(descriptorName + ": Invalid number of inputs.");
    }
    if (workloadInfo.m_OutputTensorInfos.size() != 1)
    {
        throw InvalidArgumentException(descriptorName + ": Invalid number of outputs.");
    }

    std::vector<DataType> supportedTypes =
    {
        DataType::Float32
    };

    // check for supported type of one input and match them with all the other input and output
    ValidateDataTypes(workloadInfo.m_InputTensorInfos[0], supportedTypes, descriptorName);

    // type matches all other inputs
    for (uint32_t i = 1u; i < workloadInfo.m_InputTensorInfos.size(); ++i)
    {
        ValidateTensorDataTypesMatch(workloadInfo.m_InputTensorInfos[0],
                                     workloadInfo.m_InputTensorInfos[i],
                                     descriptorName,
                                     "input_0",
                                     "input_" + std::to_string(i));
    }
    // type matches all other outputs
    for (uint32_t i = 0u; i < workloadInfo.m_OutputTensorInfos.size(); ++i)
    {
        ValidateTensorDataTypesMatch(workloadInfo.m_InputTensorInfos[0],
                                     workloadInfo.m_OutputTensorInfos[i],
                                     "LstmQueueDescriptor",
                                     "input_0",
                                     "output_" + std::to_string(i));
    }

    // Making sure clipping parameters have valid values.
    // == 0 means no clipping
    //  > 0 means clipping
    if (m_Parameters.m_ClippingThresCell < 0.0f)
    {
        throw InvalidArgumentException(descriptorName + ": negative cell clipping threshold is invalid");
    }
    if (m_Parameters.m_ClippingThresProj < 0.0f)
    {
        throw InvalidArgumentException(descriptorName + ": negative projection clipping threshold is invalid");
    }

    unsigned int batchIndx = 0;
    unsigned int inputIndx = 1;
    uint32_t timeStep = 1;
    unsigned int timeIndx = 1;
    inputIndx = 2;
    if (m_Parameters.m_TimeMajor)
    {
        batchIndx = 1;
        timeIndx = 0;

    }
    timeStep = workloadInfo.m_InputTensorInfos[0].GetShape()[timeIndx];

    // Inferring batch size, number of outputs and number of cells from the inputs.
    const uint32_t n_input = workloadInfo.m_InputTensorInfos[0].GetShape()[inputIndx];
    const uint32_t n_batch = workloadInfo.m_InputTensorInfos[0].GetShape()[batchIndx];
    ValidatePointer(m_InputToOutputWeights, "Null pointer check", "InputToOutputWeights");
    const uint32_t n_cell = m_InputToOutputWeights->GetShape()[0];
    ValidatePointer(m_RecurrentToOutputWeights, "Null pointer check", "RecurrentToOutputWeights");
    const uint32_t n_output = m_RecurrentToOutputWeights->GetShape()[1];

    // input tensor
    ValidateTensorNumDimNumElem(workloadInfo.m_InputTensorInfos[0], 3, (timeStep * n_batch * n_input),
                                descriptorName + " input_0");
    // outputStateInTensor
    ValidateTensorNumDimNumElem(workloadInfo.m_InputTensorInfos[1], 2, (n_batch * n_output),
                                descriptorName + " input_1");
    // outputStateInTensor
    ValidateTensorNumDimNumElem(workloadInfo.m_InputTensorInfos[2], 2, (n_batch * n_cell),
                                descriptorName + " input_2");

    // outputTensor
    ValidateTensorNumDimNumElem(workloadInfo.m_OutputTensorInfos[0], 3, (timeStep * n_batch * n_output),
                                descriptorName + " output_0");

    // check that dimensions of inputs/outputs and QueueDescriptor data match with each other
    if ( m_InputToInputWeights )
    {
        ValidateTensorNumDimNumElem(m_InputToInputWeights->GetTensorInfo(), 2,
                                      (n_cell * n_input), "InputLayerNormWeights");
    }

    ValidatePointer(m_InputToForgetWeights, "Null pointer check", "InputToForgetWeights");
    ValidateTensorNumDimNumElem(m_InputToForgetWeights->GetTensorInfo(), 2,
                                  (n_cell * n_input), "InputToForgetWeights");

    ValidatePointer(m_InputToCellWeights, "Null pointer check", "InputToCellWeights");
    ValidateTensorNumDimNumElem(m_InputToCellWeights->GetTensorInfo(), 2,
                                  (n_cell * n_input), "InputToCellWeights");

    if ( m_RecurrentToInputWeights )
    {
        ValidateTensorNumDimNumElem(m_RecurrentToInputWeights->GetTensorInfo(), 2,
                                      (n_cell * n_output), "RecurrentToInputWeights");
    }

    ValidatePointer(m_RecurrentToForgetWeights, "Null pointer check", "RecurrentToForgetWeights");
    ValidateTensorNumDimNumElem(m_RecurrentToForgetWeights->GetTensorInfo(), 2,
                                  (n_cell * n_output), "RecurrentToForgetWeights");

    ValidatePointer(m_RecurrentToCellWeights, "Null pointer check", "RecurrentToCellWeights");
    ValidateTensorNumDimNumElem(m_RecurrentToCellWeights->GetTensorInfo(), 2,
                                  (n_cell * n_output), "RecurrentToCellWeights");

    // Make sure the input-gate's parameters are either both present (regular
    // LSTM) or not at all (CIFG-LSTM). And CifgEnable is set accordingly.
    bool cifg_weights_all_or_none = ((m_InputToInputWeights && m_RecurrentToInputWeights &&
                                     !m_Parameters.m_CifgEnabled) ||
                                     (!m_InputToInputWeights && !m_RecurrentToInputWeights &&
                                     m_Parameters.m_CifgEnabled));
    if (!cifg_weights_all_or_none)
    {
        throw InvalidArgumentException(descriptorName + ": Input-Gate's parameters InputToInputWeights and "
                                       "RecurrentToInputWeights must either both be present (regular LSTM) "
                                       "or both not present (CIFG-LSTM). In addition CifgEnable must be set "
                                       "accordingly.");
    }

    if ( m_CellToInputWeights )
    {
        ValidateTensorNumDimNumElem(m_CellToInputWeights->GetTensorInfo(), 1,
                                      n_cell, "CellToInputWeights");
    }
    if ( m_CellToForgetWeights )
    {
        ValidateTensorNumDimNumElem(m_CellToForgetWeights->GetTensorInfo(), 1,
                                      n_cell, "CellToForgetWeights");
    }
    if ( m_CellToOutputWeights )
    {
        ValidateTensorNumDimNumElem(m_CellToOutputWeights->GetTensorInfo(), 1,
                                      n_cell, "CellToOutputWeights");
    }

    // Making sure the peephole weights are there all or none. And PeepholeEnable is set accordingly.
    bool peephole_weights_all_or_none =
            (((m_CellToInputWeights || m_Parameters.m_CifgEnabled) &&  m_CellToForgetWeights
            && m_CellToOutputWeights && m_Parameters.m_PeepholeEnabled)
            || ( !m_CellToInputWeights && !m_CellToForgetWeights
            && !m_CellToOutputWeights && !m_Parameters.m_PeepholeEnabled));
    if (!peephole_weights_all_or_none)
    {
        throw InvalidArgumentException(descriptorName + ": Invalid combination of peephole parameters.");
    }

    // Make sure the input gate bias is present only when not a CIFG-LSTM.
    if (m_Parameters.m_CifgEnabled)
    {
        if (m_InputGateBias)
        {
            throw InvalidArgumentException(descriptorName + ": InputGateBias is present and CIFG-LSTM is enabled.");
        }
    }
    else
    {
        if (!m_InputGateBias)
        {
            throw InvalidArgumentException(descriptorName + ": If CIFG-LSTM is disabled InputGateBias "
                                           "must be present.");
        }
        ValidateTensorNumDimNumElem(m_InputGateBias->GetTensorInfo(), 1,
                                      n_cell, "InputGateBias");
    }

    ValidatePointer(m_ForgetGateBias, "Null pointer check", "ForgetGateBias");
    ValidateTensorNumDimNumElem(m_ForgetGateBias->GetTensorInfo(), 1, n_cell, "ForgetGateBias");

    ValidatePointer(m_CellBias, "Null pointer check", "CellBias");
    ValidateTensorNumDimNumElem(m_CellBias->GetTensorInfo(), 1, n_cell, "CellBias");

    ValidatePointer(m_OutputGateBias, "Null pointer check", "OutputGateBias");
    ValidateTensorNumDimNumElem(m_OutputGateBias->GetTensorInfo(), 1, n_cell, "OutputGateBias");

    if (m_ProjectionWeights)
    {
        ValidateTensorNumDimNumElem(m_ProjectionWeights->GetTensorInfo(), 2,
                                      (n_cell * n_output), "ProjectionWeights");
    }
    if (m_ProjectionBias)
    {
        ValidateTensorNumDimNumElem(m_ProjectionBias->GetTensorInfo(), 1, n_output, "ProjectionBias");
    }

    // Making sure the projection tensors are consistent:
    // 1) If projection weight is not present, then projection bias should not be
    // present.
    // 2) If projection weight is present, then projection bias is optional.
    bool projecton_tensors_consistent = ((!m_ProjectionWeights && !m_ProjectionBias &&
                                        !m_Parameters.m_ProjectionEnabled)
                                        || (m_ProjectionWeights && !m_ProjectionBias &&
                                        m_Parameters.m_ProjectionEnabled)
                                        || (m_ProjectionWeights && m_ProjectionBias &&
                                        m_Parameters.m_ProjectionEnabled));
    if (!projecton_tensors_consistent)
    {
        throw InvalidArgumentException(descriptorName + ": Projection tensors are inconsistent.");
    }

    // The four layer normalization weights either all have values or none of them have values. Additionally, if
    // CIFG is used, input layer normalization weights tensor is omitted and the other layer normalization weights
    // either all have values or none of them have values. Layer normalization is used when the values of all the
    // layer normalization weights are present
    if (m_InputLayerNormWeights)
    {
        ValidateTensorNumDimNumElem(m_InputLayerNormWeights->GetTensorInfo(), 1, n_cell, "InputLayerNormWeights");
    }
    if (m_ForgetLayerNormWeights)
    {
        ValidateTensorNumDimNumElem(m_ForgetLayerNormWeights->GetTensorInfo(), 1, n_cell, "ForgetLayerNormWeights");
    }
    if (m_CellLayerNormWeights)
    {
        ValidateTensorNumDimNumElem(m_CellLayerNormWeights->GetTensorInfo(), 1, n_cell, "CellLayerNormWeights");
    }
    if (m_OutputLayerNormWeights)
    {
        ValidateTensorNumDimNumElem(m_OutputLayerNormWeights->GetTensorInfo(), 1, n_cell, "OutputLayerNormWeights");
    }

    if (m_Parameters.m_LayerNormEnabled)
    {
        if (!m_Parameters.m_CifgEnabled)
        {
            if (!m_InputLayerNormWeights)
            {
                throw InvalidArgumentException(descriptorName + ": Layer normalisation is enabled and CIFG-LSTM is "
                                               "disabled but InputLayerNormWeights are not present");
            }
            ValidateTensorNumDimNumElem(m_InputLayerNormWeights->GetTensorInfo(),
                                          1, n_cell, "InputLayerNormWeights");
        }
        else if (m_InputLayerNormWeights)
        {
            throw InvalidArgumentException(descriptorName + ":InputLayerNormWeights are present while CIFG is "
                                           "enabled");
        }

        ValidatePointer(m_ForgetLayerNormWeights, "Null pointer check layer normalisation enabled",
                        "ForgetLayerNormWeights");
        ValidateTensorNumDimNumElem(m_ForgetLayerNormWeights->GetTensorInfo(), 1, n_cell, "ForgetLayerNormWeights");

        ValidatePointer(m_OutputLayerNormWeights, "Null pointer check layer normalisation enabled",
                        "OutputLayerNormWeights");
        ValidateTensorNumDimNumElem(m_OutputLayerNormWeights->GetTensorInfo(), 1, n_cell, "OutputLayerNormWeights");

        ValidatePointer(m_CellLayerNormWeights, "Null pointer check layer normalisation enabled",
                        "CellLayerNormWeights");
        ValidateTensorNumDimNumElem(m_CellLayerNormWeights->GetTensorInfo(), 1, n_cell, "CellLayerNormWeights");
    }
    else if (m_InputLayerNormWeights || m_ForgetLayerNormWeights || m_OutputLayerNormWeights || m_CellLayerNormWeights)
    {
        throw InvalidArgumentException(descriptorName + ": Layer normalisation is disabled but one or more layer "
                                       "normalisation weights are present.");
    }
}


} // namespace armnn