/*
 * Copyright (c) 2017-2019 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 "arm_compute/core/NEON/kernels/NEL2NormalizeLayerKernel.h"

#include "arm_compute/core/Error.h"
#include "arm_compute/core/Helpers.h"
#include "arm_compute/core/ITensor.h"
#include "arm_compute/core/NEON/NEMath.h"
#include "arm_compute/core/TensorInfo.h"
#include "arm_compute/core/Utils.h"
#include "arm_compute/core/Validate.h"
#include "arm_compute/core/Window.h"

#include "arm_compute/core/NEON/wrapper/wrapper.h"
#include <arm_neon.h>
#include <cmath>

namespace arm_compute
{
namespace
{
constexpr int max_input_tensor_dim = 3;

template <typename T, int S>
void l2_normalize_X(const ITensor *in, const ITensor *sum, ITensor *out, float epsilon, const Window &window)
{
    /** NEON vector tag type. */
    using ExactTagType = typename wrapper::traits::neon_vector<T, S>::tag_type;

    Window window_sum(window);
    window_sum.set(Window::DimX, Window::Dimension(0, 0, 0));

    Window in_slice  = window.first_slice_window_1D();
    Window sum_slice = window_sum.first_slice_window_1D();

    do
    {
        Iterator input_it(in, in_slice);
        Iterator sum_it(sum, sum_slice);
        Iterator output_it(out, in_slice);

        const auto sum_value           = *reinterpret_cast<const T *>(sum_it.ptr());
        const auto vec_normalize_value = wrapper::vdup_n(static_cast<T>(1.f / std::sqrt(std::max(sum_value, static_cast<T>(epsilon)))), ExactTagType{});

        execute_window_loop(in_slice, [&](const Coordinates &)
        {
            const auto in_ptr  = reinterpret_cast<const T *>(input_it.ptr());
            const auto out_ptr = reinterpret_cast<T *>(output_it.ptr());

            wrapper::vstore(out_ptr, wrapper::vmul(wrapper::vloadq(in_ptr), vec_normalize_value));
        },
        input_it, output_it);
    }
    while(window.slide_window_slice_1D(in_slice) && window.slide_window_slice_1D(sum_slice));
}

template <typename T, int S>
void l2_normalize_Y(const ITensor *in, const ITensor *sum, ITensor *out, float epsilon, const Window &window)
{
    /** NEON vector tag type. */
    using ExactTagType = typename wrapper::traits::neon_vector<T, S>::tag_type;

    Window window_sum(window);
    window_sum.set(Window::DimY, Window::Dimension(0, 0, 0));

    Window in_slice  = window.first_slice_window_2D();
    Window sum_slice = window_sum.first_slice_window_2D();

    do
    {
        Iterator input_it(in, in_slice);
        Iterator sum_it(sum, sum_slice);
        Iterator output_it(out, in_slice);

        auto eps = wrapper::vdup_n(static_cast<T>(epsilon), ExactTagType{});

        execute_window_loop(in_slice, [&](const Coordinates &)
        {
            const auto in_ptr  = reinterpret_cast<const T *>(input_it.ptr());
            const auto sum_ptr = reinterpret_cast<const T *>(sum_it.ptr());
            const auto out_ptr = reinterpret_cast<T *>(output_it.ptr());

            const auto vec_normalize_value = wrapper::vinvsqrt(wrapper::vmax(wrapper::vloadq(sum_ptr), eps));
            wrapper::vstore(out_ptr, wrapper::vmul(wrapper::vloadq(in_ptr), vec_normalize_value));
        },
        input_it, sum_it, output_it);
    }
    while(window.slide_window_slice_2D(in_slice) && window.slide_window_slice_2D(sum_slice));
}

template <typename T, int S>
void l2_normalize_Z(const ITensor *in, const ITensor *sum, ITensor *out, float epsilon, const Window &window)
{
    /** NEON vector tag type. */
    using ExactTagType = typename wrapper::traits::neon_vector<T, S>::tag_type;

    Window window_sum(window);
    window_sum.set(Window::DimZ, Window::Dimension(0, 0, 0));

    Window in_slice  = window.first_slice_window_3D();
    Window sum_slice = window_sum.first_slice_window_3D();

    do
    {
        Iterator input_it(in, in_slice);
        Iterator sum_it(sum, sum_slice);
        Iterator output_it(out, in_slice);

        auto eps = wrapper::vdup_n(static_cast<T>(epsilon), ExactTagType{});

        execute_window_loop(in_slice, [&](const Coordinates &)
        {
            const auto in_ptr  = reinterpret_cast<const T *>(input_it.ptr());
            const auto sum_ptr = reinterpret_cast<const T *>(sum_it.ptr());
            const auto out_ptr = reinterpret_cast<T *>(output_it.ptr());

            const auto vec_normalize_value = wrapper::vinvsqrt(wrapper::vmax(wrapper::vloadq(sum_ptr), eps));
            wrapper::vstore(out_ptr, wrapper::vmul(wrapper::vloadq(in_ptr), vec_normalize_value));
        },
        input_it, sum_it, output_it);
    }
    while(window.slide_window_slice_3D(in_slice) && window.slide_window_slice_3D(sum_slice));
}

