/*
 * Copyright (c) 2018-2020 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 "ROIAlignLayer.h"

#include "arm_compute/core/Types.h"
#include "arm_compute/core/utils/misc/ShapeCalculator.h"
#include "tests/validation/Helpers.h"

#include <algorithm>

namespace arm_compute
{
namespace test
{
namespace validation
{
namespace reference
{
namespace
{
/** Average pooling over an aligned window */
inline float roi_align_1x1(const float *input, TensorShape input_shape,
                           float region_start_x,
                           float bin_size_x,
                           int   grid_size_x,
                           float region_end_x,
                           float region_start_y,
                           float bin_size_y,
                           int   grid_size_y,
                           float region_end_y,
                           int   pz)
{
    if((region_end_x <= region_start_x) || (region_end_y <= region_start_y))
    {
        return 0;
    }
    else
    {
        float avg = 0;
        // Iterate through the aligned pooling region
        for(int iy = 0; iy < grid_size_y; ++iy)
        {
            for(int ix = 0; ix < grid_size_x; ++ix)
            {
                // Align the window in the middle of every bin
                float y = region_start_y + (iy + 0.5) * bin_size_y / float(grid_size_y);
                float x = region_start_x + (ix + 0.5) * bin_size_x / float(grid_size_x);

                // Interpolation in the [0,0] [0,1] [1,0] [1,1] square
                const int y_low  = y;
                const int x_low  = x;
                const int y_high = y_low + 1;
                const int x_high = x_low + 1;

                const float ly = y - y_low;
                const float lx = x - x_low;
                const float hy = 1. - ly;
                const float hx = 1. - lx;

                const float w1 = hy * hx;
                const float w2 = hy * lx;
                const float w3 = ly * hx;
                const float w4 = ly * lx;

                const size_t idx1  = coord2index(input_shape, Coordinates(x_low, y_low, pz));
                float        data1 = input[idx1];

                const size_t idx2  = coord2index(input_shape, Coordinates(x_high, y_low, pz));
                float        data2 = input[idx2];

                const size_t idx3  = coord2index(input_shape, Coordinates(x_low, y_high, pz));
                float        data3 = input[idx3];

                const size_t idx4  = coord2index(input_shape, Coordinates(x_high, y_high, pz));
                float        data4 = input[idx4];

                avg += w1 * data1 + w2 * data2 + w3 * data3 + w4 * data4;
            }
        }

        avg /= grid_size_x * grid_size_y;

        return avg;
    }
}

template <typename TI, typename TO>
SimpleTensor<TO> float_converter(const SimpleTensor<TI> &tensor, DataType dst_dt)
{
    SimpleTensor<TO> dst{ tensor.shape(), dst_dt, 1, QuantizationInfo(), tensor.data_layout() };
#if defined(_OPENMP)
    #pragma omp parallel for
#endif /* _OPENMP */
    for(int i = 0; i < tensor.num_elements(); ++i)
    {
        dst[i] = tensor[i];
    }
    return dst;
}

SimpleTensor<float> convert_rois_from_asymmetric(SimpleTensor<uint16_t> rois)
{
    const UniformQuantizationInfo &quantization_info = rois.quantization_info().uniform();
    SimpleTensor<float>            dst{ rois.shape(), DataType::F32, 1, QuantizationInfo(), rois.data_layout() };

    for(int i = 0; i < rois.num_elements(); i += 5)
    {
        dst[i]     = static_cast<float>(rois[i]); // batch idx
        dst[i + 1] = dequantize_qasymm16(rois[i + 1], quantization_info);
        dst[i + 2] = dequantize_qasymm16(rois[i + 2], quantization_info);
        dst[i + 3] = dequantize_qasymm16(rois[i + 3], quantization_info);
        dst[i + 4] = dequantize_qasymm16(rois[i + 4], quantization_info);
    }
    return dst;
}
} // namespace

