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

#include "ConcatTestImpl.hpp"

#include <QuantizeHelper.hpp>
#include <ResolveType.hpp>


#include <armnnUtils/Permute.hpp>

#include <backendsCommon/test/TensorCopyUtils.hpp>
#include <backendsCommon/test/WorkloadTestUtils.hpp>

#include <test/TensorHelpers.hpp>

using namespace armnn;
using namespace armnnUtils;

//
// Helper functions and templates
//

OriginsDescriptor CreateDescriptorForConcat(
    const std::vector<TensorInfo> & inputTensorInfos,
    unsigned int concatDim)
{
    std::vector<TensorShape> shapes;
    shapes.reserve(inputTensorInfos.size());
    for (const TensorInfo& it: inputTensorInfos)
    {
        shapes.push_back(it.GetShape());
    }

    return CreateDescriptorForConcatenation(shapes.begin(), shapes.end(), concatDim);
}

//
// Concat is only supported for N and C dimensions for NCHW and the inner most dimension
// In case of <4 dimensions we need to make sure that the concat dimensions are at least
// the 3rd slowest iterating one or the inner most dimension.
//

bool NeedPermuteForConcat(
    const std::vector<TensorInfo> & inputTensorInfos,
    unsigned int concatDim)
{
    // See note above. Additionally we expect the input shapes to have the
    // same number of dimensions.
    unsigned int nDimensions = 0;

    // Determine the number of dimensions as well as sanity check them
    // agains test implementation issues.
    for (auto && tensorInfo : inputTensorInfos)
    {
        if (!nDimensions)
        {
            nDimensions = tensorInfo.GetShape().GetNumDimensions();
        }
        else
        {
            BOOST_ASSERT_MSG(nDimensions == tensorInfo.GetShape().GetNumDimensions(),
                "Input shapes must have the same number of dimensions");
        }
    }

    return (nDimensions < 3 || (nDimensions == 3 && (nDimensions-concatDim) < 3 && (nDimensions-concatDim) != 1));
}

TensorShape ExpandTensorShapeTo3dForPermute(const TensorShape & inputShape)
{
    unsigned int numDims = inputShape.GetNumDimensions();
    if (numDims >= 3)
    {
        // Nothing to do if the inputShape has at least 3 dimensions.
        return inputShape;
    }

    std::vector<unsigned int> newDims(size_t(3), 1u);
    unsigned int expandedBy = 3 - numDims;
    for (unsigned int i=0; i<numDims; ++i)
    {
        newDims[expandedBy+i] = inputShape[i];
    }
    return TensorShape(3u, &newDims[0]);
}

void Generate3dPermuteVectorForConcat(
    unsigned int numDimensions,
    unsigned int & concatDim,
    std::pair<PermutationVector, PermutationVector> & permutations)
{
    BOOST_ASSERT_MSG(numDimensions <= 3,
       "Only dimensions 1,2 and 3 are supported by this helper");
    unsigned int expandedBy = 3 - numDimensions;
    unsigned int expandedConcatAxis = concatDim + expandedBy;

    if (expandedConcatAxis == 2)
    {
        concatDim = 0;
        PermutationVector forwardPermutation({1, 2, 0});
        PermutationVector reversePermutation({2, 0, 1});
        permutations = std::make_pair(forwardPermutation, reversePermutation);
    }
    else if (expandedConcatAxis == 1)
    {
        concatDim = 0;
        PermutationVector forwardPermutation({2, 0, 1});
        PermutationVector reversePermutation({1, 2, 0});
        permutations = std::make_pair(forwardPermutation, reversePermutation);
    }
    else
    {
        BOOST_ASSERT(expandedConcatAxis == 0);
        concatDim = 0;
    }
}

template<typename T> void PermuteTensorData(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    const PermutationVector& mappings,
    TensorInfo & inputTensorInfo,
    const T * inputData,
    std::vector<T>& outputData)
{
    boost::ignore_unused(memoryManager);
    BOOST_ASSERT_MSG(inputData != nullptr, "inputData must not be null");
    if (inputData == nullptr)
    {
        // Nullptr is an error in the test. By returning without doing the concatenation
        // I expect the caller to fail the test. It still makes sense to report this as
        // an assert for Debug builds.
        return;
    }

    TensorInfo outputTensorInfo = armnnUtils::Permuted(inputTensorInfo, mappings);

    std::unique_ptr<ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfo);
    std::unique_ptr<ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);

    PermuteQueueDescriptor queueDescriptor;
    queueDescriptor.m_Parameters = PermuteDescriptor{mappings};
    WorkloadInfo workloadInfo;
    AddInputToWorkload(queueDescriptor, workloadInfo, inputTensorInfo, inputHandle.get());
    AddOutputToWorkload(queueDescriptor, workloadInfo, outputTensorInfo, outputHandle.get());

    std::unique_ptr<IWorkload> workload = workloadFactory.CreatePermute(queueDescriptor, workloadInfo);

    inputHandle->Allocate();
    outputHandle->Allocate();

    CopyDataToITensorHandle(inputHandle.get(), inputData);

    workload->PostAllocationConfigure();
    workload->Execute();

    outputData.resize(outputTensorInfo.GetNumElements());
    CopyDataFromITensorHandle(&outputData[0], outputHandle.get());
    inputTensorInfo = outputTensorInfo;
}

//
// Permute the input tensors so we can do a supported concatenation.
// Also treat lower than 3d tensors as 3d by adding dummy 1 dimensions
// at the front. Finally this function tells what the output shape
// of the permuted concatenated tensor is going to be.
//
template<typename T> void PermuteInputsForConcat(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    std::vector<TensorInfo> & inputTensorInfos,
    std::vector<T *> & inputData,
    std::vector<std::vector<T>> & inputDataStorage,
    PermutationVector & permuteVector,
    unsigned int & concatDim,
    TensorInfo & outputTensorInfo)
{
    boost::ignore_unused(memoryManager);
    BOOST_ASSERT_MSG(inputTensorInfos.size() > 1,
        "Expecting more than one tensor to be concatenated here");

    unsigned int numDims = 0;
    unsigned int nthInput = 0;
    const PermutationVector identity({0, 1, 2});

    std::pair<PermutationVector, PermutationVector> permutations =
        std::make_pair(identity, identity);

    inputDataStorage.resize(inputData.size());

    for (auto && tensorInfo : inputTensorInfos)
    {
        if (numDims == 0)
        {
            numDims = tensorInfo.GetShape().GetNumDimensions();
            Generate3dPermuteVectorForConcat(numDims, concatDim, permutations);

            // Store the reverese permutation.
            permuteVector = permutations.second;
            BOOST_ASSERT_MSG(!permuteVector.IsEqual(identity),
                "Test logic error, we don't need permutation, so we shouldn't arrive here");
        }
        else
        {
            BOOST_ASSERT_MSG(numDims == tensorInfo.GetShape().GetNumDimensions(),
                "All inputs must have the same number of dimensions");
        }

        TensorInfo newTensorInfo = tensorInfo;
        newTensorInfo.SetShape(ExpandTensorShapeTo3dForPermute(tensorInfo.GetShape()));

        PermuteTensorData<T>(workloadFactory,
                             memoryManager,
                             permutations.first,
                             newTensorInfo,
                             inputData[nthInput],
                             inputDataStorage[nthInput]);

        inputData[nthInput] = inputDataStorage[nthInput].data();
        inputTensorInfos[nthInput] = newTensorInfo;

        ++nthInput;
    }

    outputTensorInfo.SetShape(
        armnnUtils::Permuted(
            ExpandTensorShapeTo3dForPermute(outputTensorInfo.GetShape()),
            permutations.first));
}

//
// This is the pair of PermuteInputsForConcat(...) which permutes back
// the output of the concatenation so we can check it against an expected
// output.
//
template <typename T> void PermuteOutputForConcat(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    const TensorInfo & tensorInfo,
    const PermutationVector & permuteVector,
    std::unique_ptr<ITensorHandle> && inputDataHandle,
    T * data)
{
    BOOST_ASSERT_MSG(data != nullptr, "data must not be null");
    if (data == nullptr)
    {
        // Nullptr is an error in the test. By returning without doing the permutation
        // I expect the caller to fail the test. It still makes sense to report this as
        // an assert for Debug builds.
        return;
    }

    TensorInfo resultTensorInfo = tensorInfo;
    std::vector<T> inputData(tensorInfo.GetNumElements());
    std::vector<T> outputData;

    CopyDataFromITensorHandle(&inputData[0], inputDataHandle.get());

    PermuteTensorData<T>(workloadFactory,
                         memoryManager,
                         permuteVector,
                         resultTensorInfo,
                         &inputData[0],
                         outputData);

    ::memcpy(data, &outputData[0], sizeof(T)*outputData.size());
}

