/*
 * Copyright (c) 2017-2021 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/CpuDirectConv2dOutputStageKernel.h"

#include "arm_compute/core/Error.h"
#include "arm_compute/core/Helpers.h"
#include "arm_compute/core/ITensor.h"
#include "arm_compute/core/Types.h"
#include "arm_compute/core/Validate.h"
#include "arm_compute/core/Window.h"
#include "arm_compute/core/utils/misc/Traits.h"
#include "src/core/CPP/Validate.h"
#include "src/core/NEON/NEAsymm.h"
#include "src/core/NEON/NEFixedPoint.h"
#include "src/core/NEON/wrapper/wrapper.h"
#include "src/core/helpers/AutoConfiguration.h"
#include "src/core/helpers/WindowHelpers.h"

#include <arm_neon.h>
#include <cstddef>
#include <cstdint>

namespace arm_compute
{
namespace cpu
{
namespace kernels
{
namespace
{
Status validate_arguments(const ITensorInfo *src, const ITensorInfo *bias, const ITensorInfo *dst,
                          const DirectConvolutionLayerOutputStageKernelInfo &info)
{
    ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(src);
    ARM_COMPUTE_RETURN_ERROR_ON_CPU_F16_UNSUPPORTED(src);
    ARM_COMPUTE_RETURN_ERROR_ON(src->data_layout() == DataLayout::UNKNOWN);
    ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(src, 1, DataType::F16, DataType::S32, DataType::F32);

    if(bias != nullptr)
    {
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(src, bias);
        ARM_COMPUTE_RETURN_ERROR_ON(bias->dimension(0) != src->dimension(get_data_layout_dimension_index(src->data_layout(), DataLayoutDimension::CHANNEL)));
        ARM_COMPUTE_RETURN_ERROR_ON(bias->num_dimensions() > 1);
    }

    if(src->data_type() == DataType::S32)
    {
        ARM_COMPUTE_RETURN_ERROR_ON_MSG(dst == nullptr, "In-place computation not allowed for quantized output");
    }

    // Checks performed when output is configured
    if((dst != nullptr) && (dst->total_size() != 0))
    {
        if(is_data_type_float(src->data_type()))
        {
            ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(src, dst);
        }
        else
        {
            ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(dst, 1, DataType::QASYMM8, DataType::QASYMM8_SIGNED);
        }
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(src, dst);
    }
    else if(src->data_type() == DataType::S32)
    {
        // In case of quantized computation and unconfigured output, the output data type must be provided through DirectConvolutionLayerOutputStageKernelInfo
        ARM_COMPUTE_RETURN_ERROR_ON((info.output_data_type != DataType::QASYMM8) && (info.output_data_type != DataType::QASYMM8_SIGNED));
    }

    return Status{};
}

template <typename T>
typename std::enable_if<arm_compute::utils::traits::is_floating_point<T>::value, void>::type
output_stage_nchw(ITensor *src, const ITensor *bias, const Window &window, ITensor *dst,
                  int result_fixedpoint_multiplier, int result_shift, int result_offset_after_shift)
{
    const bool has_bias = bias != nullptr;
    /** SIMD vector tag type. */
    using ExactTagType = typename wrapper::traits::neon_bitvector_tag_t<T, wrapper::traits::BitWidth::W128>;

    ARM_COMPUTE_ERROR_ON(src->info()->data_layout() == DataLayout::UNKNOWN);
    ARM_COMPUTE_UNUSED(result_fixedpoint_multiplier);
    ARM_COMPUTE_UNUSED(result_shift);
    ARM_COMPUTE_UNUSED(result_offset_after_shift);

    const int window_start_x = window.x().start();
    const int window_end_x   = window.x().end();
    const int window_step_x  = 16 / src->info()->element_size();
    Window    win            = window;
    win.set(Window::DimX, Window::Dimension(0, 1, 1));

    Iterator in(src, win);
    Iterator out(dst, win);
    execute_window_loop(win, [&](const Coordinates & id)
    {
        int x = window_start_x;
        for(; x <= (window_end_x - window_step_x); x += window_step_x)
        {
            // Get bias and pointer to input
            const auto in_ptr = reinterpret_cast<const T *>(in.ptr()) + x;
            auto       v_in   = wrapper::vloadq(in_ptr);

            // Accumulate bias
            if(has_bias)
            {
                const auto vb = wrapper::vdup_n(*reinterpret_cast<const T *>(bias->ptr_to_element(Coordinates(id.z()))), ExactTagType{});
                v_in          = wrapper::vadd(v_in, vb);
            }

            const auto out_ptr = reinterpret_cast<T *>(out.ptr()) + x;
            wrapper::vstore(out_ptr, v_in);
        }

        // Left-overs loop
        for(; x < window_end_x; ++x)
        {
            // Get bias and pointer to input
            auto s_in = *(reinterpret_cast<const T *>(in.ptr()) + x);

            // Accumulate bias
            if(has_bias)
            {
                const auto b = *reinterpret_cast<const T *>(bias->ptr_to_element(Coordinates(id.z())));
                s_in += b;
            }

            *(reinterpret_cast<T *>(out.ptr()) + x) = s_in;
        }

    },
    in, out);
}