template <>
SimpleTensor<float> roi_align_layer(const SimpleTensor<float> &src, const SimpleTensor<float> &rois, const ROIPoolingLayerInfo &pool_info, const QuantizationInfo &output_qinfo)
{
    ARM_COMPUTE_UNUSED(output_qinfo);

    const size_t values_per_roi = rois.shape()[0];
    const size_t num_rois       = rois.shape()[1];
    DataType     dst_data_type  = src.data_type();

    const auto *rois_ptr = static_cast<const float *>(rois.data());

    TensorShape         input_shape = src.shape();
    TensorShape         output_shape(pool_info.pooled_width(), pool_info.pooled_height(), src.shape()[2], num_rois);
    SimpleTensor<float> dst(output_shape, dst_data_type);

    // Iterate over every pixel of the input image
    for(size_t px = 0; px < pool_info.pooled_width(); ++px)
    {
        for(size_t py = 0; py < pool_info.pooled_height(); ++py)
        {
            for(size_t pw = 0; pw < num_rois; ++pw)
            {
                const unsigned int roi_batch = rois_ptr[values_per_roi * pw];
                const auto         x1        = float(rois_ptr[values_per_roi * pw + 1]);
                const auto         y1        = float(rois_ptr[values_per_roi * pw + 2]);
                const auto         x2        = float(rois_ptr[values_per_roi * pw + 3]);
                const auto         y2        = float(rois_ptr[values_per_roi * pw + 4]);

                const float roi_anchor_x = x1 * pool_info.spatial_scale();
                const float roi_anchor_y = y1 * pool_info.spatial_scale();
                const float roi_dims_x   = std::max((x2 - x1) * pool_info.spatial_scale(), 1.0f);
                const float roi_dims_y   = std::max((y2 - y1) * pool_info.spatial_scale(), 1.0f);

                float bin_size_x     = roi_dims_x / pool_info.pooled_width();
                float bin_size_y     = roi_dims_y / pool_info.pooled_height();
                float region_start_x = px * bin_size_x + roi_anchor_x;
                float region_start_y = py * bin_size_y + roi_anchor_y;
                float region_end_x   = (px + 1) * bin_size_x + roi_anchor_x;
                float region_end_y   = (py + 1) * bin_size_y + roi_anchor_y;

                region_start_x = utility::clamp(region_start_x, 0.0f, float(input_shape[0]));
                region_start_y = utility::clamp(region_start_y, 0.0f, float(input_shape[1]));
                region_end_x   = utility::clamp(region_end_x, 0.0f, float(input_shape[0]));
                region_end_y   = utility::clamp(region_end_y, 0.0f, float(input_shape[1]));

                const int roi_bin_grid_x = (pool_info.sampling_ratio() > 0) ? pool_info.sampling_ratio() : int(ceil(bin_size_x));
                const int roi_bin_grid_y = (pool_info.sampling_ratio() > 0) ? pool_info.sampling_ratio() : int(ceil(bin_size_y));

                // Move input and output pointer across the fourth dimension
                const size_t input_stride_w  = input_shape[0] * input_shape[1] * input_shape[2];
                const size_t output_stride_w = output_shape[0] * output_shape[1] * output_shape[2];
                const float *input_ptr       = src.data() + roi_batch * input_stride_w;
                float       *output_ptr      = dst.data() + px + py * output_shape[0] + pw * output_stride_w;

                for(int pz = 0; pz < int(input_shape[2]); ++pz)
                {
                    // For every pixel pool over an aligned region
                    *(output_ptr + pz * output_shape[0] * output_shape[1]) = roi_align_1x1(input_ptr, input_shape,
                                                                                           region_start_x,
                                                                                           bin_size_x,
                                                                                           roi_bin_grid_x,
                                                                                           region_end_x,
                                                                                           region_start_y,
                                                                                           bin_size_y,
                                                                                           roi_bin_grid_y,
                                                                                           region_end_y, pz);
                }
            }
        }
    }
    return dst;
}

template <>
SimpleTensor<half> roi_align_layer(const SimpleTensor<half> &src, const SimpleTensor<half> &rois, const ROIPoolingLayerInfo &pool_info, const QuantizationInfo &output_qinfo)
{
    SimpleTensor<float> src_tmp  = float_converter<half, float>(src, DataType::F32);
    SimpleTensor<float> rois_tmp = float_converter<half, float>(rois, DataType::F32);
    SimpleTensor<float> dst_tmp  = roi_align_layer<float, float>(src_tmp, rois_tmp, pool_info, output_qinfo);
    SimpleTensor<half>  dst      = float_converter<float, half>(dst_tmp, DataType::F16);
    return dst;
}

template <>
SimpleTensor<uint8_t> roi_align_layer(const SimpleTensor<uint8_t> &src, const SimpleTensor<uint16_t> &rois, const ROIPoolingLayerInfo &pool_info, const QuantizationInfo &output_qinfo)
{
    SimpleTensor<float>   src_tmp  = convert_from_asymmetric(src);
    SimpleTensor<float>   rois_tmp = convert_rois_from_asymmetric(rois);
    SimpleTensor<float>   dst_tmp  = roi_align_layer<float, float>(src_tmp, rois_tmp, pool_info, output_qinfo);
    SimpleTensor<uint8_t> dst      = convert_to_asymmetric<uint8_t>(dst_tmp, output_qinfo);
    return dst;
}
template <>
SimpleTensor<int8_t> roi_align_layer(const SimpleTensor<int8_t> &src, const SimpleTensor<uint16_t> &rois, const ROIPoolingLayerInfo &pool_info, const QuantizationInfo &output_qinfo)
{
    SimpleTensor<float>  src_tmp  = convert_from_asymmetric(src);
    SimpleTensor<float>  rois_tmp = convert_rois_from_asymmetric(rois);
    SimpleTensor<float>  dst_tmp  = roi_align_layer<float, float>(src_tmp, rois_tmp, pool_info, output_qinfo);
    SimpleTensor<int8_t> dst      = convert_to_asymmetric<int8_t>(dst_tmp, output_qinfo);
    return dst;
}
} // namespace reference
} // namespace validation
} // namespace test
} // namespace arm_compute
