/*
 * Copyright (c) 2019-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 "helpers_asymm.h"

/** Generate all the region of interests based on the image size and the anchors passed in. For each element (x,y) of the
 * grid, it will generate NUM_ANCHORS rois, given by shifting the grid position to match the anchor.
 *
 * @attention The following variables must be passed at compile time:
 * -# -DDATA_TYPE= Tensor data type. Supported data types: QASYMM8
 * -# -DHEIGHT= Height of the feature map on which this kernel is applied
 * -# -DWIDTH= Width of the feature map on which this kernel is applied
 * -# -DNUM_ANCHORS= Number of anchors to be used to generate the rois per each pixel
 * -# -DSTRIDE= Stride to be applied at each different pixel position (i.e., x_range = (1:WIDTH)*STRIDE and y_range = (1:HEIGHT)*STRIDE
 * -# -DNUM_ROI_FIELDS= Number of fields used to represent a roi
 *
 * @param[in]  anchors_ptr                           Pointer to the anchors tensor. Supported data types: QASYMM8
 * @param[in]  anchors_stride_x                      Stride of the anchors tensor in X dimension (in bytes)
 * @param[in]  anchors_step_x                        anchors_stride_x * number of elements along X processed per workitem(in bytes)
 * @param[in]  anchors_stride_y                      Stride of the anchors tensor in Y dimension (in bytes)
 * @param[in]  anchors_step_y                        anchors_stride_y * number of elements along Y processed per workitem(in bytes)
 * @param[in]  anchors_stride_z                      Stride of the source tensor in Z dimension (in bytes)
 * @param[in]  anchors_step_z                        anchors_stride_z * number of elements along Z processed per workitem(in bytes)
 * @param[in]  anchors_offset_first_element_in_bytes The offset of the first element in the boxes tensor
 * @param[out] rois_ptr                              Pointer to the rois. Supported data types: same as @p in_ptr
 * @param[out] rois_stride_x                         Stride of the rois in X dimension (in bytes)
 * @param[out] rois_step_x                           pred_boxes_stride_x * number of elements along X processed per workitem(in bytes)
 * @param[out] rois_stride_y                         Stride of the rois in Y dimension (in bytes)
 * @param[out] rois_step_y                           pred_boxes_stride_y * number of elements along Y processed per workitem(in bytes)
 * @param[out] rois_stride_z                         Stride of the rois in Z dimension (in bytes)
 * @param[out] rois_step_z                           pred_boxes_stride_z * number of elements along Z processed per workitem(in bytes)
 * @param[out] rois_offset_first_element_in_bytes    The offset of the first element in the rois
 */
#if defined(DATA_TYPE) && defined(WIDTH) && defined(HEIGHT) && defined(NUM_ANCHORS) && defined(STRIDE) && defined(NUM_ROI_FIELDS) && defined(OFFSET) && defined(SCALE)
__kernel void generate_proposals_compute_all_anchors_quantized(
    VECTOR_DECLARATION(anchors),
    VECTOR_DECLARATION(rois))
{
    Vector anchors = CONVERT_TO_VECTOR_STRUCT_NO_STEP(anchors);
    Vector rois    = CONVERT_TO_VECTOR_STRUCT(rois);

    const size_t idx = get_global_id(0);
    // Find the index of the anchor
    const size_t anchor_idx = idx % NUM_ANCHORS;

    // Find which shift is this thread using
    const size_t shift_idx = idx / NUM_ANCHORS;

    // Compute the shift on the X and Y direction (the shift depends exclusively by the index thread id)
    const float shift_x = (float)(shift_idx % WIDTH) * STRIDE;
    const float shift_y = (float)(shift_idx / WIDTH) * STRIDE;

    VEC_DATA_TYPE(float, NUM_ROI_FIELDS)
    shift = (VEC_DATA_TYPE(float, NUM_ROI_FIELDS))(shift_x, shift_y, shift_x, shift_y);

    // Read the given anchor
    VEC_DATA_TYPE(float, NUM_ROI_FIELDS)
    anchor = DEQUANTIZE(VLOAD(NUM_ROI_FIELDS)(0, (__global DATA_TYPE *)vector_offset(&anchors, anchor_idx * NUM_ROI_FIELDS)), OFFSET, SCALE, DATA_TYPE, NUM_ROI_FIELDS);

    // Apply the shift to the anchor
    VEC_DATA_TYPE(float, NUM_ROI_FIELDS)
    shifted_anchor = anchor + shift;

    VSTORE(NUM_ROI_FIELDS)
    (QUANTIZE(shifted_anchor, OFFSET, SCALE, DATA_TYPE, NUM_ROI_FIELDS), 0, (__global DATA_TYPE *)rois.ptr);
}
#endif //defined(DATA_TYPE) && defined(WIDTH) && defined(HEIGHT) && defined(NUM_ANCHORS) && defined(STRIDE) && defined(NUM_ROI_FIELDS) && defined(OFFSET) && defined(SCALE)
