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

#include "RefElementwiseUnaryWorkload.hpp"

#include "Decoders.hpp"
#include "ElementwiseFunction.hpp"
#include "Encoders.hpp"
#include "RefWorkloadUtils.hpp"
#include "Abs.hpp"
#include "Exp.hpp"
#include "Rsqrt.hpp"
#include "Sqrt.hpp"

#include <Profiling.hpp>

#include <armnn/TypesUtils.hpp>

#include <functional>

namespace armnn
{

RefElementwiseUnaryWorkload::RefElementwiseUnaryWorkload(const ElementwiseUnaryQueueDescriptor& desc,
                                                         const WorkloadInfo& info)
    : BaseWorkload<ElementwiseUnaryQueueDescriptor>(desc, info)
{}

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

void RefElementwiseUnaryWorkload::ExecuteAsync(WorkingMemDescriptor &workingMemDescriptor)
{

    Execute(workingMemDescriptor.m_Inputs, workingMemDescriptor.m_Outputs);
}

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

    const TensorInfo& inputInfo = GetTensorInfo(inputs[0]);
    const TensorInfo& outputInfo = GetTensorInfo(outputs[0]);

    const TensorShape& inShape = inputInfo.GetShape();
    const TensorShape& outShape = outputInfo.GetShape();

    std::unique_ptr<Decoder<InType>>  input = MakeDecoder<InType>(inputInfo, inputs[0]->Map());
    std::unique_ptr<Encoder<OutType>> output= MakeEncoder<OutType>(outputInfo, outputs[0]->Map());

    using AbsFunction   = ElementwiseUnaryFunction<abs<InType>>;
    using ExpFunction   = ElementwiseUnaryFunction<exp<InType>>;
    using NegFunction   = ElementwiseUnaryFunction<std::negate<InType>>;
    using RsqrtFunction = ElementwiseUnaryFunction<rsqrt<InType>>;
    using SqrtFunction  = ElementwiseUnaryFunction<sqrt<InType>>;

    switch (m_Data.m_Parameters.m_Operation)
    {
        case UnaryOperation::Abs:
        {
            AbsFunction(inShape, outShape, *input, *output);
            break;
        }
        case UnaryOperation::Exp:
        {
            ExpFunction(inShape, outShape, *input, *output);
            break;
        }
        case UnaryOperation::Neg:
        {
            NegFunction(inShape, outShape, *input, *output);
            break;
        }
        case UnaryOperation::Rsqrt:
        {
            RsqrtFunction(inShape, outShape, *input, *output);
            break;
        }
        case UnaryOperation::Sqrt:
        {
            SqrtFunction(inShape, outShape, *input, *output);
            break;
        }
        default:
        {
            throw InvalidArgumentException(std::string("Unsupported unary operation ") +
                GetUnaryOperationAsCString(m_Data.m_Parameters.m_Operation), CHECK_LOCATION());
        }
    }
}

} // namespace armnn
