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

#include "StackTestImpl.hpp"
#include "LayerTestResult.hpp"

#include <ResolveType.hpp>


#include <armnn/backends/IBackendInternal.hpp>
#include <backendsCommon/WorkloadFactory.hpp>

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

#include <test/TensorHelpers.hpp>

namespace
{

template<armnn::DataType ArmnnType, typename T, std::size_t outputDimLength>
LayerTestResult<T, outputDimLength> StackTestHelper(
        armnn::IWorkloadFactory& workloadFactory,
        const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager,
        const armnn::TensorInfo& inputTensorInfo,
        const armnn::TensorInfo& outputTensorInfo,
        unsigned int axis,
        const std::vector<std::vector<T>>& inputData,
        const std::vector<T>& outputExpectedData)
{
    IgnoreUnused(memoryManager);
    unsigned int numInputs = static_cast<unsigned int>(inputData.size());
    std::vector<boost::multi_array<T, outputDimLength-1>> inputs;
    for (unsigned int i = 0; i < numInputs; ++i)
    {
        inputs.push_back(MakeTensor<T, outputDimLength-1>(inputTensorInfo, inputData[i]));
    }

    LayerTestResult<T, outputDimLength> result(outputTensorInfo);
    result.outputExpected = MakeTensor<T, outputDimLength>(outputTensorInfo, outputExpectedData);

    std::vector<std::unique_ptr<armnn::ITensorHandle>> inputHandles;
    ARMNN_NO_DEPRECATE_WARN_BEGIN
    for (unsigned int i = 0; i < numInputs; ++i)
    {
        inputHandles.push_back(workloadFactory.CreateTensorHandle(inputTensorInfo));
    }
    std::unique_ptr<armnn::ITensorHandle> outputHandle = workloadFactory.CreateTensorHandle(outputTensorInfo);
    ARMNN_NO_DEPRECATE_WARN_END

    armnn::StackQueueDescriptor descriptor;
    descriptor.m_Parameters.m_Axis = axis;
    descriptor.m_Parameters.m_InputShape = inputTensorInfo.GetShape();
    descriptor.m_Parameters.m_NumInputs = numInputs;

    armnn::WorkloadInfo info;
    for (unsigned int i = 0; i < numInputs; ++i)
    {
        std::unique_ptr<armnn::ITensorHandle>& inputHandle = inputHandles[i];
        AddInputToWorkload(descriptor, info, inputTensorInfo, inputHandle.get());
        inputHandle->Allocate();
        CopyDataToITensorHandle(inputHandle.get(), inputs[i].origin());
    }

    AddOutputToWorkload(descriptor, info, outputTensorInfo, outputHandle.get());
    outputHandle->Allocate();

    std::unique_ptr<armnn::IWorkload> workload = workloadFactory.CreateStack(descriptor, info);

    workload->Execute();

    CopyDataFromITensorHandle(result.output.origin(), outputHandle.get());

    return result;
}

} // anonymous namespace

//
// Implementation templates
//

template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
LayerTestResult<T, 4> StackAxis0TestImpl(
        armnn::IWorkloadFactory& workloadFactory,
        const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    armnn::TensorInfo inputTensorInfo ({ 3, 2, 3 }, ArmnnType);
    armnn::TensorInfo outputTensorInfo({ 2, 3, 2, 3 }, ArmnnType);

    std::vector<std::vector<T>> inputData;

    inputData.push_back(
    {
        1, 2, 3,
        4, 5, 6,

        7, 8, 9,
        10, 11, 12,

        13, 14, 15,
        16, 17, 18
    });

    inputData.push_back(
    {
        19, 20, 21,
        22, 23, 24,

        25, 26, 27,
        28, 29, 30,

        31, 32, 33,
        34, 35, 36
    });

    std::vector<T> outputExpectedData =
    {
        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
    };

    return StackTestHelper<ArmnnType, T, 4>(
        workloadFactory,
        memoryManager,
        inputTensorInfo,
        outputTensorInfo,
        0U,
        inputData,
        outputExpectedData
    );
}

template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
LayerTestResult<T, 4> StackOutput4DAxis1TestImpl(
        armnn::IWorkloadFactory& workloadFactory,
        const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    armnn::TensorInfo inputTensorInfo ({ 3, 2, 3 }, ArmnnType);
    armnn::TensorInfo outputTensorInfo({ 3, 2, 2, 3 }, ArmnnType);

    std::vector<std::vector<T>> inputData;

    inputData.push_back(
    {
        1, 2, 3,
        4, 5, 6,

        7, 8, 9,
        10, 11, 12,

        13, 14, 15,
        16, 17, 18
    });

    inputData.push_back(
    {
        19, 20, 21,
        22, 23, 24,

        25, 26, 27,
        28, 29, 30,

        31, 32, 33,
        34, 35, 36
    });

    std::vector<T> outputExpectedData =
    {
        1, 2, 3,
        4, 5, 6,

        19, 20, 21,
        22, 23, 24,


        7, 8, 9,
        10, 11, 12,

        25, 26, 27,
        28, 29, 30,


        13, 14, 15,
        16, 17, 18,

        31, 32, 33,
        34, 35, 36
    };

    return StackTestHelper<ArmnnType, T, 4>(
        workloadFactory,
        memoryManager,
        inputTensorInfo,
        outputTensorInfo,
        1U,
        inputData,
        outputExpectedData
    );
}

