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

#if defined(DATA_TYPE) && defined(SRC_WIDTH) && defined(SRC_HEIGHT)
/** This kernel applies dot product to each plane on the input tensor and the corrispective column of the reshaped weight tensor.
 *
 * @note Datatype and source width and height should be given as a preprocessor argument using -DDATA_TYPE=type, -DSRC_WIDTH=width and -DSRC_HEIGHT=height. e.g. -DDATA_TYPE=short
 *
 * @param[in]  src_ptr                               Pointer to the source tensor. Supported data types: F16/F32
 * @param[in]  src_stride_x                          Stride of the source tensor in X dimension (in bytes)
 * @param[in]  src_step_x                            src_stride_x * number of elements along X processed per workitem(in bytes)
 * @param[in]  src_stride_y                          Stride of the source tensor in Y dimension (in bytes)
 * @param[in]  src_step_y                            src_stride_y * number of elements along Y processed per workitem(in bytes)
 * @param[in]  src_stride_z                          Stride of the source tensor in Z dimension (in bytes)
 * @param[in]  src_step_z                            src_stride_z * number of elements along Y processed per workitem(in bytes)
 * @param[in]  src_offset_first_element_in_bytes     The offset of the first element in the source tensor
 * @param[in]  weights_ptr                           Pointer to the weights tensor. Same as @p src_ptr
 * @param[in]  weights_stride_x                      Stride of the weights tensor in X dimension (in bytes)
 * @param[in]  weights_step_x                        weights_stride_x * number of elements along X processed per workitem(in bytes)
 * @param[in]  weights_stride_y                      Stride of the weights tensor in Y dimension (in bytes)
 * @param[in]  weights_step_y                        weights_stride_y * number of elements along Y processed per workitem(in bytes)
 * @param[in]  weights_offset_first_element_in_bytes The offset of the first element in the weights tensor
 * @param[out] dst_ptr                               Pointer to the destination tensor. Same as @p src_ptr
 * @param[in]  dst_stride_x                          Stride of the destination tensor in X dimension (in bytes)
 * @param[in]  dst_step_x                            dst_stride_x * number of elements along X processed per workitem(in bytes)
 * @param[in]  dst_offset_first_element_in_bytes     The offset of the first element in the destination tensor
 */
__kernel void gemm_mv(TENSOR3D_DECLARATION(src), IMAGE_DECLARATION(weights), VECTOR_DECLARATION(dst))
{
    Tensor3D src = CONVERT_TO_TENSOR3D_STRUCT(src);

    int y = get_global_id(1) * 4;
    int z = get_global_id(2);

    __global uchar *current_weights = weights_ptr + weights_offset_first_element_in_bytes + z * weights_stride_y;
    __global uchar *input_ptr       = src.ptr;

    DATA_TYPE acc0 = (DATA_TYPE)0;
    DATA_TYPE acc1 = (DATA_TYPE)0;
    DATA_TYPE acc2 = (DATA_TYPE)0;
    DATA_TYPE acc3 = (DATA_TYPE)0;

    // This kernel handle 4 rows in per thread so that it can reuse the weights
    for(int i = 0; i < SRC_WIDTH; i += 4)
    {
        VEC_DATA_TYPE(DATA_TYPE, 4)
        weights = vload4(0, (__global DATA_TYPE *)(current_weights + i * weights_stride_x));

        int4 offset = (int4)i * (int4)src_stride_x + (int4)(0, 1, 2, 3) * (int4)src_stride_y;

        VEC_DATA_TYPE(DATA_TYPE, 4)
        tmp0 = vload4(0, (__global DATA_TYPE *)(input_ptr + offset.s0));
        VEC_DATA_TYPE(DATA_TYPE, 4)
        tmp1 = vload4(0, (__global DATA_TYPE *)(input_ptr + offset.s1));
        VEC_DATA_TYPE(DATA_TYPE, 4)
        tmp2 = vload4(0, (__global DATA_TYPE *)(input_ptr + offset.s2));
        VEC_DATA_TYPE(DATA_TYPE, 4)
        tmp3 = vload4(0, (__global DATA_TYPE *)(input_ptr + offset.s3));

        acc0 += dot(weights, tmp0);
        acc1 += dot(weights, tmp1);
        acc2 += dot(weights, tmp2);
        acc3 += dot(weights, tmp3);
    }

    __global uchar *output_ptr = dst_ptr + dst_offset_first_element_in_bytes + (y + z * SRC_HEIGHT) * dst_stride_x;

    int rows_left = SRC_HEIGHT - (y + 4);

    // This if check is used to handle the last few rows when it can't be divided by the four
    if(rows_left >= 0)
    {
        VEC_DATA_TYPE(DATA_TYPE, 4)
        out = (VEC_DATA_TYPE(DATA_TYPE, 4))(acc0, acc1, acc2, acc3);
        vstore4(out, 0, (__global DATA_TYPE *)output_ptr);
    }
    else
    {
        switch(rows_left)
        {
            case -1: // three rows left; one is padding
                *((__global DATA_TYPE *)(output_ptr + 2 * dst_stride_x)) = acc2;
            case -2: // two rows left; two are padding
                *((__global DATA_TYPE *)(output_ptr + 1 * dst_stride_x)) = acc1;
            case -3: // one row left; three are padding
                *((__global DATA_TYPE *)(output_ptr + 0 * dst_stride_x)) = acc0;
                break;
        }
    }
}

