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

#include "arm_compute/core/Error.h"
#include "arm_compute/core/Helpers.h"
#include "arm_compute/core/ITensor.h"
#include "arm_compute/core/TensorInfo.h"
#include "arm_compute/core/Types.h"
#include "arm_compute/core/Validate.h"
#include "arm_compute/core/utils/misc/ShapeCalculator.h"
#include "src/core/NEON/wrapper/wrapper.h"
#include "src/core/helpers/AutoConfiguration.h"
#include "src/core/helpers/WindowHelpers.h"

namespace arm_compute
{
namespace
{
Status validate_arguments(const ITensorInfo *input, const ITensorInfo *output, const PaddingList &paddings, const PaddingMode mode)
{
    ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input);
    ARM_COMPUTE_RETURN_ERROR_ON(input->data_type() == DataType::UNKNOWN);
    ARM_COMPUTE_RETURN_ERROR_ON_MSG(mode != PaddingMode::CONSTANT, "Only constant padding mode is supported");
    ARM_COMPUTE_RETURN_ERROR_ON_MSG(paddings.size() > 4, "Padding list bigger than 4 dimensions");
    if(output->total_size() != 0)
    {
        const TensorShape expected_output_shape = arm_compute::misc::shape_calculator::compute_padded_shape(input->tensor_shape(), paddings);
        const TensorInfo  expected_output_info  = input->clone()->set_tensor_shape(expected_output_shape);
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_SHAPES(output, &expected_output_info);
        ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input, output);
    }
    return Status{};
}
} // namespace

template <typename T>
void NEPadLayerKernel::run_pad_constant(const Window &window)
{
    Window output_window{ window };
    output_window.set(Window::DimX, Window::Dimension(0, 1, 1));

    const size_t element_size = _input->info()->element_size();
    Iterator     output_it(_output, output_window);
    execute_window_loop(output_window, [&](const Coordinates & id)
    {
        Coordinates idin{ id };
        for(size_t dim = _padding.size() - 1; dim > 0; --dim)
        {
            idin[dim] -= _padding[dim].first;
            if(idin[dim] < 0 || static_cast<int>(_input->info()->dimension(dim)) - 1 < idin[dim])
            {
                std::fill_n(reinterpret_cast<T *>(output_it.ptr()), _output->info()->dimension(0), _constant_value.get<T>());
                return;
            }
        }
        T *input_it_ptr  = reinterpret_cast<T *>(_input->ptr_to_element(idin));
        T *output_it_ptr = reinterpret_cast<T *>(output_it.ptr());
        std::fill_n(output_it_ptr, _padding[0].first, _constant_value.get<T>());
        memcpy(output_it_ptr + _padding[0].first, input_it_ptr, _input->info()->dimension(0) * element_size);
        std::fill_n(output_it_ptr + _padding[0].first + _input->info()->dimension(0), _padding[0].second, _constant_value.get<T>());
    },
    output_it);
}