template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
LayerTestResult<T, 4> StackOutput4DAxis2TestImpl(
        armnn::IWorkloadFactory& workloadFactory,
        const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    armnn::TensorInfo inputTensorInfo ({ 3, 2, 3 }, ArmnnType);
    armnn::TensorInfo outputTensorInfo({ 3, 2, 2, 3 }, ArmnnType);

    std::vector<std::vector<T>> inputData;

    inputData.push_back(
    {
        1, 2, 3,
        4, 5, 6,

        7, 8, 9,
        10, 11, 12,

        13, 14, 15,
        16, 17, 18
    });

    inputData.push_back(
    {
        19, 20, 21,
        22, 23, 24,

        25, 26, 27,
        28, 29, 30,

        31, 32, 33,
        34, 35, 36
    });

    std::vector<T> outputExpectedData =
    {
        1, 2, 3,
        19, 20, 21,

        4, 5, 6,
        22, 23, 24,

        7, 8, 9,
        25, 26, 27,

        10, 11, 12,
        28, 29, 30,

        13, 14, 15,
        31, 32, 33,

        16, 17, 18,
        34, 35, 36
    };

    return StackTestHelper<ArmnnType, T, 4>(
        workloadFactory,
        memoryManager,
        inputTensorInfo,
        outputTensorInfo,
        2U,
        inputData,
        outputExpectedData
    );
}

template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
LayerTestResult<T, 4> StackOutput4DAxis3TestImpl(
        armnn::IWorkloadFactory& workloadFactory,
        const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    armnn::TensorInfo inputTensorInfo ({ 3, 2, 3 }, ArmnnType);
    armnn::TensorInfo outputTensorInfo({ 3, 2, 3, 2 }, ArmnnType);

    std::vector<std::vector<T>> inputData;

    inputData.push_back(
    {
        1, 2, 3,
        4, 5, 6,

        7, 8, 9,
        10, 11, 12,

        13, 14, 15,
        16, 17, 18
    });

    inputData.push_back(
    {
        19, 20, 21,
        22, 23, 24,

        25, 26, 27,
        28, 29, 30,

        31, 32, 33,
        34, 35, 36
    });

    std::vector<T> outputExpectedData =
    {
        1, 19,
        2, 20,
        3, 21,

        4, 22,
        5, 23,
        6, 24,


        7, 25,
        8, 26,
        9, 27,

        10, 28,
        11, 29,
        12, 30,


        13, 31,
        14, 32,
        15, 33,

        16, 34,
        17, 35,
        18, 36
    };

    return StackTestHelper<ArmnnType, T, 4>(
        workloadFactory,
        memoryManager,
        inputTensorInfo,
        outputTensorInfo,
        3U,
        inputData,
        outputExpectedData
    );
}

template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
LayerTestResult<T, 3> StackOutput3DInputs3TestImpl(
        armnn::IWorkloadFactory& workloadFactory,
        const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    armnn::TensorInfo inputTensorInfo ({ 3, 3 }, ArmnnType);
    armnn::TensorInfo outputTensorInfo({ 3, 3, 3 }, ArmnnType);

    std::vector<std::vector<T>> inputData;

    inputData.push_back(
    {
        1, 2, 3,
        4, 5, 6,
        7, 8, 9
    });

    inputData.push_back(
    {
        10, 11, 12,
        13, 14, 15,
        16, 17, 18
    });

    inputData.push_back(
    {
        19, 20, 21,
        22, 23, 24,
        25, 26, 27
    });

    std::vector<T> outputExpectedData =
    {
        1, 2, 3,
        10, 11, 12,
        19, 20, 21,

        4, 5, 6,
        13, 14, 15,
        22, 23, 24,

        7, 8, 9,
        16, 17, 18,
        25, 26, 27
    };

    return StackTestHelper<ArmnnType, T, 3>(
        workloadFactory,
        memoryManager,
        inputTensorInfo,
        outputTensorInfo,
        1U,
        inputData,
        outputExpectedData
    );
}