template<typename T> void Concatenate(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    std::initializer_list<const TensorInfo> inputTensorInfosOrig,
    std::initializer_list<T *> inputsOrig,
    const TensorInfo& outputTensorInfoOrig,
    T * output,
    unsigned int concatDim,
    bool useSubtensor)
{
    BOOST_ASSERT_MSG(output != nullptr, "output must not be null");
    if (output == nullptr)
    {
        // Nullptr is an error in the test. By returning without doing the permutation
        // I expect the caller to fail the test. It still makes sense to report this as
        // an assert for Debug builds.
        return;
    }

    // Saves a copy of the parameters which we might need to change.
    std::vector<TensorInfo> inputTensorInfos(inputTensorInfosOrig.begin(), inputTensorInfosOrig.end());
    std::vector<T *> inputs            = inputsOrig;
    TensorInfo outputTensorInfo = outputTensorInfoOrig;

    PermutationVector permuteVector{0, 1, 2};

    // Holds and automatically releases memory for the reshaped input data.
    std::vector<std::vector<T>> tmpInputDataStorage;

    const size_t inputCount = inputTensorInfos.size();

    bool needPermuteForConcat = NeedPermuteForConcat(inputTensorInfos, concatDim);

    if (needPermuteForConcat)
    {
        //
        // We need to permute the inputs, because concatenation along
        // the requested axis is not supported.
        //
        PermuteInputsForConcat<T>(workloadFactory,
                                  memoryManager,
                                  inputTensorInfos,
                                  inputs,
                                  tmpInputDataStorage,
                                  permuteVector,
                                  concatDim,
                                  outputTensorInfo);
    }

    WorkloadInfo workloadInfo;

    std::vector<std::unique_ptr<ITensorHandle>> inputHandles;
    inputHandles.reserve(inputCount);

    std::unique_ptr<ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);

    ConcatQueueDescriptor queueDescriptor;
    OriginsDescriptor viewsDescriptor = CreateDescriptorForConcat(inputTensorInfos, concatDim);
    queueDescriptor.m_Parameters = viewsDescriptor;

    if (useSubtensor)
    {
        queueDescriptor.m_ViewOrigins.reserve(viewsDescriptor.GetNumViews());
        for (unsigned int i = 0; i < viewsDescriptor.GetNumViews(); ++i)
        {
            queueDescriptor.m_ViewOrigins.emplace_back(std::vector<unsigned int>(viewsDescriptor.GetViewOrigin(i),
                viewsDescriptor.GetViewOrigin(i) + viewsDescriptor.GetNumDimensions()));
        }

        outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);

        const bool subTensorsSupported = workloadFactory.SupportsSubTensors();
        for (unsigned int i = 0; i < inputCount; ++i)
        {
            const TensorInfo& inputTensorInfo = inputTensorInfos[i];
            std::unique_ptr<ITensorHandle> inputHandle =
                subTensorsSupported ?
                    workloadFactory.CreateSubTensorHandle(*outputHandle,
                                                          inputTensorInfo.GetShape(),
                                                          queueDescriptor.m_ViewOrigins[i].m_Origin.data()) :
                    workloadFactory.CreateTensorHandle(inputTensorInfo);

            inputHandles.emplace_back(std::move(inputHandle));
        }

    }
    else
    {
        for (unsigned int i = 0; i < inputCount; ++i)
        {
            std::unique_ptr<ITensorHandle> inputHandle = workloadFactory.CreateTensorHandle(inputTensorInfos[i]);
            inputHandles.emplace_back(std::move(inputHandle));
        }
    }

    for (unsigned int i = 0; i < inputCount; ++i)
    {
        AddInputToWorkload(queueDescriptor, workloadInfo, inputTensorInfos[i], inputHandles[i].get());
    }

    AddOutputToWorkload(queueDescriptor, workloadInfo, outputTensorInfo, outputHandle.get());

    std::unique_ptr<IWorkload> workload = workloadFactory.CreateConcat(queueDescriptor, workloadInfo);

    for (auto& inputHandle : inputHandles)
    {
        inputHandle->Allocate();
    }

    outputHandle->Allocate();

    unsigned int nextInputId = 0;
    for (auto& inputHandle : inputHandles)
    {
        CopyDataToITensorHandle(inputHandle.get(), inputs[nextInputId]);
        ++nextInputId;
    }

    workload->PostAllocationConfigure();
    workload->Execute();

    if (needPermuteForConcat)
    {
        PermuteOutputForConcat<T>(workloadFactory,
                                  memoryManager,
                                  outputTensorInfo,
                                  permuteVector,
                                  std::move(outputHandle),
                                  output);
    }
    else
    {
        CopyDataFromITensorHandle(output, outputHandle.get());
    }
}

