/*
 * Copyright (c) 2019-2023 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.
 */
#ifndef ACL_SRC_GPU_CL_KERNELS_CLGEMMMATRIXMULTIPLYRESHAPEDONLYRHSKERNEL_H
#define ACL_SRC_GPU_CL_KERNELS_CLGEMMMATRIXMULTIPLYRESHAPEDONLYRHSKERNEL_H

#include "arm_compute/core/KernelDescriptors.h"

#include "src/core/common/Macros.h"
#include "src/gpu/cl/ClCompileContext.h"
#include "src/gpu/cl/IClKernel.h"

namespace arm_compute
{
namespace opencl
{
namespace kernels
{
/** OpenCL kernel to multiply matrices when only the input matrix RHS (src1) has been reshaped
 *
 * @note The input matrix src1 must be reshaped through @ref ClGemmReshapeRhsMatrixKernel
 */
class ClGemmMatrixMultiplyReshapedOnlyRhsKernel : public ICLKernel
{
public:
    ClGemmMatrixMultiplyReshapedOnlyRhsKernel();
    ARM_COMPUTE_DISALLOW_COPY_ALLOW_MOVE(ClGemmMatrixMultiplyReshapedOnlyRhsKernel);
    /** Initialise the kernel's input and output.
     *
     * @note If rhs_info.export_to_cl_image = true, this OpenCL kernel will fetch the RHS data using the OpenCL read_image built-in function.
     *       Reading from the OpenCL image object can increase the performance. However, since the OpenCL image object is created importing the OpenCL buffer,
     *       the following conditions are required:
     *       -# rhs_info.n0 can only be 4, 8 and 16
     *       -# rhs_info.k0 can only be 4, 8 and 16
     *       -# Data type can only be F32
     *       -# The platform should support the OpenCL cl_khr_image2d_from_buffer extension
     *       -# The stride Y for the src1 should satisfy the OpenCL pitch alignment requirement
     *       -# src1 width should be less or equal to (CL_DEVICE_IMAGE2D_MAX_WIDTH * 4)
     *       -# src1 (height * depth) should be less or equal to CL_DEVICE_IMAGE2D_MAX_HEIGHT
     *
     * @param[in]  compile_context The compile context to be used.
     * @param[in]  src0            Input tensor containing the LHS matrix. Data type supported: F16/F32 (only F32 if rhs_info.export_to_cl_image = true).
     *                             The number of dimensions for the LHS matrix must be less or equal than 4.
     * @param[in]  src1            Input tensor containing the RHS reshaped matrix. Data type supported: same as @p src0. The number of dimensions for the RHS matrix must be less or equal than 3.
     * @param[in]  src2            Input tensor containing the bias matrix. Data type supported: same as @p src0.
     * @param[out] dst             Output tensor to store the result of matrix multiplication. Data type supported: same as @p src0
     * @param[in]  alpha           Weight of the matrix product
     * @param[in]  beta            Weight of the matrix bias
     * @param[in]  lhs_info        LHS matrix information used to retrieve the number of rows to be processed by each thread. Only the following values are supported:
     *                             lhs_info.m0: 1,2,3,4,5,6,7,8
     * @param[in]  rhs_info        RHS matrix information used for reshaping the src1 tensor.  Only the following values are supported:
     *                             rhs_info.k0: 2,3,4,8,16
     *                             rhs_info.n0: 2,3,4,8,16
     *                             rhs_info.transpose: true,false
     * @param[in]  gemm_info       GEMM information used to retrieve the original dimensions of the input matrices
     */
    void configure(const ClCompileContext  &compile_context,
                   const ITensorInfo       *src0,
                   const ITensorInfo       *src1,
                   const ITensorInfo       *src2,
                   ITensorInfo             *dst,
                   float                    alpha,
                   float                    beta,
                   const GEMMLHSMatrixInfo &lhs_info,
                   const GEMMRHSMatrixInfo &rhs_info,
                   const GEMMKernelInfo    &gemm_info);
    /** Static function to check if given info will lead to a valid configuration
     *
     * Similar to @ref ClGemmMatrixMultiplyReshapedOnlyRhsKernel::configure()
     *
     * @return a status
     */
    static Status validate(const ITensorInfo       *src0,
                           const ITensorInfo       *src1,
                           const ITensorInfo       *src2,
                           const ITensorInfo       *dst,
                           float                    alpha,
                           float                    beta,
                           const GEMMLHSMatrixInfo &lhs_info,
                           const GEMMRHSMatrixInfo &rhs_info,
                           const GEMMKernelInfo    &gemm_info);

    // Inherited methods overridden:
    void run_op(ITensorPack &tensors, const Window &window, cl::CommandQueue &queue) override;

private:
    bool       _slide_matrix_b{true};
    bool       _reinterpret_input_as_3d{false};
    bool       _reinterpret_output_as_3d{false};
    bool       _use_dummy_work_items{false};
    bool       _add_bias{false};
    bool       _export_to_cl_image{false};
    bool       _has_pad_y{false};
    signed int _m{1};
    signed int _n{1};
    signed int _k{1};
};
} // namespace kernels
} // namespace opencl
} // namespace arm_compute
#endif // ACL_SRC_GPU_CL_KERNELS_CLGEMMMATRIXMULTIPLYRESHAPEDONLYRHSKERNEL_H