template <typename T>
typename std::enable_if<arm_compute::utils::traits::is_floating_point<T>::value, void>::type
output_stage_nhwc(ITensor *src, const ITensor *bias, const Window &window, ITensor *dst,
                  int result_fixedpoint_multiplier, int result_shift, int result_offset_after_shift)
{
    const bool has_bias = bias != nullptr;
    ARM_COMPUTE_UNUSED(result_fixedpoint_multiplier);
    ARM_COMPUTE_UNUSED(result_shift);
    ARM_COMPUTE_UNUSED(result_offset_after_shift);

    Window window_bias = window;
    window_bias.set(Window::DimX, Window::Dimension(0, 1, 1));
    window_bias.set(Window::DimY, Window::Dimension(0, 0, 0));
    window_bias.set(Window::DimZ, Window::Dimension(0, 0, 0));
    window_bias.set(3, Window::Dimension(0, 0, 0));

    const int window_start_x = window.x().start();
    const int window_end_x   = window.x().end();
    const int window_step_x  = 16 / src->info()->element_size();
    Window    win            = window;
    win.set(Window::DimX, Window::Dimension(0, 1, 1));

    Iterator in(src, win);
    Iterator bi(bias, window_bias);
    Iterator out(dst, win);

    execute_window_loop(win, [&](const Coordinates &)
    {
        int x = window_start_x;
        for(; x <= (window_end_x - window_step_x); x += window_step_x)
        {
            // Get bias and pointer to input
            const auto in_ptr = reinterpret_cast<const T *>(in.ptr());
            auto       v_in   = wrapper::vloadq(in_ptr + x);

            // Accumulate bias
            if(has_bias)
            {
                const auto bias_ptr = reinterpret_cast<T *>(bi.ptr()) + x;
                v_in                = wrapper::vadd(v_in, wrapper::vloadq(bias_ptr));
            }

            const auto out_ptr = reinterpret_cast<T *>(out.ptr());
            wrapper::vstore(out_ptr + x, v_in);
        }

        // Left-overs loop
        for(; x < window_end_x; ++x)
        {
            // Get bias and pointer to input
            auto s_in = *(reinterpret_cast<const T *>(in.ptr()) + x);

            // Accumulate bias
            if(has_bias)
            {
                const auto bias_ptr = reinterpret_cast<T *>(bi.ptr()) + x;
                s_in += *bias_ptr;
            }

            const auto out_ptr = reinterpret_cast<T *>(out.ptr());
            *(out_ptr + x)     = s_in;
        }
    },
    in, bi, out);
}