Status validate_arguments(const ITensorInfo *input, const ITensorInfo *sum, const ITensorInfo *output, int axis, float epsilon)
{
    ARM_COMPUTE_UNUSED(epsilon);

    const uint32_t actual_axis = wrap_around(axis, max_input_tensor_dim);
    ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input, sum, output);
    ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input, sum);
    ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input, 1, DataType::F16, DataType::F32);
    ARM_COMPUTE_RETURN_ERROR_ON_MSG(actual_axis > 2, "Actual axis greater than 2 is not supported");
    ARM_COMPUTE_RETURN_ERROR_ON_MSG(actual_axis >= TensorShape::num_max_dimensions, "Actual normalization axis greater than max number of dimensions");

    // Reduce shape on axis
    TensorShape sum_shape = input->tensor_shape();
    sum_shape.set(actual_axis, 1);
    ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DIMENSIONS(sum->tensor_shape(), sum_shape);

    if(output->total_size() != 0)
    {
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(input, output);
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input, output);
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DIMENSIONS(input->tensor_shape(), output->tensor_shape());
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT(input, output);
    }

    return Status{};
}

std::tuple<Status, Window> validate_and_configure_window(ITensorInfo *input, ITensorInfo *sum, ITensorInfo *output, int axis)
{
    const uint32_t actual_axis = wrap_around(axis, max_input_tensor_dim);
    const unsigned int num_elems_processed_per_iteration     = 16 / data_size_from_type(input->data_type());
    const unsigned int num_elems_processed_per_iteration_sum = (actual_axis == 0) ? 1 : num_elems_processed_per_iteration;

    Window win = calculate_max_window(*input, Steps(num_elems_processed_per_iteration));

    // Output auto initialization if not yet initialized
    auto_init_if_empty(*output, input->tensor_shape(), 1, input->data_type());

    AccessWindowHorizontal input_access(input, 0, num_elems_processed_per_iteration);
    AccessWindowHorizontal sum_access(sum, 0, num_elems_processed_per_iteration_sum);
    AccessWindowHorizontal output_access(output, 0, num_elems_processed_per_iteration);

    bool window_changed = update_window_and_padding(win, input_access, sum_access, output_access);
    output_access.set_valid_region(win, input->valid_region());

    Status err = (window_changed) ? ARM_COMPUTE_CREATE_ERROR(ErrorCode::RUNTIME_ERROR, "Insufficient Padding!") : Status{};

    return std::make_tuple(err, win);
}
} // namespace

NEL2NormalizeLayerKernel::NEL2NormalizeLayerKernel()
    : _input(nullptr), _sum(nullptr), _output(nullptr), _actual_axis(0), _epsilon(1e-12)
{
}

void NEL2NormalizeLayerKernel::configure(const ITensor *input, const ITensor *sum, ITensor *output, int axis, float epsilon)
{
    ARM_COMPUTE_ERROR_ON_NULLPTR(input, sum, output);
    ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(input->info(), sum->info(), output->info(), axis, epsilon));

    _input   = input;
    _sum     = sum;
    _output  = output;
    _actual_axis    = wrap_around(axis, max_input_tensor_dim);
    _epsilon = epsilon;

    // Configure kernel window
    auto win_config = validate_and_configure_window(_input->info(), _sum->info(), _output->info(), axis);
    ARM_COMPUTE_ERROR_THROW_ON(std::get<0>(win_config));

    INEKernel::configure(std::get<1>(win_config));
}

Status NEL2NormalizeLayerKernel::validate(const ITensorInfo *input, const ITensorInfo *sum, const ITensorInfo *output, int axis, float epsilon)
{
    ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(input, sum, output, axis, epsilon));
    ARM_COMPUTE_RETURN_ON_ERROR(std::get<0>(validate_and_configure_window(input->clone().get(), sum->clone().get(), output->clone().get(), axis)));

    return Status{};
}

void NEL2NormalizeLayerKernel::run(const Window &window, const ThreadInfo &info)
{
    ARM_COMPUTE_UNUSED(info);
    ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this);
    ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(INEKernel::window(), window);

    switch(_actual_axis)
    {
        case 0:
            switch(_input->info()->data_type())
            {
                case DataType::F32:
                    l2_normalize_X<float, 4>(_input, _sum, _output, _epsilon, window);
                    break;
#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
                case DataType::F16:
                    l2_normalize_X<float16_t, 8>(_input, _sum, _output, _epsilon, window);
                    break;
#endif // __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
                default:
                    ARM_COMPUTE_ERROR("Not implemented");
            }
            break;
        case 1:
            switch(_input->info()->data_type())
            {
                case DataType::F32:
                    l2_normalize_Y<float, 4>(_input, _sum, _output, _epsilon, window);
                    break;
#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
                case DataType::F16:
                    l2_normalize_Y<float16_t, 8>(_input, _sum, _output, _epsilon, window);
#endif // __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
                    break;
                default:
                    ARM_COMPUTE_ERROR("Not implemented");
            }
            break;
        case 2:
            switch(_input->info()->data_type())
            {
                case DataType::F32:
                    l2_normalize_Z<float, 4>(_input, _sum, _output, _epsilon, window);
                    break;
#ifdef __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
                case DataType::F16:
                    l2_normalize_Z<float16_t, 8>(_input, _sum, _output, _epsilon, window);
                    break;
#endif // __ARM_FEATURE_FP16_VECTOR_ARITHMETIC
                default:
                    ARM_COMPUTE_ERROR("Not implemented");
            }
            break;
        default:
            ARM_COMPUTE_ERROR("Unsupported normalization axis");
    }
}
} // namespace arm_compute
