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

#include "RefComparisonWorkload.hpp"

#include "Decoders.hpp"
#include "ElementwiseFunction.hpp"
#include "Encoders.hpp"
#include "RefWorkloadUtils.hpp"

#include <Profiling.hpp>

#include <armnn/TypesUtils.hpp>

#include <functional>

namespace armnn
{

RefComparisonWorkload::RefComparisonWorkload(const ComparisonQueueDescriptor& desc,
                                             const WorkloadInfo& info)
    : RefBaseWorkload<ComparisonQueueDescriptor>(desc, info)
{}

void RefComparisonWorkload::PostAllocationConfigure()
{
    PostAllocationConfigure(m_Data.m_Inputs, m_Data.m_Outputs);
}

void RefComparisonWorkload::PostAllocationConfigure(std::vector<ITensorHandle*> inputs,
                                                    std::vector<ITensorHandle*> outputs)
{
    const TensorInfo& inputInfo0 = GetTensorInfo(inputs[0]);
    const TensorInfo& inputInfo1 = GetTensorInfo(inputs[1]);
    const TensorInfo& outputInfo = GetTensorInfo(outputs[0]);

    m_Input0 = MakeDecoder<InType>(inputInfo0);
    m_Input1 = MakeDecoder<InType>(inputInfo1);

    m_Output = MakeEncoder<OutType>(outputInfo);
}

void RefComparisonWorkload::Execute() const
{
    Execute(m_Data.m_Inputs, m_Data.m_Outputs);
}

void RefComparisonWorkload::ExecuteAsync(ExecutionData& executionData)
{
    WorkingMemDescriptor* workingMemDescriptor = static_cast<WorkingMemDescriptor*>(executionData.m_Data);

    PostAllocationConfigure(workingMemDescriptor->m_Inputs, workingMemDescriptor->m_Outputs);
    Execute(workingMemDescriptor->m_Inputs, workingMemDescriptor->m_Outputs);
}

void RefComparisonWorkload::Execute(std::vector<ITensorHandle*> inputs, std::vector<ITensorHandle*> outputs) const
{
    ARMNN_SCOPED_PROFILING_EVENT(Compute::CpuRef, "RefComparisonWorkload_Execute");

    const TensorInfo& inputInfo0 = GetTensorInfo(inputs[0]);
    const TensorInfo& inputInfo1 = GetTensorInfo(inputs[1]);
    const TensorInfo& outputInfo = GetTensorInfo(outputs[0]);

    const TensorShape& inShape0 = inputInfo0.GetShape();
    const TensorShape& inShape1 = inputInfo1.GetShape();
    const TensorShape& outShape = outputInfo.GetShape();

    m_Input0->Reset(inputs[0]->Map());
    m_Input1->Reset(inputs[1]->Map());
    m_Output->Reset(outputs[0]->Map());

    using EqualFunction          = ElementwiseBinaryFunction<std::equal_to<InType>>;
    using GreaterFunction        = ElementwiseBinaryFunction<std::greater<InType>>;
    using GreaterOrEqualFunction = ElementwiseBinaryFunction<std::greater_equal<InType>>;
    using LessFunction           = ElementwiseBinaryFunction<std::less<InType>>;
    using LessOrEqualFunction    = ElementwiseBinaryFunction<std::less_equal<InType>>;
    using NotEqualFunction       = ElementwiseBinaryFunction<std::not_equal_to<InType>>;

    switch (m_Data.m_Parameters.m_Operation)
    {
        case ComparisonOperation::Equal:
        {
            EqualFunction(inShape0, inShape1, outShape, *m_Input0, *m_Input1, *m_Output);
            break;
        }
        case ComparisonOperation::Greater:
        {
            GreaterFunction(inShape0, inShape1, outShape, *m_Input0, *m_Input1, *m_Output);
            break;
        }
        case ComparisonOperation::GreaterOrEqual:
        {
            GreaterOrEqualFunction(inShape0, inShape1, outShape, *m_Input0, *m_Input1, *m_Output);
            break;
        }
        case ComparisonOperation::Less:
        {
            LessFunction(inShape0, inShape1, outShape, *m_Input0, *m_Input1, *m_Output);
            break;
        }
        case ComparisonOperation::LessOrEqual:
        {
            LessOrEqualFunction(inShape0, inShape1, outShape, *m_Input0, *m_Input1, *m_Output);
            break;
        }
        case ComparisonOperation::NotEqual:
        {
            NotEqualFunction(inShape0, inShape1, outShape, *m_Input0, *m_Input1, *m_Output);
            break;
        }
        default:
        {
            throw InvalidArgumentException(std::string("Unsupported comparison operation ") +
                GetComparisonOperationAsCString(m_Data.m_Parameters.m_Operation), CHECK_LOCATION());
        }
    }
}

} // namespace armnn