// Quantized case
template < typename TOut, typename std::enable_if < std::is_same<TOut, uint8_t>::value || std::is_same<TOut, int8_t>::value, int >::type = 0 >
void output_stage_nchw(ITensor *src, const ITensor *bias, const Window &window, ITensor *dst,
                       int result_fixedpoint_multiplier, int result_shift, int result_offset_after_shift)
{
    const bool has_bias = bias != nullptr;
    using VectorType    = typename wrapper::traits::neon_bitvector_t<TOut, wrapper::traits::BitWidth::W128>;
    using TagType       = typename wrapper::traits::neon_bitvector_tag_t<TOut, wrapper::traits::BitWidth::W128>;

    const int32x4_t result_offset_after_shift_s32 = vdupq_n_s32(result_offset_after_shift);

    const VectorType min = wrapper::vdup_n(std::numeric_limits<TOut>::lowest(), TagType{});
    const VectorType max = wrapper::vdup_n(std::numeric_limits<TOut>::max(), TagType{});

    const int window_start_x = window.x().start();
    const int window_end_x   = window.x().end();
    const int window_step_x  = 16 / src->info()->element_size();
    Window    win            = window;
    win.set(Window::DimX, Window::Dimension(0, 1, 1));

    Iterator in(src, win);
    Iterator out(dst, win);

    execute_window_loop(win, [&](const Coordinates & id)
    {

        int x = window_start_x;
        for(; x <= (window_end_x - window_step_x); x += window_step_x)
        {
            // Get bias and pointer to input
            const auto  in_ptr = reinterpret_cast<int32_t *>(in.ptr()) + x;
            int32x4x4_t v_in =
            {
                {
                    wrapper::vloadq(in_ptr),
                    wrapper::vloadq(in_ptr + 4),
                    wrapper::vloadq(in_ptr + 8),
                    wrapper::vloadq(in_ptr + 12)
                }
            };

            // Accumulate bias
            if(has_bias)
            {
                const auto vb = wrapper::vdup_n(*reinterpret_cast<const int32_t *>(bias->ptr_to_element(Coordinates(id.z()))), TagType{});
                v_in =
                {
                    {
                        wrapper::vadd(v_in.val[0], vb),
                        wrapper::vadd(v_in.val[1], vb),
                        wrapper::vadd(v_in.val[2], vb),
                        wrapper::vadd(v_in.val[3], vb)
                    }
                };
            }

            const auto out_ptr = reinterpret_cast<TOut *>(out.ptr()) + x;
            wrapper::vstore(out_ptr, finalize_quantization(v_in, result_fixedpoint_multiplier, result_shift, result_offset_after_shift_s32,
                                                           min, max, false));
        }

        // Left-overs loop
        for(; x < window_end_x; ++x)
        {
            // Get bias and pointer to input
            int32_t s_in = *(reinterpret_cast<const int32_t *>(in.ptr()) + x);

            // Accumulate bias
            if(has_bias)
            {
                const auto b = *reinterpret_cast<const int32_t *>(bias->ptr_to_element(Coordinates(id.z())));
                s_in += b;
            }

            const auto out_ptr = reinterpret_cast<TOut *>(out.ptr()) + x;
            *out_ptr           = finalize_quantization(s_in, result_fixedpoint_multiplier, result_shift, result_offset_after_shift,
                                                       std::numeric_limits<TOut>::lowest(), std::numeric_limits<TOut>::max(), false);
        }
    },
    in, out);
}
template < typename TOut, typename std::enable_if < std::is_same<TOut, uint8_t>::value || std::is_same<TOut, int8_t>::value, int >::type = 0 >
void output_stage_nhwc(ITensor *src, const ITensor *bias, const Window &window, ITensor *dst,
                       int result_fixedpoint_multiplier, int result_shift, int result_offset_after_shift)
{
    const bool has_bias = bias != nullptr;
    using VectorType    = typename wrapper::traits::neon_bitvector_t<TOut, wrapper::traits::BitWidth::W128>;
    using TagType       = typename wrapper::traits::neon_bitvector_tag_t<TOut, wrapper::traits::BitWidth::W128>;

    const int32x4_t result_offset_after_shift_s32 = vdupq_n_s32(result_offset_after_shift);

    const VectorType min = wrapper::vdup_n(std::numeric_limits<TOut>::lowest(), TagType{});
    const VectorType max = wrapper::vdup_n(std::numeric_limits<TOut>::max(), TagType{});

    Window window_bias = window;
    window_bias.set(Window::DimX, Window::Dimension(0, 1, 1));
    window_bias.set(Window::DimY, Window::Dimension(0, 0, 0));
    window_bias.set(Window::DimZ, Window::Dimension(0, 0, 0));
    window_bias.set(3, Window::Dimension(0, 0, 0));

    const int window_start_x = window.x().start();
    const int window_end_x   = window.x().end();
    const int window_step_x  = 16 / src->info()->element_size();
    Window    win            = window;
    win.set(Window::DimX, Window::Dimension(0, 1, 1));

    Iterator in(src, win);
    Iterator bi(bias, window_bias);
    Iterator out(dst, win);

    execute_window_loop(win, [&](const Coordinates &)
    {
        int x = window_start_x;
        for(; x <= (window_end_x - window_step_x); x += window_step_x)
        {
            // Get bias and pointer to input
            const auto  in_ptr = reinterpret_cast<int32_t *>(in.ptr()) + x;
            int32x4x4_t v_in =
            {
                {
                    wrapper::vloadq(in_ptr),
                    wrapper::vloadq(in_ptr + 4),
                    wrapper::vloadq(in_ptr + 8),
                    wrapper::vloadq(in_ptr + 12),
                }
            };

            // Accumulate bias
            if(has_bias)
            {
                const auto bias_ptr = reinterpret_cast<int32_t *>(bi.ptr()) + x;

                wrapper::vadd(v_in.val[0], wrapper::vloadq(bias_ptr));
                wrapper::vadd(v_in.val[1], wrapper::vloadq(bias_ptr + 4));
                wrapper::vadd(v_in.val[2], wrapper::vloadq(bias_ptr + 8));
                wrapper::vadd(v_in.val[3], wrapper::vloadq(bias_ptr + 12));
            }

            const auto out_ptr = reinterpret_cast<TOut *>(out.ptr()) + x;
            wrapper::vstore(out_ptr, finalize_quantization(v_in, result_fixedpoint_multiplier, result_shift, result_offset_after_shift_s32, min, max, false));
        }

        // Left-overs loop
        for(; x < window_end_x; ++x)
        {
            // Get bias and pointer to input
            const auto in_ptr = reinterpret_cast<int32_t *>(in.ptr()) + x;
            int32_t    s_in   = *in_ptr;

            // Accumulate bias
            if(has_bias)
            {
                const auto bias_ptr = reinterpret_cast<int32_t *>(bi.ptr()) + x;
                s_in += *bias_ptr;
            }

            const auto out_ptr = reinterpret_cast<TOut *>(out.ptr()) + x;
            *out_ptr           = finalize_quantization(s_in, result_fixedpoint_multiplier, result_shift, result_offset_after_shift,
                                                       std::numeric_limits<TOut>::lowest(), std::numeric_limits<TOut>::max(), false);
        }
    },
    in, bi, out);
}
} // namespace