//
// Implementation templates
//

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 1> Concat1dTestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    float qScale,
    int32_t qOffset)
{
    TensorInfo inputTensorInfo({ 3 }, ArmnnType, qScale, qOffset);

    auto input0 = MakeTensor<T, 1>(inputTensorInfo, QuantizedVector<T>({ 1.0f, 2.0f, 3.0f }, qScale, qOffset));
    auto input1 = MakeTensor<T, 1>(inputTensorInfo, QuantizedVector<T>({ 4.0f, 5.0f, 6.0f }, qScale, qOffset));
    auto input2 = MakeTensor<T, 1>(inputTensorInfo, QuantizedVector<T>({ 7.0f, 8.0f, 9.0f }, qScale, qOffset));

    TensorInfo outputTensorInfo({ 9 }, ArmnnType, qScale, qOffset);

    LayerTestResult<T, 1> result(outputTensorInfo);

    std::vector<T> output;
    output.resize(outputTensorInfo.GetNumElements());
    Concatenate<T>(workloadFactory, memoryManager,
                   { inputTensorInfo, inputTensorInfo, inputTensorInfo },
                   { input0.data(), input1.data(), input2.data() },
                   outputTensorInfo,
                   output.data(),
                   0,
                   true);

    result.output         = MakeTensor<T, 1>(outputTensorInfo, output);
    result.outputExpected = MakeTensor<T, 1>(outputTensorInfo, QuantizedVector<T>(
        {
            1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f
        },
        qScale, qOffset));

    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 2> Concat2dTestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    const TensorInfo& outputTensorInfo,
    unsigned int dimension,
    const float qScale,
    const int32_t qOffset)
{
    TensorInfo inputTensorInfo({ 2, 3 }, ArmnnType, qScale, qOffset);

    auto input0 = MakeTensor<T, 2>(inputTensorInfo, QuantizedVector<T>(
        {
            // Batch 0
            1.0f, 2.0f, 3.0f,

            // Batch 1
            10.0f, 11.0f, 12.0f,
        },
        qScale, qOffset));

    auto input1 = MakeTensor<T, 2>(inputTensorInfo, QuantizedVector<T>(
         {
            // Batch 0
            4.0f, 5.0f, 6.0f,

            // Batch 1
            13.0f, 14.0f, 15.0f,
        },
        qScale, qOffset));

    auto input2 = MakeTensor<T, 2>(inputTensorInfo, QuantizedVector<T>(
        {
            // Batch 0
            7.0f, 8.0f, 9.0f,

            // Batch 1
            16.0f, 17.0f, 18.0f,
        },
        qScale, qOffset));

    LayerTestResult<T, 2> result(outputTensorInfo);

    std::vector<T> output;
    output.resize(outputTensorInfo.GetNumElements());
    Concatenate<T>(workloadFactory, memoryManager,
                   { inputTensorInfo, inputTensorInfo, inputTensorInfo },
                   { input0.data(), input1.data(), input2.data() },
                   outputTensorInfo,
                   output.data(),
                   dimension,
                   true);

    result.output = MakeTensor<T, 2>(outputTensorInfo, output);
    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 2> Concat2dDim0TestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    float qScale,
    int32_t qOffset)
{
    TensorInfo outputTensorInfo({ 6, 3 }, ArmnnType, qScale, qOffset);

    LayerTestResult<T, 2> result = Concat2dTestImpl<ArmnnType>(
        workloadFactory, memoryManager, outputTensorInfo, 0, qScale, qOffset);

    result.outputExpected = MakeTensor<T, 2>(outputTensorInfo, QuantizedVector<T>(
        {
            // Batch 0
            1.0f, 2.0f, 3.0f,

            // Batch 1
            10.0f, 11.0f, 12.0f,

            // Batch 2
            4.0f, 5.0f, 6.0f,

            // Batch 3
            13.0f, 14.0f, 15.0f,

            // Batch 4
            7.0f, 8.0f, 9.0f,

            // Batch 5
            16.0f, 17.0f, 18.0f,
        },
        qScale, qOffset));

    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 2> Concat2dDim1TestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    float qScale,
    int32_t qOffset)
{
    TensorInfo outputTensorInfo({ 2, 9 }, ArmnnType, qScale, qOffset);

    LayerTestResult<T, 2> result = Concat2dTestImpl<ArmnnType>(
        workloadFactory, memoryManager, outputTensorInfo, 1, qScale, qOffset);

    result.outputExpected = MakeTensor<T, 2>(outputTensorInfo, QuantizedVector<T>(
        {
            // Batch 0
            1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f,

            // Batch 1
            10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f
        },
        qScale, qOffset));

    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 2> Concat2dDim0DiffInputDimsTestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    float qScale,
    int32_t qOffset)
{
    TensorInfo input0TensorInfo({ 2, 3 }, ArmnnType, qScale, qOffset);
    auto input0 = MakeTensor<T, 2>(input0TensorInfo, QuantizedVector<T>(
        {
            // Batch 0
            1.0f, 2.0f, 3.0f,

            // Batch 1
            10.0f, 11.0f, 12.0f,
        },
        qScale, qOffset));

    TensorInfo input1TensorInfo({ 3, 3 }, ArmnnType, qScale, qOffset);
    auto input1 = MakeTensor<T, 2>(input1TensorInfo, QuantizedVector<T>(
        {
            // Batch 0
            4.0f, 5.0f, 6.0f,

            // Batch 1
            13.0f, 14.0f, 15.0f,

            // Batch 0
            7.0f, 8.0f, 9.0f,
        },
        qScale, qOffset));

    TensorInfo input2TensorInfo({ 1, 3 }, ArmnnType, qScale, qOffset);
    auto input2 = MakeTensor<T, 2>(input2TensorInfo, QuantizedVector<T>(
        {
            // Batch 1
            16.0f, 17.0f, 18.0f,
        },
        qScale, qOffset));

    TensorInfo outputTensorInfo({ 6, 3 }, ArmnnType, qScale, qOffset);
    LayerTestResult<T, 2> result(outputTensorInfo);

    std::vector<T> output;
    output.resize(outputTensorInfo.GetNumElements());
    Concatenate<T>(workloadFactory, memoryManager,
                   { input0TensorInfo, input1TensorInfo, input2TensorInfo },
                   { input0.data(), input1.data(), input2.data() },
                   outputTensorInfo,
                   output.data(),
                   0,
                   true);

    result.output = MakeTensor<T, 2>(outputTensorInfo, output);
    result.outputExpected = MakeTensor<T, 2>(outputTensorInfo, QuantizedVector<T>(
        {
            // Batch 0
            1.0f, 2.0f, 3.0f,

            // Batch 1
            10.0f, 11.0f, 12.0f,

            // Batch 2
            4.0f, 5.0f, 6.0f,

            // Batch 3
            13.0f, 14.0f, 15.0f,

            // Batch 4
            7.0f, 8.0f, 9.0f,

            // Batch 5
            16.0f, 17.0f, 18.0f,
        },
        qScale, qOffset));

    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 2> Concat2dDim1DiffInputDimsTestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    float qScale,
    int32_t qOffset)
{
    TensorInfo input0TensorInfo({ 2, 3 }, ArmnnType, qScale, qOffset);
    auto input0 = MakeTensor<T, 2>(input0TensorInfo, QuantizedVector<T>(
        {
            // Batch 0
            1.0f, 2.0f, 3.0f,

            // Batch 1
            10.0f, 11.0f, 12.0f,
        },
        qScale, qOffset));

    TensorInfo input1TensorInfo({ 2, 5 }, ArmnnType, qScale, qOffset);
    auto input1 = MakeTensor<T, 2>(input1TensorInfo, QuantizedVector<T>(
        {
            // Batch 0
            4.0f, 5.0f, 6.0f, 7.0f, 8.0f,

            // Batch 1
            13.0f, 14.0f, 15.0f, 16.0f, 17.0f,
        },
        qScale, qOffset));

    TensorInfo input2TensorInfo({ 2, 1 }, ArmnnType, qScale, qOffset);
    auto input2 = MakeTensor<T, 2>(input2TensorInfo, QuantizedVector<T>(
        {
            // Batch 0
            9.0f,

            // Batch 1
            18.0f
        },
        qScale, qOffset));

    TensorInfo outputTensorInfo({ 2, 9 }, ArmnnType, qScale, qOffset);
    LayerTestResult<T, 2> result(outputTensorInfo);

    std::vector<T> output;
    output.resize(outputTensorInfo.GetNumElements());
    Concatenate<T>(workloadFactory, memoryManager,
                   { input0TensorInfo, input1TensorInfo, input2TensorInfo },
                   { input0.data(), input1.data(), input2.data() },
                   outputTensorInfo,
                   output.data(),
                   1,
                   true);

    result.output = MakeTensor<T, 2>(outputTensorInfo, output);
    result.outputExpected = MakeTensor<T, 2>(outputTensorInfo, QuantizedVector<T>(
        {
            // Batch 0
            1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f,

            // Batch 1
            10.0f, 11.0f, 12.0f, 13.0f, 14.0f, 15.0f, 16.0f, 17.0f, 18.0f,
        },
        qScale, qOffset));

    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 3> Concat3dTestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    const TensorInfo& outputTensorInfo,
    unsigned int dimension,
    bool useSubtensor,
    float qScale,
    int32_t qOffset)
{
    TensorInfo inputTensorInfo({ 2, 3, 2 }, ArmnnType, qScale, qOffset);

    auto input0 = MakeTensor<T, 3>(inputTensorInfo, QuantizedVector<T>(
        {
            // Batch 0, Channel 0
            1.0f, 2.0f,

            // Batch 0, Channel 1
            3.0f, 4.0f,

            // Batch 0, Channel 2
            5.0f, 6.0f,

            // Batch 1, Channel 0
            19.0f, 20.0f,

            // Batch 1, Channel 1
            21.0f, 22.0f,

            // Batch 1, Channel 2
            23.0f, 24.0f
        },
        qScale, qOffset));

    auto input1 = MakeTensor<T, 3>(inputTensorInfo, QuantizedVector<T>(
        {
            // Batch 0, Channel 0
            7.0f, 8.0f,

            // Batch 0, Channel 1
            9.0f, 10.0f,

            // Batch 0, Channel 2
            11.0f, 12.0f,

            // Batch 1, Channel 0
            25.0f, 26.0f,

            // Batch 1, Channel 1
            27.0f, 28.0f,

            // Batch 1, Channel 2
            29.0f, 30.0f
        },
        qScale, qOffset));

    auto input2 = MakeTensor<T, 3>(inputTensorInfo, QuantizedVector<T>(
        {
            // Batch 0, Channel 0
            13.0f, 14.0f,

            // Batch 0, Channel 1
            15.0f, 16.0f,

            // Batch 0, Channel 2
            17.0f, 18.0f,

            // Batch 1, Channel 0
            31.0f, 32.0f,

            // Batch 1, Channel 1
            33.0f, 34.0f,

            // Batch 1, Channel 2
            35.0f, 36.0f
        },
        qScale, qOffset));

    LayerTestResult<T, 3> result(outputTensorInfo);

    std::vector<T> output;
    output.resize(outputTensorInfo.GetNumElements());
    Concatenate<T>(workloadFactory, memoryManager,
                   { inputTensorInfo, inputTensorInfo, inputTensorInfo },
                   { input0.data(), input1.data(), input2.data() },
                   outputTensorInfo,
                   output.data(),
                   dimension,
                   useSubtensor);

    result.output = MakeTensor<T, 3>(outputTensorInfo, output);
    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 3> Concat3dDim0TestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    float qScale,
    int32_t qOffset)
{
    TensorInfo outputTensorInfo({ 6, 3, 2 }, ArmnnType, qScale, qOffset);

    LayerTestResult<T, 3> result = Concat3dTestImpl<ArmnnType>(
        workloadFactory, memoryManager, outputTensorInfo, 0, true, qScale, qOffset);

    result.outputExpected = MakeTensor<T, 3>(outputTensorInfo, QuantizedVector<T>(
        {
            // Batch 0, Channel 0
            1.0f, 2.0f,

            // Batch 0, Channel 1
            3.0f, 4.0f,

            // Batch 0, Channel 2
            5.0f, 6.0f,

            // Batch 1, Channel 0
            19.0f, 20.0f,

            // Batch 1, Channel 1
            21.0f, 22.0f,

            // Batch 1, Channel 2
            23.0f, 24.0f,

            // Batch 2, Channel 0
            7.0f, 8.0f,

            // Batch 2, Channel 1
            9.0f, 10.0f,

            // Batch 2, Channel 2
            11.0f, 12.0f,

            // Batch 3, Channel 0
            25.0f, 26.0f,

            // Batch 3, Channel 1
            27.0f, 28.0f,

            // Batch 3, Channel 2
            29.0f, 30.0f,

            // Batch 4, Channel 0
            13.0f, 14.0f,

            // Batch 4, Channel 1
            15.0f, 16.0f,

            // Batch 4, Channel 2
            17.0f, 18.0f,

            // Batch 5, Channel 0
            31.0f, 32.0f,

            // Batch 5, Channel 1
            33.0f, 34.0f,

            // Batch 5, Channel 2
            35.0f, 36.0f
        },
        qScale, qOffset));

    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 3> Concat3dDim1TestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    float qScale,
    int32_t qOffset)
{
    TensorInfo outputTensorInfo({ 2, 9, 2 }, ArmnnType, qScale, qOffset);

    LayerTestResult<T, 3> result = Concat3dTestImpl<ArmnnType>(
        workloadFactory, memoryManager, outputTensorInfo, 1, true, qScale, qOffset);

    result.outputExpected = MakeTensor<T, 3>(outputTensorInfo, QuantizedVector<T>(
        {
            // Batch 0, Channel 0
            1.0f, 2.0f,

            // Batch 0, Channel 1
            3.0f, 4.0f,

            // Batch 0, Channel 2
            5.0f, 6.0f,

            // Batch 0, Channel 3
            7.0f, 8.0f,

            // Batch 0, Channel 4
            9.0f, 10.0f,

            // Batch 0, Channel 5
            11.0f, 12.0f,

            // Batch 0, Channel 6
            13.0f, 14.0f,

            // Batch 0, Channel 7
            15.0f, 16.0f,

            // Batch 0, Channel 8
            17.0f, 18.0f,

            // Batch 1, Channel 0
            19.0f, 20.0f,

            // Batch 1, Channel 1
            21.0f, 22.0f,

            // Batch 1, Channel 2
            23.0f, 24.0f,

            // Batch 1, Channel 3
            25.0f, 26.0f,

            // Batch 1, Channel 4
            27.0f, 28.0f,

            // Batch 1, Channel 5
            29.0f, 30.0f,

            // Batch 1, Channel 6
            31.0f, 32.0f,

            // Batch 1, Channel 7
            33.0f, 34.0f,

            // Batch 1, Channel 8
            35.0f, 36.0f
        },
        qScale, qOffset));

    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 3> Concat3dDim2TestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    bool useSubtensor,
    float qScale,
    int32_t qOffset)
{
    TensorInfo outputTensorInfo({ 2, 3, 6 }, ArmnnType, qScale, qOffset);

    LayerTestResult<T, 3> result = Concat3dTestImpl<ArmnnType>(
        workloadFactory, memoryManager, outputTensorInfo, 2, useSubtensor, qScale, qOffset);

    result.outputExpected = MakeTensor<T, 3>(outputTensorInfo, QuantizedVector<T>(
        {
            // Batch 0, Channel 0
            1.0f, 2.0f, 7.0f, 8.0f, 13.0f, 14.0f,

            // Batch 0, Channel 1
            3.0f, 4.0f, 9.0f, 10.0f, 15.0f, 16.0f,

            // Batch 0, Channel 2
            5.0f, 6.0f, 11.0f, 12.0f, 17.0f, 18.0f,

            // Batch 1, Channel 0
            19.0f, 20.0f, 25.0f, 26.0f, 31.0f, 32.0f,

            // Batch 1, Channel 1
            21.0f, 22.0f, 27.0f, 28.0f, 33.0f, 34.0f,

            // Batch 1, Channel 2
            23.0f, 24.0f, 29.0f, 30.0f, 35.0f, 36.0f,
        },
        qScale, qOffset));

    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 3> Concat3dDim0DiffInputDimsTestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    float qScale,
    int32_t qOffset)
{
    TensorInfo input0TensorInfo({ 2, 3, 2 }, ArmnnType);
    auto input0 = MakeTensor<T, 3>(input0TensorInfo, QuantizedVector<T>(
        {
            // Batch 0, Channel 0
            1.0f, 2.0f,

            // Batch 0, Channel 1
            3.0f, 4.0f,

            // Batch 0, Channel 2
            5.0f, 6.0f,

            // Batch 1, Channel 0
            19.0f, 20.0f,

            // Batch 1, Channel 1
            21.0f, 22.0f,

            // Batch 1, Channel 2
            23.0f, 24.0f
        },
        qScale, qOffset));

    TensorInfo input1TensorInfo({ 1, 3, 2 }, ArmnnType);
    auto input1 = MakeTensor<T, 3>(input1TensorInfo, QuantizedVector<T>(
        {
            // Batch 0, Channel 0
            7.0f, 8.0f,

            // Batch 0, Channel 1
            9.0f, 10.0f,

            // Batch 0, Channel 2
            11.0f, 12.0f,
        },
        qScale, qOffset));

    TensorInfo input2TensorInfo({ 3, 3, 2 }, ArmnnType);
    auto input2 = MakeTensor<T, 3>(input2TensorInfo, QuantizedVector<T>(
        {
            // Batch 0, Channel 0
            25.0f, 26.0f,

            // Batch 0, Channel 1
            27.0f, 28.0f,

            // Batch 0, Channel 2
            29.0f, 30.0f,

            // Batch 1, Channel 0
            13.0f, 14.0f,

            // Batch 1, Channel 1
            15.0f, 16.0f,

            // Batch 1, Channel 2
            17.0f, 18.0f,

            // Batch 2, Channel 0
            31.0f, 32.0f,

            // Batch 2, Channel 1
            33.0f, 34.0f,

            // Batch 2, Channel 2
            35.0f, 36.0f
        },
        qScale, qOffset));

    TensorInfo outputTensorInfo({ 6, 3, 2 }, ArmnnType);
    LayerTestResult<T, 3> result(outputTensorInfo);

    std::vector<T> output;
    output.resize(outputTensorInfo.GetNumElements());
    Concatenate<T>(workloadFactory, memoryManager,
                   { input0TensorInfo, input1TensorInfo, input2TensorInfo },
                   { input0.data(), input1.data(), input2.data() },
                   outputTensorInfo,
                   output.data(),
                   0,
                   true);

    result.output = MakeTensor<T, 3>(outputTensorInfo, output);
    result.outputExpected = MakeTensor<T, 3>(outputTensorInfo, QuantizedVector<T>(
        {
            // Batch 0, Channel 0
            1.0f, 2.0f,

            // Batch 0, Channel 1
            3.0f, 4.0f,

            // Batch 0, Channel 2
            5.0f, 6.0f,

            // Batch 1, Channel 0
            19.0f, 20.0f,

            // Batch 1, Channel 1
            21.0f, 22.0f,

            // Batch 1, Channel 2
            23.0f, 24.0f,

            // Batch 2, Channel 0
            7.0f, 8.0f,

            // Batch 2, Channel 1
            9.0f, 10.0f,

            // Batch 2, Channel 2
            11.0f, 12.0f,

            // Batch 3, Channel 0
            25.0f, 26.0f,

            // Batch 3, Channel 1
            27.0f, 28.0f,

            // Batch 3, Channel 2
            29.0f, 30.0f,

            // Batch 4, Channel 0
            13.0f, 14.0f,

            // Batch 4, Channel 1
            15.0f, 16.0f,

            // Batch 4, Channel 2
            17.0f, 18.0f,

            // Batch 5, Channel 0
            31.0f, 32.0f,

            // Batch 5, Channel 1
            33.0f, 34.0f,

            // Batch 5, Channel 2
            35.0f, 36.0f
        },
        qScale, qOffset));

    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 3> Concat3dDim1DiffInputDimsTestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    float qScale,
    int32_t qOffset)
{
    TensorInfo input0TensorInfo({ 2, 3, 2 }, ArmnnType, qScale, qOffset);
    auto input0 = MakeTensor<T, 3>(input0TensorInfo, QuantizedVector<T>(
        {
            // Batch 0, Channel 0
            1.0f, 2.0f,

            // Batch 0, Channel 1
            3.0f, 4.0f,

            // Batch 0, Channel 2
            5.0f, 6.0f,

            // Batch 1, Channel 0
            19.0f, 20.0f,

            // Batch 1, Channel 1
            21.0f, 22.0f,

            // Batch 1, Channel 2
            23.0f, 24.0f
        },
        qScale, qOffset));

    TensorInfo input1TensorInfo({ 2, 4, 2 }, ArmnnType, qScale, qOffset);
    auto input1 = MakeTensor<T, 3>(input1TensorInfo, QuantizedVector<T>(
        {
            // Batch 0, Channel 0
            7.0f, 8.0f,

            // Batch 0, Channel 1
            9.0f, 10.0f,

            // Batch 0, Channel 2
            11.0f, 12.0f,

            // Batch 0, Channel 3
            25.0f, 26.0f,

            // Batch 1, Channel 0
            27.0f, 28.0f,

            // Batch 1, Channel 1
            29.0f, 30.0f,

            // Batch 1, Channel 2
            13.0f, 14.0f,

            // Batch 1, Channel 3
            15.0f, 16.0f,
        },
        qScale, qOffset));

    TensorInfo input2TensorInfo({ 2, 1, 2 }, ArmnnType, qScale, qOffset);
    auto input2 = MakeTensor<T, 3>(input2TensorInfo, QuantizedVector<T>(
        {
            // Batch 0, Channel 0
            17.0f, 18.0f,

            // Batch 1, Channel 0
            31.0f, 32.0f,
        },
        qScale, qOffset));

    TensorInfo outputTensorInfo({ 2, 8, 2 }, ArmnnType, qScale, qOffset);
    LayerTestResult<T, 3> result(outputTensorInfo);

    std::vector<T> output;
    output.resize(outputTensorInfo.GetNumElements());
    Concatenate<T>(workloadFactory, memoryManager,
                   { input0TensorInfo, input1TensorInfo, input2TensorInfo },
                   { input0.data(), input1.data(), input2.data() },
                   outputTensorInfo,
                   output.data(),
                   1,
                   true);

    result.output = MakeTensor<T, 3>(outputTensorInfo, output);
    result.outputExpected = MakeTensor<T, 3>(outputTensorInfo, QuantizedVector<T>(
        {
            // Batch 0, Channel 0
            1.0f, 2.0f,

            // Batch 0, Channel 1
            3.0f, 4.0f,

            // Batch 0, Channel 2
            5.0f, 6.0f,

            // Batch 0, Channel 3
            7.0f, 8.0f,

            // Batch 0, Channel 4
            9.0f, 10.0f,

            // Batch 0, Channel 5
            11.0f, 12.0f,

            // Batch 0, Channel 6
            25.0f, 26.0f,

            // Batch 0, Channel 7
            17.0f, 18.0f,

            // Batch 1, Channel 0
            19.0f, 20.0f,

            // Batch 1, Channel 1
            21.0f, 22.0f,

            // Batch 1, Channel 2
            23.0f, 24.0f,

            // Batch 1, Channel 3
            27.0f, 28.0f,

            // Batch 1, Channel 4
            29.0f, 30.0f,

            // Batch 1, Channel 5
            13.0f, 14.0f,

            // Batch 1, Channel 6
            15.0f, 16.0f,

            // Batch 1, Channel 7
            31.0f, 32.0f,
        },
        qScale, qOffset));

    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 3> Concat3dDim2DiffInputDimsTestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    bool useSubtensor,
    float qScale,
    int32_t qOffset)
{
    TensorInfo input0TensorInfo({ 2, 3, 2 }, ArmnnType, qScale, qOffset);
    auto input0 = MakeTensor<T, 3>(input0TensorInfo, QuantizedVector<T>(
        {
            // Batch 0, Channel 0
            1.0f, 2.0f,

            // Batch 0, Channel 1
            3.0f, 4.0f,

            // Batch 0, Channel 2
            5.0f, 6.0f,

            // Batch 1, Channel 0
            19.0f, 20.0f,

            // Batch 1, Channel 1
            21.0f, 22.0f,

            // Batch 1, Channel 2
            23.0f, 24.0f
        },
        qScale, qOffset));

    TensorInfo input1TensorInfo({ 2, 3, 1 }, ArmnnType, qScale, qOffset);
    auto input1 = MakeTensor<T, 3>(input1TensorInfo, QuantizedVector<T>(
        {
            // Batch 0, Channel 0
            7.0f,

            // Batch 0, Channel 1
            9.0f,

            // Batch 0, Channel 2
            11.0f,

            // Batch 1, Channel 0
            25.0f,

            // Batch 1, Channel 1
            27.0f,

            // Batch 1, Channel 2
            29.0f
        },
        qScale, qOffset));

    TensorInfo input2TensorInfo({ 2, 3, 3 }, ArmnnType, qScale, qOffset);
    auto input2 = MakeTensor<T, 3>(input2TensorInfo, QuantizedVector<T>(
        {
            // Batch 0, Channel 0
            13.0f, 14.0f, 50.0f,

            // Batch 0, Channel 1
            15.0f, 16.0f, 51.0f,

            // Batch 0, Channel 2
            17.0f, 18.0f, 52.0f,

            // Batch 1, Channel 0
            31.0f, 32.0f, 53.0f,

            // Batch 1, Channel 1
            33.0f, 34.0f, 54.0f,

            // Batch 1, Channel 2
            35.0f, 36.0f, 55.0f,
        },
        qScale, qOffset));

    TensorInfo outputTensorInfo({ 2, 3, 6 }, ArmnnType, qScale, qOffset);
    LayerTestResult<T, 3> result(outputTensorInfo);

    std::vector<T> output;
    output.resize(outputTensorInfo.GetNumElements());
    Concatenate<T>(workloadFactory, memoryManager,
                   { input0TensorInfo, input1TensorInfo, input2TensorInfo },
                   { input0.data(), input1.data(), input2.data() },
                   outputTensorInfo,
                   output.data(),
                   2,
                   useSubtensor);

    result.output = MakeTensor<T, 3>(outputTensorInfo, output);
    result.outputExpected = MakeTensor<T, 3>(outputTensorInfo, QuantizedVector<T>(
        {
            // Batch 0, Channel 0
            1.0f, 2.0f, 7.0f, 13.0f, 14.0f, 50.0f,

            // Batch 0, Channel 1
            3.0f, 4.0f, 9.0f, 15.0f, 16.0f, 51.0f,

            // Batch 0, Channel 2
            5.0f, 6.0f, 11.0f, 17.0f, 18.0f, 52.0f,

            // Batch 1, Channel 0
            19.0f, 20.0f, 25.0f, 31.0f, 32.0f, 53.0f,

            // Batch 1, Channel 1
            21.0f, 22.0f, 27.0f, 33.0f, 34.0f, 54.0f,

            // Batch 1, Channel 2
            23.0f, 24.0f, 29.0f, 35.0f, 36.0f, 55.0f,
        },
        qScale, qOffset));

    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 4> Concat4dTestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    const TensorInfo& outputTensorInfo,
    unsigned int dimension,
    bool useSubtensor,
    float qScale,
    int32_t qOffset)
{
    TensorInfo inputTensorInfo({ 1, 3, 2, 2 }, ArmnnType, qScale, qOffset);

    auto input0 = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(
        {
             1.0f,  2.0f,
             3.0f,  4.0f,
             5.0f,  6.0f,
             7.0f,  8.0f,
             9.0f, 10.0f,
            11.0f, 12.0f
        },
        qScale, qOffset));

    auto input1 = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(
        {
            11.0f, 12.0f,
            13.0f, 14.0f,
            15.0f, 16.0f,
            17.0f, 18.0f,
            19.0f, 20.0f,
            21.0f, 22.0f
        },
        qScale, qOffset));

    auto input2 = MakeTensor<T, 4>(inputTensorInfo, QuantizedVector<T>(
        {
            21.0f, 22.0f,
            23.0f, 24.0f,
            25.0f, 26.0f,
            27.0f, 28.0f,
            29.0f, 30.0f,
            31.0f, 32.0f
        },
        qScale, qOffset));

    LayerTestResult<T, 4> result(outputTensorInfo);

    std::vector<T> output;
    output.resize(outputTensorInfo.GetNumElements());

    Concatenate<T>(workloadFactory,
                   memoryManager,
                   {inputTensorInfo, inputTensorInfo, inputTensorInfo},
                   {input0.data(), input1.data(), input2.data()},
                   outputTensorInfo,
                   output.data(),
                   dimension,
                   useSubtensor);

    result.output = MakeTensor<T, 4>(outputTensorInfo, output);
    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 4> Concat4dDim0TestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    float qScale,
    int32_t qOffset)
{
    TensorInfo outputTensorInfo({ 3, 3, 2, 2 }, ArmnnType, qScale, qOffset);

    LayerTestResult<T, 4> result = Concat4dTestImpl<ArmnnType>(
        workloadFactory, memoryManager, outputTensorInfo, 0, true, qScale, qOffset);

    result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(
        {
             1.0f,  2.0f,
             3.0f,  4.0f,
             5.0f,  6.0f,
             7.0f,  8.0f,
             9.0f, 10.0f,
            11.0f, 12.0f,

            11.0f, 12.0f,
            13.0f, 14.0f,
            15.0f, 16.0f,
            17.0f, 18.0f,
            19.0f, 20.0f,
            21.0f, 22.0f,

            21.0f, 22.0f,
            23.0f, 24.0f,
            25.0f, 26.0f,
            27.0f, 28.0f,
            29.0f, 30.0f,
            31.0f, 32.0f
        },
        qScale, qOffset));

    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 4> Concat4dDim1TestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    float qScale,
    int32_t qOffset)
{
    TensorInfo outputTensorInfo({ 1, 9, 2, 2 }, ArmnnType, qScale, qOffset);

    LayerTestResult<T, 4> result = Concat4dTestImpl<ArmnnType>(
        workloadFactory, memoryManager, outputTensorInfo, 1, true, qScale, qOffset);

    result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(
        {
             1.0f,  2.0f,
             3.0f,  4.0f,
             5.0f,  6.0f,
             7.0f,  8.0f,
             9.0f, 10.0f,
            11.0f, 12.0f,

            11.0f, 12.0f,
            13.0f, 14.0f,
            15.0f, 16.0f,
            17.0f, 18.0f,
            19.0f, 20.0f,
            21.0f, 22.0f,

            21.0f, 22.0f,
            23.0f, 24.0f,
            25.0f, 26.0f,
            27.0f, 28.0f,
            29.0f, 30.0f,
            31.0f, 32.0f
        },
        qScale, qOffset));

    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 4> Concat4dDim2TestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    float qScale,
    int32_t qOffset)
{
    TensorInfo outputTensorInfo({ 1, 3, 6, 2 }, ArmnnType, qScale, qOffset);

    LayerTestResult<T, 4> result = Concat4dTestImpl<ArmnnType>(
        workloadFactory, memoryManager, outputTensorInfo, 2, true, qScale, qOffset);

    result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(
        {
             1.0f,  2.0f,
             3.0f,  4.0f,
            11.0f, 12.0f,
            13.0f, 14.0f,
            21.0f, 22.0f,
            23.0f, 24.0f,

             5.0f,  6.0f,
             7.0f,  8.0f,
            15.0f, 16.0f,
            17.0f, 18.0f,
            25.0f, 26.0f,
            27.0f, 28.0f,

             9.0f, 10.0f,
            11.0f, 12.0f,
            19.0f, 20.0f,
            21.0f, 22.0f,
            29.0f, 30.0f,
            31.0f, 32.0f
        },
        qScale, qOffset));

    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 4> Concat4dDim3TestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    float qScale,
    int32_t qOffset,
    bool useSubtensor)
{
    TensorInfo outputTensorInfo({ 1, 3, 2, 6 }, ArmnnType, qScale, qOffset);

    LayerTestResult<T, 4> result = Concat4dTestImpl<ArmnnType>(
        workloadFactory, memoryManager, outputTensorInfo, 3, useSubtensor, qScale, qOffset);

    result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(
        {
             1.0f,  2.0f,
            11.0f, 12.0f,
            21.0f, 22.0f,
             3.0f,  4.0f,
            13.0f, 14.0f,
            23.0f, 24.0f,

             5.0f,  6.0f,
            15.0f, 16.0f,
            25.0f, 26.0f,
             7.0f,  8.0f,
            17.0f, 18.0f,
            27.0f, 28.0f,

             9.0f, 10.0f,
            19.0f, 20.0f,
            29.0f, 30.0f,
            11.0f, 12.0f,
            21.0f, 22.0f,
            31.0f, 32.0f
        },
        qScale, qOffset));

    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 4> Concat4dDiffShapeDim0TestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    float qScale,
    int32_t qOffset)
{
    constexpr unsigned int dimension = 0u;

    TensorInfo inputTensorInfo0({ 1, 3, 2, 2 }, ArmnnType, qScale, qOffset);
    auto input0 = MakeTensor<T, 4>(inputTensorInfo0, QuantizedVector<T>(
        {
             1.0f,  2.0f,
             3.0f,  4.0f,
             5.0f,  6.0f,
             7.0f,  8.0f,
             9.0f, 10.0f,
            11.0f, 12.0f
        },
        qScale, qOffset));

    TensorInfo inputTensorInfo1({ 2, 3, 2, 2 }, ArmnnType, qScale, qOffset);

    auto input1 = MakeTensor<T, 4>(inputTensorInfo1, QuantizedVector<T>(
        {
            11.0f, 12.0f,
            13.0f, 14.0f,
            15.0f, 16.0f,
            17.0f, 18.0f,
            19.0f, 20.0f,
            21.0f, 22.0f,

            21.0f, 22.0f,
            23.0f, 24.0f,
            25.0f, 26.0f,
            27.0f, 28.0f,
            29.0f, 30.0f,
            31.0f, 32.0f
        },
        qScale, qOffset));

    TensorInfo outputTensorInfo({ 3, 3, 2, 2 }, ArmnnType, qScale, qOffset);

    LayerTestResult<T, 4> result(outputTensorInfo);

    std::vector<T> output;
    output.resize(outputTensorInfo.GetNumElements());
    Concatenate<T>(workloadFactory,
                   memoryManager,
                   {inputTensorInfo0, inputTensorInfo1},
                   {input0.data(), input1.data()},
                   outputTensorInfo,
                   output.data(),
                   dimension,
                   true);

    result.output = MakeTensor<T, 4>(outputTensorInfo, output);
    result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(
        {
             1.0f, 2.0f,
             3.0f, 4.0f,
             5.0f, 6.0f,
             7.0f, 8.0f,
             9.0f, 10.0f,
            11.0f, 12.0f,

            11.0f, 12.0f,
            13.0f, 14.0f,
            15.0f, 16.0f,
            17.0f, 18.0f,
            19.0f, 20.0f,
            21.0f, 22.0f,

            21.0f, 22.0f,
            23.0f, 24.0f,
            25.0f, 26.0f,
            27.0f, 28.0f,
            29.0f, 30.0f,
            31.0f, 32.0f
        },
        qScale, qOffset));

    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 4> Concat4dDiffShapeDim1TestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    float qScale,
    int32_t qOffset)
{
    constexpr unsigned int dimension = 1u;

    TensorInfo inputTensorInfo0({ 1, 3, 2, 2 }, ArmnnType, qScale, qOffset);
    auto input0 = MakeTensor<T, 4>(inputTensorInfo0, QuantizedVector<T>(
        {
             1.0f,  2.0f,
             3.0f,  4.0f,
             5.0f,  6.0f,
             7.0f,  8.0f,
             9.0f, 10.0f,
            11.0f, 12.0f
        },
        qScale, qOffset));

    TensorInfo inputTensorInfo1({ 1, 2, 2, 2 }, ArmnnType, qScale, qOffset);

    auto input1 = MakeTensor<T, 4>(inputTensorInfo1, QuantizedVector<T>(
        {
            11.0f, 12.0f,
            13.0f, 14.0f,
            15.0f, 16.0f,
            17.0f, 18.0f,
        },
        qScale, qOffset));

    TensorInfo outputTensorInfo({ 1, 5, 2, 2 }, ArmnnType, qScale, qOffset);

    LayerTestResult<T, 4> result(outputTensorInfo);

    std::vector<T> output;
    output.resize(outputTensorInfo.GetNumElements());
    Concatenate<T>(workloadFactory,
                   memoryManager,
                   {inputTensorInfo0, inputTensorInfo1},
                   {input0.data(), input1.data()},
                   outputTensorInfo,
                   output.data(),
                   dimension,
                   true);

    result.output = MakeTensor<T, 4>(outputTensorInfo, output);
    result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(
        {
             1.0f,  2.0f,
             3.0f,  4.0f,
             5.0f,  6.0f,
             7.0f,  8.0f,
             9.0f, 10.0f,
            11.0f, 12.0f,
            11.0f, 12.0f,
            13.0f, 14.0f,
            15.0f, 16.0f,
            17.0f, 18.0f
        },
        qScale, qOffset));

    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 4> Concat4dDiffShapeDim2TestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    float qScale,
    int32_t qOffset)
{
    constexpr unsigned int dimension = 2u;

    TensorInfo inputTensorInfo0({ 1, 3, 2, 2 }, ArmnnType, qScale, qOffset);
    auto input0 = MakeTensor<T, 4>(inputTensorInfo0, QuantizedVector<T>(
        {
             1.0f, 2.0f,
             3.0f, 4.0f,
             5.0f, 6.0f,
             7.0f, 8.0f,
            9.0f, 10.0f,
            11.0f, 12.0f
        },
        qScale, qOffset));

    TensorInfo inputTensorInfo1({ 1, 3, 3, 2 }, ArmnnType, qScale, qOffset);
    auto input1 = MakeTensor<T, 4>(inputTensorInfo1, QuantizedVector<T>(
        {
            11.0f, 12.0f,
            13.0f, 14.0f,
            15.0f, 16.0f,
            17.0f, 18.0f,
            19.0f, 20.0f,
            21.0f, 22.0f,
            23.0f, 24.0f,
            25.0f, 26.0f,
            27.0f, 28.0f
        },
        qScale, qOffset));

    TensorInfo outputTensorInfo({ 1, 3, 5, 2 }, ArmnnType, qScale, qOffset);
    LayerTestResult<T, 4> result(outputTensorInfo);

    std::vector<T> output;
    output.resize(outputTensorInfo.GetNumElements());
    Concatenate<T>(workloadFactory,
                   memoryManager,
                   {inputTensorInfo0, inputTensorInfo1},
                   {input0.data(), input1.data()},
                   outputTensorInfo,
                   output.data(),
                   dimension,
                   true);

    result.output         = MakeTensor<T, 4>(outputTensorInfo, output);
    result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(
        {
             1.0f,  2.0f,
             3.0f,  4.0f,
            11.0f, 12.0f,
            13.0f, 14.0f,
            15.0f, 16.0f,

             5.0f,  6.0f,
             7.0f,  8.0f,
            17.0f, 18.0f,
            19.0f, 20.0f,
            21.0f, 22.0f,

             9.0f, 10.0f,
            11.0f, 12.0f,
            23.0f, 24.0f,
            25.0f, 26.0f,
            27.0f, 28.0f
        },
        qScale, qOffset));

    return result;
}

