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

#include <reference/workloads/Decoders.hpp>
#include <armnn/utility/NumericCast.hpp>

#include <fmt/format.h>

#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_SUITE(RefPerChannelDecoder)

template<typename T>
void CompareVector(std::vector<T> vec1, std::vector<T> vec2)
{
    BOOST_TEST(vec1.size() == vec2.size());

    bool mismatch = false;
    for (uint i = 0; i < vec1.size(); ++i)
    {
        if (vec1[i] != vec2[i])
        {
            /*std::stringstream ss;
            ss << "Vector value mismatch: index=" << i << "  " <<  vec1[i] << "!=" << vec2[i];*/
            BOOST_TEST_MESSAGE(fmt::format("Vector value mismatch: index={}  {} != {}",
                                           i,
                                           vec1[i],
                                           vec2[i]));
            mismatch = true;
        }
    }

    if (mismatch)
    {
        BOOST_FAIL("Error in CompareVector. Vectors don't match.");
    }
}

// Ensure quantization works for none depthwise convolutions
BOOST_AUTO_TEST_CASE(RefPerChannelDecoderTest1)
{
    using namespace armnn;
    std::vector<int8_t> input =
    {
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23
    };

    std::vector<float> expOutput =
    {
        0.0f,   1.0f,  2.0f,  3.0f,  4.0f,  5.0f,  6.0f,  7.0f,  8.0f,  9.0f, 10.0f, 11.0f,
        24.0f, 26.0f, 28.0f, 30.0f, 32.0f, 34.0f, 36.0f, 38.0f, 40.0f, 42.0f, 44.0f, 46.0f
    };

    TensorInfo tensorInfo ({2,2,2,3},DataType::QSymmS8,{1.0f, 2.0f},0);
    auto decoder = MakeDecoder<float>(tensorInfo, input.data());

    std::vector<float> output = decoder->DecodeTensor(tensorInfo.GetShape());

    CompareVector(output, expOutput);
}

// Ensure quantization works for depthwise convolutions M=1
BOOST_AUTO_TEST_CASE(RefPerChannelDecoderTest2)
{
    using namespace armnn;
    std::vector<int8_t> input =
    {
        0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15
    };

    std::vector<float> expOutput =
    {
         0.0f,  1.0f,  2.0f,  3.0f,
         8.0f, 10.0f, 12.0f, 14.0f,
        24.0f, 27.0f, 30.0f, 33.0f,
        48.0f, 52.0f, 56.0f, 60.0f
    };

    // [O,1,H,W] = [I*M,1,H,W] = [4*1,1,2,2]
    TensorInfo tensorInfo ({4,1,2,2},DataType::QSymmS8,{1.0f, 2.0f, 3.0f, 4.0f},0);
    auto decoder = MakeDecoder<float>(tensorInfo, input.data());

    std::vector<float> output = decoder->DecodeTensor(tensorInfo.GetShape(), true);

    CompareVector(output, expOutput);
}

// Ensure quantization works for depthwise convolutions M=2
BOOST_AUTO_TEST_CASE(RefPerChannelDecoderTest3)
{
    using namespace armnn;
    std::vector<int8_t> input =
    {
        0, 1, 2, 3,
        4, 5, 6, 7,
        8, 9, 10, 11,
        12, 13, 14, 15,
        16, 17, 18, 19,
        20, 21, 22, 23
    };

    std::vector<float> expOutput =
    {
         0.0f,  1.0f,  2.0f,  3.0f,
         8.0f, 10.0f, 12.0f, 14.0f,
        24.0f, 27.0f, 30.0f, 33.0f,
        48.0f, 52.0f, 56.0f, 60.0f,
        80.0f, 85.0f, 90.0f, 95.0f,
        120.0f, 126.0f, 132.0f, 138.0f
    };

    // [O,1,H,W] = [I*M,1,H,W] = [3*2,1,2,2]
    TensorInfo tensorInfo ({6,1,2,2},DataType::QSymmS8,{1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f},0);
    auto decoder = MakeDecoder<float>(tensorInfo, input.data());

    std::vector<float> output = decoder->DecodeTensor(tensorInfo.GetShape(), true);

    CompareVector(output, expOutput);
}

// Ensure quantization works for depthwise convolutions M=2 for int32
BOOST_AUTO_TEST_CASE(RefPerChannelDecoderTest4)
{
    using namespace armnn;
    std::vector<int32_t> input =
    {
        0, 1, 2, 3,
        4, 5, 6, 7,
        8, 9, 10, 11,
        12, 13, 14, 15,
        16, 17, 18, 19,
        20, 21, 22, 23
    };

    std::vector<float> expOutput =
    {
         0.0f,  1.0f,  2.0f,  3.0f,
         8.0f, 10.0f, 12.0f, 14.0f,
        24.0f, 27.0f, 30.0f, 33.0f,
        48.0f, 52.0f, 56.0f, 60.0f,
        80.0f, 85.0f, 90.0f, 95.0f,
        120.0f, 126.0f, 132.0f, 138.0f
    };

    // [O,1,H,W] = [I*M,1,H,W] = [3*2,1,2,2]
    TensorInfo tensorInfo ({6,1,2,2},DataType::Signed32,{1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f},0);
    auto decoder = MakeDecoder<float>(tensorInfo, input.data());

    std::vector<float> output = decoder->DecodeTensor(tensorInfo.GetShape(), true);

    CompareVector(output, expOutput);
}

BOOST_AUTO_TEST_SUITE_END()