template<armnn::DataType ArmnnType, typename T = armnn::ResolveType<ArmnnType>>
LayerTestResult<T, 5> StackOutput5DTestImpl(
        armnn::IWorkloadFactory& workloadFactory,
        const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    armnn::TensorInfo inputTensorInfo ({ 2, 2, 2, 3 }, ArmnnType);
    armnn::TensorInfo outputTensorInfo({ 2, 2, 2, 2, 3 }, ArmnnType);

    std::vector<std::vector<T>> inputData;

    inputData.push_back(
    {
        1, 2, 3,
        4, 5, 6,

        7, 8, 9,
        10, 11, 12,


        13, 14, 15,
        16, 17, 18,

        19, 20, 21,
        22, 23, 24
    });

    inputData.push_back(
    {
        25, 26, 27,
        28, 29, 30,

        31, 32, 33,
        34, 35, 36,


        37, 38, 39,
        40, 41, 42,

        43, 44, 45,
        46, 47, 48
    });

    std::vector<T> outputExpectedData =
    {
        1, 2, 3,
        4, 5, 6,

        7, 8, 9,
        10, 11, 12,


        25, 26, 27,
        28, 29, 30,

        31, 32, 33,
        34, 35, 36,



        13, 14, 15,
        16, 17, 18,

        19, 20, 21,
        22, 23, 24,


        37, 38, 39,
        40, 41, 42,

        43, 44, 45,
        46, 47, 48

    };

    return StackTestHelper<ArmnnType, T, 5>(
        workloadFactory,
        memoryManager,
        inputTensorInfo,
        outputTensorInfo,
        1U,
        inputData,
        outputExpectedData
    );
}

//
// Implementation functions
//

LayerTestResult<float, 4> StackAxis0Float32Test(
        armnn::IWorkloadFactory& workloadFactory,
        const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return StackAxis0TestImpl<armnn::DataType::Float32>(workloadFactory, memoryManager);
}

LayerTestResult<float, 4> StackOutput4DAxis1Float32Test(
        armnn::IWorkloadFactory& workloadFactory,
        const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return StackOutput4DAxis1TestImpl<armnn::DataType::Float32>(workloadFactory, memoryManager);
}

LayerTestResult<float, 4> StackOutput4DAxis2Float32Test(
        armnn::IWorkloadFactory& workloadFactory,
        const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return StackOutput4DAxis2TestImpl<armnn::DataType::Float32>(workloadFactory, memoryManager);
}

LayerTestResult<float, 4> StackOutput4DAxis3Float32Test(
        armnn::IWorkloadFactory& workloadFactory,
        const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return StackOutput4DAxis3TestImpl<armnn::DataType::Float32>(workloadFactory, memoryManager);
}

LayerTestResult<float, 3> StackOutput3DInputs3Float32Test(
        armnn::IWorkloadFactory& workloadFactory,
        const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return StackOutput3DInputs3TestImpl<armnn::DataType::Float32>(workloadFactory, memoryManager);
}

LayerTestResult<float, 5> StackOutput5DFloat32Test(
        armnn::IWorkloadFactory& workloadFactory,
        const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    return StackOutput5DTestImpl<armnn::DataType::Float32>(workloadFactory, memoryManager);
}

LayerTestResult<armnn::Half, 4> StackFloat16Test(
        armnn::IWorkloadFactory& workloadFactory,
        const armnn::IBackendInternal::IMemoryManagerSharedPtr& memoryManager)
{
    using namespace half_float::literal;

    armnn::TensorInfo inputTensorInfo ({ 3, 2, 3 }, armnn::DataType::Float16);
    armnn::TensorInfo outputTensorInfo({ 3, 2, 2, 3 }, armnn::DataType::Float16);

    std::vector<std::vector<armnn::Half>> inputData;

    inputData.push_back(
    {
        1.0_h,  2.0_h,  3.0_h,
        4.0_h,  5.0_h,  6.0_h,

        7.0_h,  8.0_h,  9.0_h,
        10.0_h, 11.0_h, 12.0_h,

        13.0_h, 14.0_h, 15.0_h,
        16.0_h, 17.0_h, 18.0_h
    });

    inputData.push_back(
    {
        19.0_h, 20.0_h, 21.0_h,
        22.0_h, 23.0_h, 24.0_h,

        25.0_h, 26.0_h, 27.0_h,
        28.0_h, 29.0_h, 30.0_h,

        31.0_h, 32.0_h, 33.0_h,
        34.0_h, 35.0_h, 36.0_h
    });

    std::vector<armnn::Half> outputExpectedData =
    {
        1.0_h,  2.0_h,  3.0_h,
        19.0_h, 20.0_h, 21.0_h,

        4.0_h,  5.0_h,  6.0_h,
        22.0_h, 23.0_h, 24.0_h,

        7.0_h,  8.0_h,  9.0_h,
        25.0_h, 26.0_h, 27.0_h,

        10.0_h, 11.0_h, 12.0_h,
        28.0_h, 29.0_h, 30.0_h,

        13.0_h, 14.0_h, 15.0_h,
        31.0_h, 32.0_h, 33.0_h,

        16.0_h, 17.0_h, 18.0_h,
        34.0_h, 35.0_h, 36.0_h
    };

    return StackTestHelper<armnn::DataType::Float16, armnn::Half, 4>(
        workloadFactory,
        memoryManager,
        inputTensorInfo,
        outputTensorInfo,
        2U,
        inputData,
        outputExpectedData
    );
}