template<DataType ArmnnType, typename T = ResolveType<ArmnnType>>
LayerTestResult<T, 4> Concat4dDiffShapeDim3TestImpl(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    float qScale,
    int32_t qOffset,
    bool useSubtensor)
{
    constexpr unsigned int dimension = 3u;

    TensorInfo inputTensorInfo0({ 1, 3, 2, 2 }, ArmnnType, qScale, qOffset);
    auto input0 = MakeTensor<T, 4>(inputTensorInfo0, QuantizedVector<T>(
        {
             1.0f,  2.0f,
             3.0f,  4.0f,
             5.0f,  6.0f,
             7.0f,  8.0f,
             9.0f, 10.0f,
            11.0f, 12.0f
        },
        qScale, qOffset));

    TensorInfo inputTensorInfo1({ 1, 3, 2, 3 }, ArmnnType, qScale, qOffset);
    auto input1 = MakeTensor<T, 4>(inputTensorInfo1, QuantizedVector<T>(
        {
            11.0f, 12.0f, 13.0f,
            14.0f, 15.0f, 16.0f,

            17.0f, 18.0f, 19.0f,
            20.0f, 21.0f, 22.0f,

            23.0f, 24.0f, 25.0f,
            26.0f, 27.0f, 28.0f
        },
        qScale, qOffset));

    TensorInfo outputTensorInfo({ 1, 3, 2, 5 }, ArmnnType, qScale, qOffset);

    LayerTestResult<T, 4> result(outputTensorInfo);

    std::vector<T> output;
    output.resize(outputTensorInfo.GetNumElements());
    Concatenate<T>(workloadFactory,
                   memoryManager,
                   {inputTensorInfo0, inputTensorInfo1},
                   {input0.data(), input1.data()},
                   outputTensorInfo,
                   output.data(),
                   dimension,
                   useSubtensor);

    result.output = MakeTensor<T, 4>(outputTensorInfo, output);
    result.outputExpected = MakeTensor<T, 4>(outputTensorInfo, QuantizedVector<T>(
        {
            1.0f, 2.0f, 11.0f, 12.0f, 13.0f,
            3.0f, 4.0f, 14.0f, 15.0f, 16.0f,
            5.0f, 6.0f, 17.0f, 18.0f, 19.0f,
            7.0f, 8.0f, 20.0f, 21.0f, 22.0f,
            9.0f, 10.0f, 23.0f, 24.0f, 25.0f,
            11.0f, 12.0f, 26.0f, 27.0f, 28.0f
        },
        qScale, qOffset));

    return result;
}

