/*
 * Copyright (c) 2018-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/core/CL/kernels/CLPriorBoxLayerKernel.h"

#include "arm_compute/core/CL/CLHelpers.h"
#include "arm_compute/core/CL/CLKernelLibrary.h"
#include "arm_compute/core/CL/ICLTensor.h"
#include "arm_compute/core/Helpers.h"
#include "arm_compute/core/TensorInfo.h"
#include "arm_compute/core/Utils.h"
#include "arm_compute/core/utils/misc/ShapeCalculator.h"
#include "src/core/CL/CLValidate.h"
#include "src/core/helpers/AutoConfiguration.h"
#include "src/core/helpers/WindowHelpers.h"

#include "support/StringSupport.h"

using namespace arm_compute::misc::shape_calculator;

namespace arm_compute
{
namespace
{
Status validate_arguments(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const PriorBoxLayerInfo &info)
{
    ARM_COMPUTE_RETURN_ERROR_ON_NULLPTR(input1, input2, output);
    ARM_COMPUTE_RETURN_ERROR_ON_DATA_TYPE_CHANNEL_NOT_IN(input1, 1, DataType::F32);
    ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_LAYOUT(input1, input2);
    ARM_COMPUTE_RETURN_ERROR_ON_MISMATCHING_DATA_TYPES(input1, input2);

    // Check variances
    const int var_size = info.variances().size();
    if(var_size > 1)
    {
        ARM_COMPUTE_RETURN_ERROR_ON_MSG(var_size != 4, "Must provide 4 variance values");
        for(int i = 0; i < var_size; ++i)
        {
            ARM_COMPUTE_RETURN_ERROR_ON_MSG(var_size <= 0, "Must be greater than 0");
        }
    }
    ARM_COMPUTE_RETURN_ERROR_ON_MSG(info.steps()[0] < 0.f, "Step x should be greater or equal to 0");
    ARM_COMPUTE_RETURN_ERROR_ON_MSG(info.steps()[1] < 0.f, "Step y should be greater or equal to 0");

    if(!info.max_sizes().empty())
    {
        ARM_COMPUTE_RETURN_ERROR_ON_MSG(info.max_sizes().size() != info.min_sizes().size(), "Max and min sizes dimensions should match");
    }

    for(unsigned int i = 0; i < info.max_sizes().size(); ++i)
    {
        ARM_COMPUTE_RETURN_ERROR_ON_MSG(info.max_sizes()[i] < info.min_sizes()[i], "Max size should be greater than min size");
    }

    if(output != nullptr && output->total_size() != 0)
    {
        ARM_COMPUTE_RETURN_ERROR_ON(output->dimension(1) != 2);
    }

    return Status{};
}

std::pair<Status, Window> validate_and_configure_window(const ITensorInfo *input1, const ITensorInfo *input2, ITensorInfo *output, const PriorBoxLayerInfo &info, int num_priors)
{
    ARM_COMPUTE_UNUSED(input2);
    // Output tensor auto initialization if not yet initialized
    TensorShape output_shape = compute_prior_box_shape(*input1, info);
    auto_init_if_empty(*output, output_shape, 1, input1->data_type());

    const unsigned int     num_elems_processed_per_iteration = 4 * num_priors;
    Window                 win                               = calculate_max_window(*output, Steps(num_elems_processed_per_iteration));
    AccessWindowHorizontal output_access(output, 0, num_elems_processed_per_iteration);
    bool                   window_changed = update_window_and_padding(win, output_access);
    Status                 err            = (window_changed) ? ARM_COMPUTE_CREATE_ERROR(ErrorCode::RUNTIME_ERROR, "Insufficient Padding!") : Status{};
    return std::make_pair(err, win);
}
} // namespace

CLPriorBoxLayerKernel::CLPriorBoxLayerKernel()
    : _input1(nullptr), _input2(nullptr), _output(nullptr), _info(), _num_priors(), _min(), _max(), _aspect_ratios()
{
    _type = CLKernelType::ELEMENTWISE;
}

void CLPriorBoxLayerKernel::configure(const ICLTensor *input1, const ICLTensor *input2, ICLTensor *output, const PriorBoxLayerInfo &info, cl::Buffer *min, cl::Buffer *max, cl::Buffer *aspect_ratios)
{
    configure(CLKernelLibrary::get().get_compile_context(), input1, input2, output, info, min, max, aspect_ratios);
}

void CLPriorBoxLayerKernel::configure(const CLCompileContext &compile_context, const ICLTensor *input1, const ICLTensor *input2, ICLTensor *output, const PriorBoxLayerInfo &info, cl::Buffer *min,
                                      cl::Buffer *max, cl::Buffer *aspect_ratios)
{
    ARM_COMPUTE_ERROR_ON_NULLPTR(input1, input2, output);

    _input1        = input1;
    _input2        = input2;
    _output        = output;
    _info          = info;
    _min           = min;
    _max           = max;
    _aspect_ratios = aspect_ratios;

    ARM_COMPUTE_ERROR_THROW_ON(validate_arguments(input1->info(), input2->info(), output->info(), info));

    // Calculate number of aspect ratios
    _num_priors = info.aspect_ratios().size() * info.min_sizes().size() + info.max_sizes().size();

    const DataLayout data_layout = input1->info()->data_layout();

    const int width_idx  = get_data_layout_dimension_index(data_layout, DataLayoutDimension::WIDTH);
    const int height_idx = get_data_layout_dimension_index(data_layout, DataLayoutDimension::HEIGHT);

    const int layer_width  = input1->info()->dimension(width_idx);
    const int layer_height = input1->info()->dimension(height_idx);

    int img_width  = info.img_size().x;
    int img_height = info.img_size().y;
    if(img_width == 0 || img_height == 0)
    {
        img_width  = input2->info()->dimension(width_idx);
        img_height = input2->info()->dimension(height_idx);
    }

    float step_x = info.steps()[0];
    float step_y = info.steps()[0];
    if(step_x == 0.f || step_y == 0.f)
    {
        step_x = static_cast<float>(img_width) / layer_width;
        step_y = static_cast<float>(img_height) / layer_height;
    }

    // Set build options
    CLBuildOptions build_opts;
    build_opts.add_option("-DDATA_TYPE=" + get_cl_type_from_data_type(input1->info()->data_type()));
    build_opts.add_option("-DWIDTH=" + support::cpp11::to_string(img_width));
    build_opts.add_option("-DHEIGHT=" + support::cpp11::to_string(img_height));
    build_opts.add_option("-DLAYER_WIDTH=" + support::cpp11::to_string(layer_width));
    build_opts.add_option("-DLAYER_HEIGHT=" + support::cpp11::to_string(layer_height));
    build_opts.add_option("-DSTEP_X=" + support::cpp11::to_string(step_x));
    build_opts.add_option("-DSTEP_Y=" + support::cpp11::to_string(step_y));
    build_opts.add_option("-DNUM_PRIORS=" + support::cpp11::to_string(_num_priors));
    build_opts.add_option("-DOFFSET=" + support::cpp11::to_string(info.offset()));
    build_opts.add_option_if(info.clip(), "-DIN_PLACE");

    if(info.variances().size() > 1)
    {
        for(unsigned int i = 0; i < info.variances().size(); ++i)
        {
            build_opts.add_option("-DVARIANCE_" + support::cpp11::to_string(i) + "=" + support::cpp11::to_string(info.variances().at(i)));
        }
    }
    else
    {
        for(unsigned int i = 0; i < 4; ++i)
        {
            build_opts.add_option("-DVARIANCE_" + support::cpp11::to_string(i) + "=" + support::cpp11::to_string(info.variances().at(0)));
        }
    }

    unsigned int idx = num_arguments_per_2D_tensor();
    _kernel          = create_kernel(compile_context, "prior_box_layer_nchw", build_opts.options());

    _kernel.setArg(idx++, *_min);
    _kernel.setArg(idx++, *_max);
    _kernel.setArg(idx++, *_aspect_ratios);
    _kernel.setArg<unsigned int>(idx++, info.min_sizes().size());
    _kernel.setArg<unsigned int>(idx++, info.max_sizes().size());
    _kernel.setArg<unsigned int>(idx++, info.aspect_ratios().size());

    // Configure kernel window
    auto win_config = validate_and_configure_window(input1->info(), input2->info(), output->info(), info, _num_priors);

    ARM_COMPUTE_ERROR_THROW_ON(win_config.first);
    ICLKernel::configure_internal(win_config.second);
}

Status CLPriorBoxLayerKernel::validate(const ITensorInfo *input1, const ITensorInfo *input2, const ITensorInfo *output, const PriorBoxLayerInfo &info)
{
    ARM_COMPUTE_ERROR_ON_NULLPTR(input1, input2, output);
    ARM_COMPUTE_RETURN_ON_ERROR(validate_arguments(input1, input2, output, info));
    const int num_priors = info.aspect_ratios().size() * info.min_sizes().size() + info.max_sizes().size();
    ARM_COMPUTE_RETURN_ON_ERROR(validate_and_configure_window(input1->clone().get(), input2->clone().get(), output->clone().get(), info, num_priors)
                                .first);

    return Status{};
}

void CLPriorBoxLayerKernel::run(const Window &window, cl::CommandQueue &queue)
{
    ARM_COMPUTE_ERROR_ON_UNCONFIGURED_KERNEL(this);
    ARM_COMPUTE_ERROR_ON_INVALID_SUBWINDOW(IKernel::window(), window);

    queue.enqueueWriteBuffer(*_min, CL_TRUE, 0, _info.min_sizes().size() * sizeof(float), _info.min_sizes().data());
    queue.enqueueWriteBuffer(*_aspect_ratios, CL_TRUE, 0, _info.aspect_ratios().size() * sizeof(float), _info.aspect_ratios().data());
    if(!_info.max_sizes().empty())
    {
        queue.enqueueWriteBuffer(*_max, CL_TRUE, 0, _info.max_sizes().size() * sizeof(float), _info.max_sizes().data());
    }

    Window slice = window.first_slice_window_2D();
    slice.set(Window::DimY, Window::Dimension(0, _output->info()->dimension(1), 2));

    unsigned int idx = 0;
    add_2D_tensor_argument(idx, _output, slice);
    enqueue(queue, *this, slice, lws_hint());
}
} // namespace arm_compute
