/*
 * Copyright (c) 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_ARM_COMPUTE_RUNTIME_CL_FUNCTIONS_CLMATMUL
#define ACL_ARM_COMPUTE_RUNTIME_CL_FUNCTIONS_CLMATMUL

#include "arm_compute/core/ActivationLayerInfo.h"
#include "arm_compute/core/Types.h"
#include "arm_compute/runtime/IFunction.h"
#include <memory>

namespace arm_compute
{
// Forward declarations for used types instead of including their header, that could minimize compile time
class CLCompileContext;
class ICLTensor;
class ITensorInfo;
class MatMulInfo;
class Status;

/** Settings for MatMul OpenCL implementation */
class GpuMatMulSettings
{
public:
    /* Placeholder for operator parity between CPU/GPU */
};

/** Basic function to execute MatMul (Matrix Multiplication) on OpenCL */
class CLMatMul : public IFunction
{
public:
    /** Default constructor.*/
    CLMatMul();
    /** Default destructor */
    ~CLMatMul();
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    CLMatMul(const CLMatMul &) = delete;
    /** Default move constructor */
    CLMatMul(CLMatMul &&);
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    CLMatMul &operator=(const CLMatMul &) = delete;
    /** Default move assignment operator */
    CLMatMul &operator=(CLMatMul &&);
    /** Initialise the kernel's inputs and output
     *
     * Valid data layouts:
     * - All
     *
     * Valid data type configurations:
     * |lhs            |rhs            |dst            |
     * |:--------------|:--------------|:--------------|
     * |F32            |F32            |F32            |
     * |F16            |F16            |F16            |
     * |QASYMM8_SIGNED |QASYMM8_SIGNED |QASYMM8_SIGNED |
     * |QASYMM8        |QASYMM8        |QASYMM8        |
     *
     * @note BatchMatMul: Batched Matrix Multiply - [A * B], Multiplies all slices (slice is an element of a batch) of Tensors A and B
     *                    and stores the result in the dst tensor of the same batch size.
     *                    Batch here is number of slices from A and B multiplied at a time, do not confuse with the batch dimension 'N' of NHWC/NCHW
     *                    For NHWC for example: the batch is the higher dimensions H * N, and in general it is H * all higher dimensions.
     * @note All tensors must have the same data type.
     *
     * @param[in]  compile_context The compile context to be used.
     * @param[in]  lhs             Left-hand side tensor info containing the input activations as Matrix A. Data types supported: F16/F32/QASYMM8_SIGNED/QASYMM8.
     * @param[in]  rhs             Right-hand side tensor info containing the input weights as Matrix B. Data types supported: same as @p lhs.
     * @param[out] dst             Output tensor to store the result of the batched matrix multiplication. Data types supported: same as @p lhs.
     * @param[in]  matmul_info     Contains MatMul operation information described in @ref MatMulInfo.
     * @param[in]  settings        Contains flags for function level settings
     * @param[in]  act_info        (Optional) Contains activation function and lower and upper bound values for bounded activation functions.
     */
    void configure(const CLCompileContext &compile_context, ICLTensor *rhs, ICLTensor *lhs, ICLTensor *dst, const MatMulInfo &matmul_info, const GpuMatMulSettings &settings = GpuMatMulSettings{}, const
                   ActivationLayerInfo &act_info = ActivationLayerInfo{});
    /** Initialise the kernel's inputs and output
     *
     * Similar to @ref CLMatMul::configure()
     */
    void configure(ICLTensor *lhs, ICLTensor *rhs, ICLTensor *dst, const MatMulInfo &matmul_info, const GpuMatMulSettings &settings = GpuMatMulSettings{}, const ActivationLayerInfo &act_info =
                       ActivationLayerInfo{});
    /** Static function to check if given info will lead to a valid configuration of @ref CLMatMul.
     *
     *
     * @note All tensors must have the same data type.
     *
     * @param[in]  lhs         Left-hand side (Matrix A) tensor info. Data types supported: F16/F32/QASYMM8_SIGNED/QASYMM8.
     * @param[in]  rhs         Right-hand side (Matrix B) tensor info. Data types supported: same as @p lhs.
     * @param[out] output      Output tensor info to store the result of the batched matrix multiplication. Data types supported: same as @p lhs.
     * @param[in]  matmul_info Contains MatMul operation information described in @ref MatMulInfo.
     * @param[in]  act_info    (Optional) Contains activation function and lower and upper bound values for bounded activation functions.
     */
    static Status validate(const ITensorInfo *lhs, const ITensorInfo *rhs, const ITensorInfo *output, const MatMulInfo &matmul_info, const ActivationLayerInfo &act_info = ActivationLayerInfo{});
    // Inherited methods overridden:
    void run() override;

private:
    struct Impl;
    std::unique_ptr<Impl> _impl;
};
} // namespace arm_compute

#endif /* ACL_ARM_COMPUTE_RUNTIME_CL_FUNCTIONS_CLMATMUL */