template<DataType ArmnnType, typename T>
LayerTestResult<T, 3> ConcatDifferentInputOutputQParamTest(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    bool useSubtensor)
{
    boost::ignore_unused(memoryManager);

    // Defines the tensor descriptors.
    TensorInfo outputTensorInfo({ 3, 6, 3 }, ArmnnType);
    TensorInfo inputTensorInfo1({ 3, 6, 2 }, ArmnnType);
    TensorInfo inputTensorInfo2({ 3, 6, 1 }, ArmnnType);

    std::vector<TensorShape> inputTensorShapes({inputTensorInfo1.GetShape(), inputTensorInfo2.GetShape()});

    // Quantized input1 tensor.
    const float inputScale1 = 0.5f;
    const int32_t inputOffset1 = 5;

    auto input1 = MakeTensor<T, 3>(inputTensorInfo1, std::vector<T>(
    {
        1, 2, 3,
        4, 5, 6,
        7, 8, 9,
        10, 11, 12,
        13, 14, 15,
        16, 17, 18,

        19, 20, 21,
        22, 23, 24,
        25, 26, 27,
        28, 29, 30,
        31, 32, 33,
        34, 35, 36
    }));

    // Quatized input2 tensor.
    const float inputScale2 = 0.2f;
    const int32_t inputOffset2 = 10;

    auto input2 = MakeTensor<T, 3>(inputTensorInfo2, std::vector<T>(
    {
        37, 38, 39,
        40, 41, 42,
        43, 44, 45,
        46, 47, 48,
        49, 50, 51,
        52, 53, 54
    }));

    // Quantized output tensor.
    const float outputScale = 0.1f;
    const int32_t outputOffset = 20;

    LayerTestResult<T, 3> ret(outputTensorInfo);

    ret.outputExpected = MakeTensor<T, 3>(outputTensorInfo, std::vector<T>(
    {
        0,   5,  74,
        10,  15,  76,
        20,  25,  78,
        30,  35,  80,
        40,  45,  82,
        50,  55,  84,

        60,  65,  86,
        70,  75,  88,
        80,  85,  90,
        90,  95,  92,
        100, 105,  94,
        110, 115,  96,

        120, 125,  98,
        130, 135, 100,
        140, 145, 102,
        150, 155, 104,
        160, 165, 106,
        170, 175, 108
    }));

    outputTensorInfo.SetQuantizationScale(outputScale);
    outputTensorInfo.SetQuantizationOffset(outputOffset);
    inputTensorInfo1.SetQuantizationScale(inputScale1);
    inputTensorInfo1.SetQuantizationOffset(inputOffset1);
    inputTensorInfo2.SetQuantizationScale(inputScale2);
    inputTensorInfo2.SetQuantizationOffset(inputOffset2);

    std::vector<unsigned int> wOrigin1 = { 0, 0, 0 }; //Extent of the window is defined by size of input[0].
    ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);

    std::vector<unsigned int> wOrigin2 = { 0, 0, 2 }; //Extent of the window is defined by size of input[1].
    ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);

    std::unique_ptr<ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);

    bool subTensorsSupported = useSubtensor && workloadFactory.SupportsSubTensors();

    std::unique_ptr<ITensorHandle> inputHandle1 =
            subTensorsSupported ?
            workloadFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
            workloadFactory.CreateTensorHandle(inputTensorInfo1);

    std::unique_ptr<ITensorHandle> inputHandle2 =
            subTensorsSupported ?
            workloadFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
            workloadFactory.CreateTensorHandle(inputTensorInfo2);

    ConcatQueueDescriptor data;
    OriginsDescriptor desc = CreateDescriptorForConcatenation(
            inputTensorShapes.begin(),inputTensorShapes.end(), 2);
    data.m_Parameters = desc;

    WorkloadInfo info;
    AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
    AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
    AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());

    data.m_ViewOrigins.push_back(window1);
    data.m_ViewOrigins.push_back(window2);

    std::unique_ptr<IWorkload> workload = workloadFactory.CreateConcat(data, info);

    inputHandle1->Allocate();
    inputHandle2->Allocate();
    outputHandle->Allocate();

    CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0]);
    CopyDataToITensorHandle(inputHandle2.get(), &input2[0][0][0]);

    workload->PostAllocationConfigure();
    workload->Execute();

    CopyDataFromITensorHandle(&ret.output[0][0][0], outputHandle.get());

    return ret;
}