/** This kernel applies dot product to each plane on the input tensor and the corresponding column of the reshaped weight tensor.
 *
 * @note Input data type should be given as a preprocessor argument using -DDATA_TYPE=type, e.g. -DDATA_TYPE=uchar
 *
 * @param[in]  src_ptr                               Pointer to the source tensor. Supported data types: QASYMM8/QASYMM8_SIGNED
 * @param[in]  src_stride_x                          Stride of the source tensor in X dimension (in bytes)
 * @param[in]  src_step_x                            src_stride_x * number of elements along X processed per workitem(in bytes)
 * @param[in]  src_stride_y                          Stride of the source tensor in Y dimension (in bytes)
 * @param[in]  src_step_y                            src_stride_y * number of elements along Y processed per workitem(in bytes)
 * @param[in]  src_stride_z                          Stride of the source tensor in Z dimension (in bytes)
 * @param[in]  src_step_z                            src_stride_z * number of elements along Y processed per workitem(in bytes)
 * @param[in]  src_offset_first_element_in_bytes     The offset of the first element in the source tensor
 * @param[in]  weights_ptr                           Pointer to the weights tensor. Supported data types: same as @p src_ptr
 * @param[in]  weights_stride_x                      Stride of the weights tensor in X dimension (in bytes)
 * @param[in]  weights_step_x                        weights_stride_x * number of elements along X processed per workitem(in bytes)
 * @param[in]  weights_stride_y                      Stride of the weights tensor in Y dimension (in bytes)
 * @param[in]  weights_step_y                        weights_stride_y * number of elements along Y processed per workitem(in bytes)
 * @param[in]  weights_offset_first_element_in_bytes The offset of the first element in the weights tensor
 * @param[out] dst_ptr                               Pointer to the destination tensor. Supported data types: S32
 * @param[in]  dst_stride_x                          Stride of the destination tensor in X dimension (in bytes)
 * @param[in]  dst_step_x                            dst_stride_x * number of elements along X processed per workitem(in bytes)
 * @param[in]  dst_offset_first_element_in_bytes     The offset of the first element in the destination tensor
 * @param[in]  input_offset                          Input's quantization offset
 * @param[in]  weights_offset                        Weights's quantization offset
 */
__kernel void gemm_mv_quantized(TENSOR3D_DECLARATION(src),
                                IMAGE_DECLARATION(weights),
                                VECTOR_DECLARATION(dst),
                                const int input_offset,
                                const int weights_offset)
{
    Tensor3D src = CONVERT_TO_TENSOR3D_STRUCT(src);

    int y = get_global_id(1) * 4;
    int z = get_global_id(2);

    __global uchar *current_weights = weights_ptr + weights_offset_first_element_in_bytes + z * weights_stride_y;
    __global uchar *input_ptr       = src.ptr;

    int acc0 = 0;
    int acc1 = 0;
    int acc2 = 0;
    int acc3 = 0;

    // This kernel handle 4 rows in per thread so that it can reuse the weights
    for(int i = 0; i < SRC_WIDTH; i += 4)
    {
        int4 w = convert_int4(vload4(0, (__global DATA_TYPE *)(current_weights + i * weights_stride_x))) + (int4)weights_offset;

        int4 offset = (int4)i * (int4)src_stride_x + (int4)(0, 1, 2, 3) * (int4)src_stride_y;

        int4 tmp0 = convert_int4(vload4(0, (__global DATA_TYPE *)(input_ptr + offset.s0))) + (int4)input_offset;
        int4 tmp1 = convert_int4(vload4(0, (__global DATA_TYPE *)(input_ptr + offset.s1))) + (int4)input_offset;
        int4 tmp2 = convert_int4(vload4(0, (__global DATA_TYPE *)(input_ptr + offset.s2))) + (int4)input_offset;
        int4 tmp3 = convert_int4(vload4(0, (__global DATA_TYPE *)(input_ptr + offset.s3))) + (int4)input_offset;

        // Accumulate
        acc0 += tmp0.s0 * w.s0 + tmp0.s1 * w.s1 + tmp0.s2 * w.s2 + tmp0.s3 * w.s3;
        acc1 += tmp1.s0 * w.s0 + tmp1.s1 * w.s1 + tmp1.s2 * w.s2 + tmp1.s3 * w.s3;
        acc2 += tmp2.s0 * w.s0 + tmp2.s1 * w.s1 + tmp2.s2 * w.s2 + tmp2.s3 * w.s3;
        acc3 += tmp3.s0 * w.s0 + tmp3.s1 * w.s1 + tmp3.s2 * w.s2 + tmp3.s3 * w.s3;
    }

    __global uchar *output_ptr = dst_ptr + dst_offset_first_element_in_bytes + (y + z * SRC_HEIGHT) * dst_stride_x;

    int rows_left = SRC_HEIGHT - (y + 4);

    // This if check is used to handle the last few rows when it can't be divided by the four
    if(rows_left >= 0)
    {
        vstore4((int4)(acc0, acc1, acc2, acc3), 0, (__global int *)output_ptr);
    }
    else
    {
        switch(rows_left)
        {
            case -1: // three rows left; one is padding
                *((__global int *)(output_ptr + 2 * dst_stride_x)) = acc2;
            case -2: // two rows left; two are padding
                *((__global int *)(output_ptr + 1 * dst_stride_x)) = acc1;
            case -3: // one row left; three are padding
                *((__global int *)(output_ptr + 0 * dst_stride_x)) = acc0;
                break;
        }
    }
}
#endif /* defined(DATA_TYPE) && defined(SRC_WIDTH) && defined(SRC_HEIGHT) */