void CpuDirectConv2dOutputStageKernel::configure(ITensorInfo *src, const ITensorInfo *bias, ITensorInfo *dst,
                                                 const DirectConvolutionLayerOutputStageKernelInfo &info)
{
    ARM_COMPUTE_UNUSED(bias);
    // Perform validation step
    ARM_COMPUTE_ERROR_ON_NULLPTR(src);
    ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(src, bias, dst, info));

    _func                         = nullptr;
    _result_fixedpoint_multiplier = info.result_fixedpoint_multiplier;
    _result_shift                 = info.result_shift;
    _result_offset_after_shift    = info.result_offset_after_shift;

    // Auto-initialize output output if required
    if(dst != nullptr)
    {
        // Work out expected output data type
        const DataType output_dt = (src->data_type() == DataType::S32) ? info.output_data_type : DataType::S32;
        // Output tensor auto initialization if not yet initialized
        auto_init_if_empty(*dst, src->clone()->set_data_type(output_dt));
    }

    Window win = calculate_max_window(*src, Steps());

    ICpuKernel::configure(win);

    const bool is_qasymm8_signed = (dst != nullptr) ? is_data_type_quantized_asymmetric_signed(dst->data_type()) : false;

    // Set appropriate function
    if(src->data_layout() == DataLayout::NCHW)
    {
        switch(src->data_type())
        {
            case DataType::S32:
            {
                if(is_qasymm8_signed)
                {
                    _func = &output_stage_nchw<int8_t>;
                }
                else
                {
                    _func = &output_stage_nchw<uint8_t>;
                }
                break;
            }
#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
            case DataType::F16:
            {
                _func = &output_stage_nchw<float16_t>;
                break;
            }
#endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */
            case DataType::F32:
            {
                _func = &output_stage_nchw<float>;
                break;
            }
            default:
            {
                ARM_COMPUTE_ERROR("Unsupported combination of types among the inputs.");
            }
        }
    }
    else
    {
        switch(src->data_type())
        {
            case DataType::S32:
            {
                if(is_qasymm8_signed)
                {
                    _func = &output_stage_nhwc<int8_t>;
                }
                else
                {
                    _func = &output_stage_nhwc<uint8_t>;
                }
                break;
            }
#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
            case DataType::F16:
            {
                _func = &output_stage_nhwc<float16_t>;
                break;
            }
#endif /* __ARM_FEATURE_FP16_VECTOR_ARITHMETIC */
            case DataType::F32:
            {
                _func = &output_stage_nhwc<float>;
                break;
            }
            default:
            {
                ARM_COMPUTE_ERROR("Unsupported combination of types among the inputs.");
            }
        }
    }
}

Status CpuDirectConv2dOutputStageKernel::validate(const ITensorInfo *src, const ITensorInfo *bias, const ITensorInfo *dst,
                                                  const DirectConvolutionLayerOutputStageKernelInfo &info)
{
    ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(src, bias, dst, info));
    return Status{};
}

void CpuDirectConv2dOutputStageKernel::run_op(ITensorPack &tensors, const Window &window, const ThreadInfo &info)
{
    ARM_COMPUTE_UNUSED(info);
    ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this);
    ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(ICpuKernel::window(), window);
    ARM_COMPUTE_ERROR_ON(_func == nullptr);

    auto src  = tensors.get_tensor(TensorType::ACL_SRC_0);
    auto bias = tensors.get_const_tensor(TensorType::ACL_SRC_1);
    auto dst  = tensors.get_tensor(TensorType::ACL_DST);

    (*_func)(src, bias, window, dst, _result_fixedpoint_multiplier, _result_shift, _result_offset_after_shift);
}

const char *CpuDirectConv2dOutputStageKernel::name() const
{
    return "CpuDirectConv2dOutputStageKernel";
}
} // namespace kernels
} // namespace cpu
} // namespace arm_compute