//
// Explicit template specializations
//

template LayerTestResult<ResolveType<DataType::QAsymmU8>, 3>
ConcatDifferentInputOutputQParamTest<DataType::QAsymmU8>(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    bool useSubtensor);

template LayerTestResult<ResolveType<DataType::QSymmS16>, 3>
ConcatDifferentInputOutputQParamTest<DataType::QSymmS16>(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    bool useSubtensor);

//
// Implementation functions
//

LayerTestResult<float,3> ConcatTest(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    boost::ignore_unused(memoryManager);

    unsigned int outputWidth = 3;
    unsigned int outputHeight = 6;
    unsigned int outputChannels = 3;

    unsigned int inputWidth1 = 3;
    unsigned int inputHeight1 = 6;
    unsigned int inputChannels1 = 2;

    unsigned int inputWidth2 = 3;
    unsigned int inputHeight2 = 6;
    unsigned int inputChannels2 = 1;

    // Define the tensor descriptors.
    TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, DataType::Float32);
    TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, DataType::Float32);
    TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, DataType::Float32);

    LayerTestResult<float,3> ret(outputTensorInfo);

    ret.outputExpected = MakeTensor<float, 3>(outputTensorInfo, std::vector<float>(
    {
            1.0f, 2.0f, 3.0f,
            4.0f, 5.0f, 6.0f,
            7.0f, 8.0f, 9.0f,
            10.0f, 11.0f, 12.0f,
            13.0f, 14.0f, 15.0f,
            16.0f, 17.0f, 18.0f,

            19.0f, 20.0f, 21.0f,
            22.0f, 23.0f, 24.0f,
            25.0f, 26.0f, 27.0f,
            28.0f, 29.0f, 30.0f,
            31.0f, 32.0f, 33.0f,
            34.0f, 35.0f, 36.0f,

            37.0f, 38.0f, 39.0f,
            40.0f, 41.0f, 42.0f,
            43.0f, 44.0f, 45.0f,
            46.0f, 47.0f, 48.0f,
            49.0f, 50.0f, 51.0f,
            52.0f, 53.0f, 54.0f,
        })
    );

    auto input1 = MakeTensor<float, 3>(inputTensorInfo1, std::vector<float>(
        {
            1.0f, 2.0f, 3.0f,
            4.0f, 5.0f, 6.0f,
            7.0f, 8.0f, 9.0f,
            10.0f, 11.0f, 12.0f,
            13.0f, 14.0f, 15.0f,
            16.0f, 17.0f, 18.0f,

            19.0f, 20.0f, 21.0f,
            22.0f, 23.0f, 24.0f,
            25.0f, 26.0f, 27.0f,
            28.0f, 29.0f, 30.0f,
            31.0f, 32.0f, 33.0f,
            34.0f, 35.0f, 36.0f,
        })
    );

    auto input2 = MakeTensor<float, 3>(inputTensorInfo2, std::vector<float>(
        {
            37.0f, 38.0f, 39.0f,
            40.0f, 41.0f, 42.0f,
            43.0f, 44.0f, 45.0f,
            46.0f, 47.0f, 48.0f,
            49.0f, 50.0f, 51.0f,
            52.0f, 53.0f, 54.0f,
        })
    );

    std::vector<unsigned int> wOrigin1 = {0, 0, 0}; //Extent of the window is defined by size of input[0].
    ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);

    std::vector<unsigned int> wOrigin2 = {2, 0, 0}; //Extent of the window is defined by size of input[1].
    ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);

    std::unique_ptr<ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);

    bool subTensorsSupported = workloadFactory.SupportsSubTensors();

    std::unique_ptr<ITensorHandle> inputHandle1 =
        subTensorsSupported ?
            workloadFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
            workloadFactory.CreateTensorHandle(inputTensorInfo1);

    std::unique_ptr<ITensorHandle> inputHandle2  =
        subTensorsSupported ?
            workloadFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
            workloadFactory.CreateTensorHandle(inputTensorInfo2);

    ConcatQueueDescriptor data;
    WorkloadInfo info;
    AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
    AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
    AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());

    data.m_ViewOrigins.push_back(window1);
    data.m_ViewOrigins.push_back(window2);

    std::unique_ptr<IWorkload> workload = workloadFactory.CreateConcat(data, info);

    inputHandle1->Allocate();
    inputHandle2->Allocate();
    outputHandle->Allocate();

    CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0]);
    CopyDataToITensorHandle(inputHandle2.get(), &input2[0][0][0]);

    workload->PostAllocationConfigure();
    workload->Execute();

    CopyDataFromITensorHandle(&ret.output[0][0][0], outputHandle.get());

    return ret;
}