void NEPadLayerKernel::run_pad_constant_uint8_3Dinput_3Dpad(const Window &window)
{
    ARM_COMPUTE_UNUSED(window);

    const size_t start_plane = window.z().start();
    const size_t end_plane   = window.z().end();

    size_t start_plane_input = start_plane;
    if(_padding.size() > 2)
    {
        start_plane_input = (start_plane < _padding[2].first) ? 0 : start_plane - _padding[2].first;
    }
    const int output_plane_size = _output->info()->dimension(0) * _output->info()->dimension(1);
    const int input_plane_size  = _input->info()->dimension(0) * _input->info()->dimension(1);

    const int pad_y_elems_top = (_padding.size() > 1 ? _padding[1].first : 0) * _output->info()->dimension(0);
    const int pad_y_elems_bot = (_padding.size() > 1 ? _padding[1].second : 0) * _output->info()->dimension(0);

    const size_t jump_to_next_row_input  = _input->info()->dimension(0);
    const size_t jump_to_next_row_output = _padding[0].first + _padding[0].second;

    uint8_t       *output_row_ptr = _output->buffer() + _output->info()->offset_first_element_in_bytes() + start_plane * output_plane_size;
    const uint8_t *input_it_ptr   = _input->buffer() + _input->info()->offset_first_element_in_bytes() + start_plane_input * input_plane_size;
    const auto     pad_value      = _constant_value.get<uint8_t>();

    for(size_t z_i = start_plane; z_i < end_plane; ++z_i)
    {
        if(_padding.size() > 2 && z_i < _padding[2].first)
        {
            memset(output_row_ptr, pad_value, output_plane_size);
            output_row_ptr += output_plane_size;
        }
        else if(_padding.size() > 2 && z_i > (_input->info()->dimension(2) + _padding[2].first - 1))
        {
            memset(output_row_ptr, pad_value, output_plane_size);
            output_row_ptr += output_plane_size;
        }
        else
        {
            memset(output_row_ptr, pad_value, pad_y_elems_top);
            output_row_ptr += pad_y_elems_top;
            size_t y_i = _input->info()->dimension(1);
            // Basic loop unrolling
            for(; y_i > 3; y_i -= 4)
            {
                memset(output_row_ptr, pad_value, _padding[0].first);
                output_row_ptr += _padding[0].first;

                memcpy(output_row_ptr, input_it_ptr, _input->info()->dimension(0));
                output_row_ptr += _input->info()->dimension(0);
                input_it_ptr += jump_to_next_row_input;

                memset(output_row_ptr, pad_value, _padding[0].second + _padding[0].first);
                output_row_ptr += jump_to_next_row_output;

                memcpy(output_row_ptr, input_it_ptr, _input->info()->dimension(0));
                output_row_ptr += _input->info()->dimension(0);
                input_it_ptr += jump_to_next_row_input;

                memset(output_row_ptr, pad_value, _padding[0].second + _padding[0].first);
                output_row_ptr += jump_to_next_row_output;

                memcpy(output_row_ptr, input_it_ptr, _input->info()->dimension(0));
                output_row_ptr += _input->info()->dimension(0);
                input_it_ptr += jump_to_next_row_input;

                memset(output_row_ptr, pad_value, _padding[0].second + _padding[0].first);
                output_row_ptr += jump_to_next_row_output;

                memcpy(output_row_ptr, input_it_ptr, _input->info()->dimension(0));
                output_row_ptr += _input->info()->dimension(0);
                input_it_ptr += jump_to_next_row_input;

                memset(output_row_ptr, pad_value, _padding[0].second);
                output_row_ptr += _padding[0].second;
            }
            for(; y_i > 0; --y_i)
            {
                memset(output_row_ptr, pad_value, _padding[0].first);
                output_row_ptr += _padding[0].first;

                memcpy(output_row_ptr, input_it_ptr, _input->info()->dimension(0));
                output_row_ptr += _input->info()->dimension(0);
                input_it_ptr += _input->info()->dimension(0);

                memset(output_row_ptr, pad_value, _padding[0].second);
                output_row_ptr += _padding[0].second;
            }
            memset(output_row_ptr, pad_value, pad_y_elems_bot);
            output_row_ptr += pad_y_elems_bot;
        }
    }
}

NEPadLayerKernel::NEPadLayerKernel()
    : _func(), _input(nullptr), _output(nullptr), _padding(), _constant_value(), _mode()
{
}

void NEPadLayerKernel::configure(ITensor *input, ITensor *output, const PaddingList &padding, const PixelValue constant_value, const PaddingMode mode)
{
    ARM_COMPUTE_ERROR_ON_NULLPTR(input, output);
    // Auto-init
    const TensorShape expected_output_shape = arm_compute::misc::shape_calculator::compute_padded_shape(input->info()->tensor_shape(), padding);
    const TensorInfo  expected_output_info  = input->info()->clone()->set_tensor_shape(expected_output_shape);
    auto_init_if_empty(*output->info(), expected_output_info);

    // Perform validation step
    ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(input->info(), output->info(), padding, mode));

    _input          = input;
    _output         = output;
    _padding        = padding;
    _constant_value = constant_value;
    _mode           = mode;

    if(_mode == PaddingMode::CONSTANT)
    {
        switch(_input->info()->element_size())
        {
            case 1:
                if(_input->info()->num_dimensions() == 3 &&                           // Is 3D
                   padding.size() <= 3 &&                                             // Has 3D padding
                   !_input->info()->has_padding() && !_output->info()->has_padding()) // Input & Output have no padding
                {
                    _func = &NEPadLayerKernel::run_pad_constant_uint8_3Dinput_3Dpad;
                }
                else
                {
                    _func = &NEPadLayerKernel::run_pad_constant<uint8_t>;
                }
                break;
            case 2:
                _func = &NEPadLayerKernel::run_pad_constant<uint16_t>;
                break;
            case 4:
                _func = &NEPadLayerKernel::run_pad_constant<uint32_t>;
                break;
            default:
                ARM_COMPUTE_ERROR("Element size not supported");
                break;
        }
    }
    else
    {
        ARM_COMPUTE_ERROR("Padding mode not supported");
    }

    // Configure kernel window
    Window win = calculate_max_window(*output->info(), Steps());

    // The NEPad doesn't need padding so update_window_and_padding() can be skipped

    ICPPKernel::configure(win);
}

Status NEPadLayerKernel::validate(const ITensorInfo *input, const ITensorInfo *output, const PaddingList &padding, const PixelValue constant_value, const PaddingMode mode)
{
    ARM_COMPUTE_UNUSED(constant_value);
    ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(input, output, padding, mode));
    return Status{};
}

void NEPadLayerKernel::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);

    if(_func != nullptr)
    {
        (this->*_func)(window);
    }
}

size_t NEPadLayerKernel::get_mws(const CPUInfo &platform, size_t thread_count) const
{
    ARM_COMPUTE_UNUSED(thread_count);
    ARM_COMPUTE_UNUSED(platform);
    
    return ICPPKernel::default_mws;
}

} // namespace arm_compute
