/*
 * Copyright (c) 2018-2023 Arm Limited.
 *
 * SPDX-License-Identifier: MIT
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
#include "src/cpu/kernels/CpuElementwiseUnaryKernel.h"

#include "arm_compute/core/Error.h"
#include "arm_compute/core/Helpers.h"
#include "arm_compute/core/ITensor.h"
#include "arm_compute/core/Utils.h"
#include "arm_compute/core/Validate.h"

#include "src/core/common/Registrars.h"
#include "src/core/CPP/Validate.h"
#include "src/core/helpers/AutoConfiguration.h"
#include "src/core/helpers/WindowHelpers.h"
#include "src/cpu/kernels/elementwise_unary/list.h"
#include "support/ToolchainSupport.h"

namespace arm_compute
{
namespace cpu
{
namespace kernels
{
namespace
{
#ifdef __aarch64__

std::unique_ptr<uint8_t[]> q8_prepare_lut(ElementWiseUnary op, const ITensorInfo *src, const ITensorInfo *dst)
{
    ARM_COMPUTE_ERROR_ON(src->data_type() != dst->data_type());
    ARM_COMPUTE_ERROR_ON(!is_data_type_quantized(src->data_type()));
    ARM_COMPUTE_ERROR_ON(src->element_size() != 1);

    auto       lut       = std::unique_ptr<uint8_t[]>(new uint8_t[256]);
    const auto is_signed = src->data_type() == DataType::QASYMM8_SIGNED;
    const auto src_qi    = src->quantization_info().uniform();
    const auto dst_qi    = dst->quantization_info().uniform();

    const auto dst_min_fp = (((is_signed) ? -128 : 0) - dst_qi.offset) * dst_qi.scale;
    const auto dst_max_fp = (((is_signed) ? 127 : 255) - dst_qi.offset) * dst_qi.scale;

    for (int i = 0; i < 256; ++i)
    {
        const auto in =
            (is_signed) ? dequantize_qasymm8_signed(static_cast<int8_t>(i), src_qi) : dequantize_qasymm8(i, src_qi);
        float result = 0;

        switch (op)
        {
            case ElementWiseUnary::RSQRT:
                result = 1 / sqrt(in);
                break;

            case ElementWiseUnary::EXP:
                result = std::exp(in);
                break;

            case ElementWiseUnary::NEG:
                result = -in;
                break;

            case ElementWiseUnary::LOG:
                result = std::log(in);
                break;

            case ElementWiseUnary::ABS:
                result = std::abs(in);
                break;

            case ElementWiseUnary::ROUND:
                result = support::cpp11::nearbyint(in);
                break;

            case ElementWiseUnary::SIN:
                result = std::sin(in);
                break;

            default:
                ARM_COMPUTE_ERROR("NOT_SUPPORTED!");
        }

        result = utility::clamp(result, dst_min_fp, dst_max_fp);

        const auto out = (is_signed) ? static_cast<uint8_t>(quantize_qasymm8_signed(result, dst_qi))
                                     : quantize_qasymm8(result, dst_qi);
        lut[i]         = out;
    }

    return lut;
}

#endif // __aarch64__

static const std::vector<CpuElementwiseUnaryKernel::ElementwiseUnaryKernel> available_kernels = {
    {
        "sve_fp32_elementwise_unary",
        [](const DataTypeISASelectorData &data) { return (data.dt == DataType::F32 && data.isa.sve); },
        REGISTER_FP32_SVE(sve_fp32_elementwise_unary),
        nullptr,
    },
    {
        "sve_fp16_elementwise_unary",
        [](const DataTypeISASelectorData &data) { return (data.dt == DataType::F16 && data.isa.sve && data.isa.fp16); },
        REGISTER_FP16_SVE(sve_fp16_elementwise_unary),
        nullptr,
    },
    {
        "sve_s32_elementwise_unary",
        [](const DataTypeISASelectorData &data) { return (data.dt == DataType::S32 && data.isa.sve); },
        REGISTER_INTEGER_SVE(sve_s32_elementwise_unary),
        nullptr,
    },
    {
        "neon_fp32_elementwise_unary",
        [](const DataTypeISASelectorData &data) { return data.dt == DataType::F32; },
        REGISTER_FP32_NEON(neon_fp32_elementwise_unary),
        nullptr,
    },
    {
        "neon_fp16_elementwise_unary",
        [](const DataTypeISASelectorData &data) { return data.dt == DataType::F16 && data.isa.fp16; },
        REGISTER_FP16_NEON(neon_fp16_elementwise_unary),
        nullptr,
    },
    {
        "neon_s32_elementwise_unary",
        [](const DataTypeISASelectorData &data) { return data.dt == DataType::S32; },
        REGISTER_INTEGER_NEON(neon_s32_elementwise_unary),
        nullptr,
    },
#ifdef __aarch64__
    {
        "sve2_q8_elementwise_unary",
        [](const DataTypeISASelectorData &data)
        { return (data.dt == DataType::QASYMM8 || data.dt == DataType::QASYMM8_SIGNED) && data.isa.sve2; },
        REGISTER_QASYMM8_SVE2(sve2_q8_elementwise_unary),
        &q8_prepare_lut,
    },
    {
        "neon_q8_elementwise_unary",
        [](const DataTypeISASelectorData &data)
        { return data.dt == DataType::QASYMM8 || data.dt == DataType::QASYMM8_SIGNED; },
        REGISTER_QASYMM8_NEON(neon_q8_elementwise_unary),
        &q8_prepare_lut,
    },
#else  // __aarch64__
    {
        "neon_qasymm8_signed_elementwise_unary",
        [](const DataTypeISASelectorData &data) { return data.dt == DataType::QASYMM8_SIGNED; },
        REGISTER_QASYMM8_SIGNED_NEON(neon_qasymm8_signed_elementwise_unary),
        nullptr,
    },
    {
        "neon_qasymm8_elementwise_unary",
        [](const DataTypeISASelectorData &data) { return data.dt == DataType::QASYMM8; },
        REGISTER_QASYMM8_NEON(neon_qasymm8_elementwise_unary),
        nullptr,
    },
#endif // __aarch64__
};

} // namespace

void CpuElementwiseUnaryKernel::configure(ElementWiseUnary op, const ITensorInfo &src, ITensorInfo &dst)
{
    ARM_COMPUTE_ERROR_THROW_ON(validate(op, src, dst));
    const auto uk = CpuElementwiseUnaryKernel::get_implementation(
        DataTypeISASelectorData{src.data_type(), CPUInfo::get().get_isa()});
    ARM_COMPUTE_ERROR_ON(uk == nullptr || uk->ukernel == nullptr);

    _op         = op;
    _run_method = uk->ukernel;
    _name       = std::string("CpuElementwiseUnaryKernel").append("/").append(uk->name);

    // If input shape is dynamic, expect a configured window and dst at run-time.
    if (src.is_dynamic())
    {
        return;
    }

    if (uk->prepare_func != nullptr)
    {
        _lut = uk->prepare_func(op, &src, &dst);
    }

    auto shape_and_window = compute_output_shape_and_window(src.tensor_shape());
    auto_init_if_empty(dst, shape_and_window.first, 1, src.data_type());
    ICpuKernel::configure(shape_and_window.second);
}

Status CpuElementwiseUnaryKernel::validate(ElementWiseUnary op, const ITensorInfo &src, const ITensorInfo &dst)
{
    ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED(&src);

    const auto *uk = CpuElementwiseUnaryKernel::get_implementation(
        DataTypeISASelectorData{src.data_type(), CPUInfo::get().get_isa()});

    ARM_COMPUTE_RETURN_ERROR_ON(uk == nullptr || uk->ukernel == nullptr);

    switch (op)
    {
        case ElementWiseUnary::EXP:
        case ElementWiseUnary::RSQRT:
        case ElementWiseUnary::LOG:
        case ElementWiseUnary::ROUND:
        case ElementWiseUnary::SIN:
            ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&src, 1, DataType::F16, DataType::F32,
                                                                 DataType::QASYMM8, DataType::QASYMM8_SIGNED);
            break;
        case ElementWiseUnary::NEG:
        case ElementWiseUnary::ABS:
            ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(&src, 1, DataType::F16, DataType::F32, DataType::S32,
                                                                 DataType::QASYMM8, DataType::QASYMM8_SIGNED);
            break;
        default:
            ARM_COMPUTE_ERROR("ElementWiseUnary operation not supported");
    }
    // Validate in case of configured dst
    if (dst.total_size() > 0)
    {
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(&src, &dst);
    }

    return Status{};
}

void CpuElementwiseUnaryKernel::run_op(ITensorPack &tensors, const Window &window, const ThreadInfo &info)
{
    ARM_COMPUTE_UNUSED(info);

    auto src = tensors.get_const_tensor(TensorType::ACL_SRC);
    auto dst = tensors.get_tensor(TensorType::ACL_DST);

    _run_method(src, dst, window, _op, _lut.get());
}

const char *CpuElementwiseUnaryKernel::name() const
{
    return _name.c_str();
}

const std::vector<CpuElementwiseUnaryKernel::ElementwiseUnaryKernel> &CpuElementwiseUnaryKernel::get_available_kernels()
{
    return available_kernels;
}

} // namespace kernels
} // namespace cpu
} // namespace arm_compute