LayerTestResult<float, 1> Concat1dTest(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat1dTestImpl<DataType::Float32>(workloadFactory, memoryManager, 0.0f, 0);
}

LayerTestResult<float, 2> Concat2dDim0Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat2dDim0TestImpl<DataType::Float32>(workloadFactory, memoryManager, 0.0f, 0);
}

LayerTestResult<float, 2> Concat2dDim1Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat2dDim1TestImpl<DataType::Float32>(workloadFactory, memoryManager, 0.0f, 0);
}

LayerTestResult<float, 2> Concat2dDim0DiffInputDimsTest(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat2dDim0DiffInputDimsTestImpl<DataType::Float32>(workloadFactory, memoryManager, 0.0f, 0);
}

LayerTestResult<float, 2> Concat2dDim1DiffInputDimsTest(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat2dDim1DiffInputDimsTestImpl<DataType::Float32>(workloadFactory, memoryManager, 0.0f, 0);
}

LayerTestResult<float, 3> Concat3dDim0Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat3dDim0TestImpl<DataType::Float32>(workloadFactory, memoryManager, 0.0f, 0);
}

LayerTestResult<float, 3> Concat3dDim1Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat3dDim1TestImpl<DataType::Float32>(workloadFactory, memoryManager, 0.0f, 0);
}

LayerTestResult<float, 3> Concat3dDim2Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    bool useSubtensor)
{
    return Concat3dDim2TestImpl<DataType::Float32>(workloadFactory, memoryManager, useSubtensor, 0.0f, 0);
}

LayerTestResult<float, 3> Concat3dDim0DiffInputDimsTest(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat3dDim0DiffInputDimsTestImpl<DataType::Float32>(
        workloadFactory, memoryManager, 0.0f, 0);
}

LayerTestResult<float, 3> Concat3dDim1DiffInputDimsTest(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat3dDim1DiffInputDimsTestImpl<DataType::Float32>(workloadFactory, memoryManager, 0.0f, 0);
}

LayerTestResult<float, 3> Concat3dDim2DiffInputDimsTest(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    bool useSubtensor)
{
    return Concat3dDim2DiffInputDimsTestImpl<DataType::Float32>(
        workloadFactory, memoryManager, useSubtensor, 0.0f, 0);
}

LayerTestResult<float, 4> Concat4dDim0Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat4dDim0TestImpl<DataType::Float32>(workloadFactory, memoryManager, 0.0f, 0);
}

LayerTestResult<float, 4> Concat4dDim1Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat4dDim1TestImpl<DataType::Float32>(workloadFactory, memoryManager, 0.0f, 0);
}

LayerTestResult<float, 4> Concat4dDim2Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat4dDim2TestImpl<DataType::Float32>(workloadFactory, memoryManager, 0.0f, 0);
}

LayerTestResult<float, 4> Concat4dDim3Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    bool useSubtensor)
{
    return Concat4dDim3TestImpl<DataType::Float32>(workloadFactory, memoryManager, 0.0f, 0, useSubtensor);
}

LayerTestResult<float, 4> Concat4dDiffShapeDim0Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat4dDiffShapeDim0TestImpl<DataType::Float32>(workloadFactory, memoryManager, 0.0f, 0);
}

LayerTestResult<float, 4> Concat4dDiffShapeDim1Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat4dDiffShapeDim1TestImpl<DataType::Float32>(
        workloadFactory, memoryManager, 0.0f, 0);
}

LayerTestResult<float, 4> Concat4dDiffShapeDim2Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat4dDiffShapeDim2TestImpl<DataType::Float32>(workloadFactory, memoryManager, 0.0f, 0);
}

LayerTestResult<float, 4> Concat4dDiffShapeDim3Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    bool useSubtensor)
{
    return Concat4dDiffShapeDim3TestImpl<DataType::Float32>(
        workloadFactory, memoryManager, 0.0f, 0, useSubtensor);
}

LayerTestResult<Half, 3> ConcatFloat16Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat3dDim1TestImpl<DataType::Float16>(workloadFactory, memoryManager, 0.0f, 0);
}

LayerTestResult<uint8_t, 3> ConcatUint8DifferentQParamsTest(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    boost::ignore_unused(memoryManager);

    unsigned int outputWidth = 3;
    unsigned int outputHeight = 6;
    unsigned int outputChannels = 3;

    unsigned int inputWidth1 = 3;
    unsigned int inputHeight1 = 6;
    unsigned int inputChannels1 = 2;

    unsigned int inputWidth2 = 3;
    unsigned int inputHeight2 = 6;
    unsigned int inputChannels2 = 1;

    // Defines the tensor descriptors.
    TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, DataType::QAsymmU8);
    TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, DataType::QAsymmU8);
    TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, DataType::QAsymmU8);

    // Quantized input1 tensor. Range [-3, 1]
    const float inputScale1 = 0.015686f;
    const int32_t inputOffset1 = 192;

    auto input1 = MakeTensor<uint8_t, 3>(inputTensorInfo1, std::vector<uint8_t>(
    {
        1, 2, 3,
        4, 5, 6,
        7, 8, 9,
        10, 11, 12,
        13, 14, 15,
        16, 17, 18,

        19, 20, 21,
        22, 23, 24,
        25, 26, 27,
        28, 29, 30,
        31, 32, 33,
        34, 35, 36,
    })
    );

    // Quatized input2 tensor. Range [-1, 4]
    const float inputScale2 = 0.019608f;
    const int32_t inputOffset2 = 50;

    auto input2 = MakeTensor<uint8_t, 3>(inputTensorInfo2, std::vector<uint8_t>(
    {
        37, 38, 39,
        40, 41, 42,
        43, 44, 45,
        46, 47, 48,
        49, 50, 51,
        52, 53, 54,
    })
    );

    // Output has the same quantization parameters than input1,
    // so that only the requantization of input2 is required
    const float outputScale = 0.015686f;
    const int32_t outputOffset = 192;

    LayerTestResult<uint8_t, 3> ret(outputTensorInfo);

    ret.outputExpected = MakeTensor<uint8_t, 3>(outputTensorInfo, std::vector<uint8_t>(
    {
        1, 2, 3,
        4, 5, 6,
        7, 8, 9,
        10, 11, 12,
        13, 14, 15,
        16, 17, 18,

        19, 20, 21,
        22, 23, 24,
        25, 26, 27,
        28, 29, 30,
        31, 32, 33,
        34, 35, 36,

        176, 177, 178,
        179, 181, 182,
        183, 184, 186,
        187, 188, 189,
        191, 192, 193,
        195, 196, 197,
    })
    );

    outputTensorInfo.SetQuantizationScale(outputScale);
    outputTensorInfo.SetQuantizationOffset(outputOffset);
    inputTensorInfo1.SetQuantizationScale(inputScale1);
    inputTensorInfo1.SetQuantizationOffset(inputOffset1);
    inputTensorInfo2.SetQuantizationScale(inputScale2);
    inputTensorInfo2.SetQuantizationOffset(inputOffset2);

    std::vector<unsigned int> wOrigin1 = { 0, 0, 0 }; //Extent of the window is defined by size of input[0].
    ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);

    std::vector<unsigned int> wOrigin2 = { 2, 0, 0 }; //Extent of the window is defined by size of input[1].
    ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);

    std::unique_ptr<ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);

    bool subTensorsSupported = workloadFactory.SupportsSubTensors();

    std::unique_ptr<ITensorHandle> inputHandle1 =
            subTensorsSupported ?
            workloadFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
            workloadFactory.CreateTensorHandle(inputTensorInfo1);

    std::unique_ptr<ITensorHandle> inputHandle2 =
            subTensorsSupported ?
            workloadFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
            workloadFactory.CreateTensorHandle(inputTensorInfo2);

    ConcatQueueDescriptor data;
    WorkloadInfo info;
    AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
    AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
    AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());

    data.m_ViewOrigins.push_back(window1);
    data.m_ViewOrigins.push_back(window2);

    std::unique_ptr<IWorkload> workload = workloadFactory.CreateConcat(data, info);

    inputHandle1->Allocate();
    inputHandle2->Allocate();
    outputHandle->Allocate();

    CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0]);
    CopyDataToITensorHandle(inputHandle2.get(), &input2[0][0][0]);

    workload->PostAllocationConfigure();
    workload->Execute();

    CopyDataFromITensorHandle(&ret.output[0][0][0], outputHandle.get());

    return ret;
}

LayerTestResult<uint8_t, 3> ConcatUint8Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    boost::ignore_unused(memoryManager);

    unsigned int outputWidth = 3;
    unsigned int outputHeight = 6;
    unsigned int outputChannels = 3;

    unsigned int inputWidth1 = 3;
    unsigned int inputHeight1 = 6;
    unsigned int inputChannels1 = 2;

    unsigned int inputWidth2 = 3;
    unsigned int inputHeight2 = 6;
    unsigned int inputChannels2 = 1;

    // Defines the tensor descriptors.
    TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, DataType::QAsymmU8);
    TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, DataType::QAsymmU8);
    TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, DataType::QAsymmU8);

    // Arbitrary scale and offsets. They don't really matter as the Concat operator doesn't dequantize/quantize them.
    const float scale = 0.13497836f;
    const int32_t offset = -7;

    outputTensorInfo.SetQuantizationScale(scale);
    outputTensorInfo.SetQuantizationOffset(offset);
    inputTensorInfo1.SetQuantizationScale(scale);
    inputTensorInfo1.SetQuantizationOffset(offset);
    inputTensorInfo2.SetQuantizationScale(scale);
    inputTensorInfo2.SetQuantizationOffset(offset);

    LayerTestResult<uint8_t, 3> ret(outputTensorInfo);

    ret.outputExpected = MakeTensor<uint8_t, 3>(outputTensorInfo, std::vector<uint8_t>(
        {
            1, 2, 3,
            4, 5, 6,
            7, 8, 9,
            10, 11, 12,
            13, 14, 15,
            16, 17, 18,

            19, 20, 21,
            22, 23, 24,
            25, 26, 27,
            28, 29, 30,
            31, 32, 33,
            34, 35, 36,

            37, 38, 39,
            40, 41, 42,
            43, 44, 45,
            46, 47, 48,
            49, 50, 51,
            52, 53, 54,
        })
    );

    auto input1 = MakeTensor<uint8_t, 3>(inputTensorInfo1, std::vector<uint8_t>(
    {
        1, 2, 3,
        4, 5, 6,
        7, 8, 9,
        10, 11, 12,
        13, 14, 15,
        16, 17, 18,

        19, 20, 21,
        22, 23, 24,
        25, 26, 27,
        28, 29, 30,
        31, 32, 33,
        34, 35, 36,
    })
    );

    auto input2 = MakeTensor<uint8_t, 3>(inputTensorInfo2, std::vector<uint8_t>(
    {
        37, 38, 39,
        40, 41, 42,
        43, 44, 45,
        46, 47, 48,
        49, 50, 51,
        52, 53, 54,
    })
    );

    std::vector<unsigned int> wOrigin1 = { 0, 0, 0 }; //Extent of the window is defined by size of input[0].
    ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);

    std::vector<unsigned int> wOrigin2 = { 2, 0, 0 }; //Extent of the window is defined by size of input[1].
    ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);


    std::unique_ptr<ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);

    bool subTensorsSupported = workloadFactory.SupportsSubTensors();

    std::unique_ptr<ITensorHandle> inputHandle1 =
        subTensorsSupported ?
            workloadFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
            workloadFactory.CreateTensorHandle(inputTensorInfo1);

    std::unique_ptr<ITensorHandle> inputHandle2 =
        subTensorsSupported ?
            workloadFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
            workloadFactory.CreateTensorHandle(inputTensorInfo2);


    ConcatQueueDescriptor data;
    WorkloadInfo info;
    AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
    AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
    AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());

    data.m_ViewOrigins.push_back(window1);
    data.m_ViewOrigins.push_back(window2);

    std::unique_ptr<IWorkload> workload = workloadFactory.CreateConcat(data, info);

    inputHandle1->Allocate();
    inputHandle2->Allocate();
    outputHandle->Allocate();

    CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0]);
    CopyDataToITensorHandle(inputHandle2.get(), &input2[0][0][0]);

    workload->PostAllocationConfigure();
    workload->Execute();

    CopyDataFromITensorHandle(&ret.output[0][0][0], outputHandle.get());

    return ret;
}

LayerTestResult<uint16_t, 3> ConcatUint16Test(
        IWorkloadFactory& workloadFactory,
        const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    boost::ignore_unused(memoryManager);

    unsigned int outputWidth = 3;
    unsigned int outputHeight = 6;
    unsigned int outputChannels = 3;

    unsigned int inputWidth1 = 3;
    unsigned int inputHeight1 = 6;
    unsigned int inputChannels1 = 2;

    unsigned int inputWidth2 = 3;
    unsigned int inputHeight2 = 6;
    unsigned int inputChannels2 = 1;

    // Defines the tensor descriptors.
    TensorInfo outputTensorInfo({ outputChannels, outputHeight, outputWidth }, DataType::QSymmS16);
    TensorInfo inputTensorInfo1({ inputChannels1, inputHeight1, inputWidth1 }, DataType::QSymmS16);
    TensorInfo inputTensorInfo2({ inputChannels2, inputHeight2, inputWidth2 }, DataType::QSymmS16);

    // Arbitrary scale and offsets. They don't really matter as the Concat operator doesn't dequantize/quantize them.
    const float scale = 0.13497836f;
    const int32_t offset = -7;

    outputTensorInfo.SetQuantizationScale(scale);
    outputTensorInfo.SetQuantizationOffset(offset);
    inputTensorInfo1.SetQuantizationScale(scale);
    inputTensorInfo1.SetQuantizationOffset(offset);
    inputTensorInfo2.SetQuantizationScale(scale);
    inputTensorInfo2.SetQuantizationOffset(offset);

    LayerTestResult<uint16_t, 3> ret(outputTensorInfo);

    ret.outputExpected = MakeTensor<uint16_t, 3>(outputTensorInfo, std::vector<uint16_t>(
    {
        1, 2, 3,
        4, 5, 6,
        7, 8, 9,
        10, 11, 12,
        13, 14, 15,
        16, 17, 18,

        19, 20, 21,
        22, 23, 24,
        25, 26, 27,
        28, 29, 30,
        31, 32, 33,
        34, 35, 36,

        37, 38, 39,
        40, 41, 42,
        43, 44, 45,
        46, 47, 48,
        49, 50, 51,
        52, 53, 54,
    }));

    auto input1 = MakeTensor<uint16_t, 3>(inputTensorInfo1, std::vector<uint16_t>(
    {
        1, 2, 3,
        4, 5, 6,
        7, 8, 9,
        10, 11, 12,
        13, 14, 15,
        16, 17, 18,

        19, 20, 21,
        22, 23, 24,
        25, 26, 27,
        28, 29, 30,
        31, 32, 33,
        34, 35, 36,
    }));

    auto input2 = MakeTensor<uint16_t, 3>(inputTensorInfo2, std::vector<uint16_t>(
    {
        37, 38, 39,
        40, 41, 42,
        43, 44, 45,
        46, 47, 48,
        49, 50, 51,
        52, 53, 54,
    }));

    std::vector<unsigned int> wOrigin1 = { 0, 0, 0 }; //Extent of the window is defined by size of input[0].
    ConcatQueueDescriptor::ViewOrigin window1(wOrigin1);

    std::vector<unsigned int> wOrigin2 = { 2, 0, 0 }; //Extent of the window is defined by size of input[1].
    ConcatQueueDescriptor::ViewOrigin window2(wOrigin2);


    std::unique_ptr<ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);

    bool subTensorsSupported = workloadFactory.SupportsSubTensors();

    std::unique_ptr<ITensorHandle> inputHandle1 =
            subTensorsSupported ?
            workloadFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo1.GetShape(), wOrigin1.data()) :
            workloadFactory.CreateTensorHandle(inputTensorInfo1);

    std::unique_ptr<ITensorHandle> inputHandle2 =
            subTensorsSupported ?
            workloadFactory.CreateSubTensorHandle(*outputHandle, inputTensorInfo2.GetShape(), wOrigin2.data()) :
            workloadFactory.CreateTensorHandle(inputTensorInfo2);


    ConcatQueueDescriptor data;
    WorkloadInfo info;
    AddInputToWorkload(data, info, inputTensorInfo1, inputHandle1.get());
    AddInputToWorkload(data, info, inputTensorInfo2, inputHandle2.get());
    AddOutputToWorkload(data, info, outputTensorInfo, outputHandle.get());

    data.m_ViewOrigins.push_back(window1);
    data.m_ViewOrigins.push_back(window2);

    std::unique_ptr<IWorkload> workload = workloadFactory.CreateConcat(data, info);

    inputHandle1->Allocate();
    inputHandle2->Allocate();
    outputHandle->Allocate();

    CopyDataToITensorHandle(inputHandle1.get(), &input1[0][0][0]);
    CopyDataToITensorHandle(inputHandle2.get(), &input2[0][0][0]);

    workload->PostAllocationConfigure();
    workload->Execute();

    CopyDataFromITensorHandle(&ret.output[0][0][0], outputHandle.get());

    return ret;
}

LayerTestResult<uint8_t, 1> Concat1dUint8Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat1dTestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, 0.5f, -1);
}

LayerTestResult<uint8_t, 2> Concat2dDim0Uint8Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat2dDim0TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, 0.5f, -1);
}

LayerTestResult<uint8_t, 2> Concat2dDim1Uint8Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat2dDim1TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, 0.5f, -1);
}

LayerTestResult<uint8_t, 2> Concat2dDim0DiffInputDimsUint8Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat2dDim0DiffInputDimsTestImpl<DataType::QAsymmU8>(
        workloadFactory, memoryManager, 0.5f, -1);
}

LayerTestResult<uint8_t, 2> Concat2dDim1DiffInputDimsUint8Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat2dDim1DiffInputDimsTestImpl<DataType::QAsymmU8>(
        workloadFactory, memoryManager, 0.5f, -1);
}

LayerTestResult<uint8_t, 3> Concat3dDim0Uint8Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat3dDim0TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, 0.5f, -1);
}

LayerTestResult<uint8_t, 3> Concat3dDim1Uint8Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat3dDim1TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, 0.5f, -1);
}

LayerTestResult<uint8_t, 3> Concat3dDim2Uint8Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    bool useSubtensor)
{
    return Concat3dDim2TestImpl<DataType::QAsymmU8>(
        workloadFactory, memoryManager, useSubtensor, 0.5f, -1);
}

LayerTestResult<uint8_t, 3> Concat3dDim0DiffInputDimsUint8Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat3dDim0TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, 0.5f, -1);
}

LayerTestResult<uint8_t, 3> Concat3dDim1DiffInputDimsUint8Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat3dDim1DiffInputDimsTestImpl<DataType::QAsymmU8>(
        workloadFactory, memoryManager, 0.5f, -1);
}

LayerTestResult<uint8_t, 3> Concat3dDim2DiffInputDimsUint8Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    bool useSubtensor)
{
    return Concat3dDim2DiffInputDimsTestImpl<DataType::QAsymmU8>(
        workloadFactory, memoryManager, useSubtensor, 0.5f, -1);
}

LayerTestResult<uint8_t, 4> Concat4dDim0Uint8Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat4dDim0TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, 0.5f, -1);
}

LayerTestResult<uint8_t, 4> Concat4dDim1Uint8Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat4dDim1TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, 0.5f, -1);
}

LayerTestResult<uint8_t, 4> Concat4dDim2Uint8Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat4dDim2TestImpl<DataType::QAsymmU8>(workloadFactory, memoryManager, 0.5f, -1);
}

LayerTestResult<uint8_t, 4> Concat4dDim3Uint8Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager, bool useSubtensor)
{
    return Concat4dDim3TestImpl<DataType::QAsymmU8>(
        workloadFactory, memoryManager, 0.5f, -1, useSubtensor);
}

LayerTestResult<uint8_t, 4> Concat4dDiffShapeDim0Uint8Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat4dDiffShapeDim0TestImpl<DataType::QAsymmU8>(
        workloadFactory, memoryManager, 0.5f, -1);
}

LayerTestResult<uint8_t, 4> Concat4dDiffShapeDim1Uint8Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat4dDiffShapeDim1TestImpl<DataType::QAsymmU8>(
        workloadFactory, memoryManager, 0.5f, -1);
}

LayerTestResult<uint8_t, 4> Concat4dDiffShapeDim2Uint8Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return Concat4dDiffShapeDim2TestImpl<DataType::QAsymmU8>(
        workloadFactory, memoryManager, 0.5f, -1);
}

LayerTestResult<uint8_t, 4> Concat4dDiffShapeDim3Uint8Test(
    IWorkloadFactory& workloadFactory,
    const IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
    bool useSubtensor)
{
    return Concat4dDiffShapeDim3TestImpl<DataType::QAsymmU8>(
        workloadFactory, memoryManager, 0.5f, -1, useSubtensor);
}
