/*
 * Copyright (c) 2020-2021, 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 ARM_COMPUTE_CL_CLUTILS_H
#define ARM_COMPUTE_CL_CLUTILS_H

#include "arm_compute/core/CL/OpenCL.h"
#include "arm_compute/core/experimental/IPostOp.h"

#include <map>

namespace arm_compute
{
class TensorShape;
class CLBuildOptions;
class ITensorInfo;
class ICLTensor;
enum class DataType;

/** OpenCL Image2D types */
enum class CLImage2DType
{
    ReadOnly,
    WriteOnly
};

/** Create a cl::Image2D object from a tensor
 *
 * @param[in] tensor     Tensor from which to construct Image 2D object
 * @param[in] image_type Image 2D type (@ref CLImage2DType)
 *
 * @return cl::Image2D object
 */
cl::Image2D create_image2d_from_tensor(const ICLTensor *tensor, CLImage2DType image_type);

/** Create a cl::Image2D object from an OpenCL buffer
 *
 * @note The following conditions are required to create a OpenCL image object from OpenCL buffer,
 *       -# The platform should support the OpenCL cl_khr_image2d_from_buffer extension
 *       -# The stride Y for the input1 should satisfy the OpenCL pitch alignment requirement
 *       -# input width should be less or equal to (CL_DEVICE_IMAGE2D_MAX_WIDTH * 4)
 *       -# input height should be less or equal to CL_DEVICE_IMAGE2D_MAX_HEIGHT
 *
 * It is user responsibility to ensure the above conditions are satisfied since no checks are performed within this function
 *
 * @param[in] ctx             cl::Context object
 * @param[in] buffer          cl::Buffer object from which the OpenCL image2d object is created
 * @param[in] shape2d         2D tensor shape
 * @param[in] data_type       DataType to use. Only supported: F32,F16
 * @param[in] image_row_pitch Image row pitch (a.k.a. stride Y) to be used in the image2d object
 * @param[in] image_type      Image 2D type (@ref CLImage2DType)
 *
 * @return cl::Image2D object
 */
cl::Image2D create_image2d_from_buffer(const cl::Context &ctx, const cl::Buffer &buffer, const TensorShape &shape2d, DataType data_type, size_t image_row_pitch, CLImage2DType image_type);

namespace experimental
{
/** @name (EXPERIMENTAL_POST_OPS)
 * @{
 */

/** Manage validation, building and configurations of PostOp CL kernels */
class PostOpCLKernelUtils final
{
public:
    /** CL kernel name postfix for post ops */
    using NamePostfix = std::string;
    /** CL kernels that supports post ops assign each post op to a 'slot', in accordance with the postfix
     * For example, for a kernel with postfix '_act_prelu_eltwiseadd', there are 3 slots
     * slot 1: (unary) activation, slot 2: pRelu, slot 3: elementwise addition
     *
     * Some kernels may allow some slots to be optional, to support multiple combinations of post op sequences.
     * In such cases, we need to explicitly set up a mapping between each post op and the slots for that kernel.
     * For example, suppose we have 2 kernels with postfixes: _eltwiseadd_prelu, _act_eltwiseadd_act_prelu, where the activations in the
     * second kernel are optional. Say we want to support an eltwise addition, followed by a prelu (sequence { eltwiseadd, prelu }).
     * Now we can choose which one of the 2 kernels to use, since they both support this post op sequence.
     * We can either:
     *  1. assign the elementwise to slot 1 and prelu to slot 2 of kernel 1
     *  { { Eltwise_Add, PRelu } -> {"_eltwise_act", {1, 2} } } or
     *  2. assign the elementwise to slot 2 and prelu to slot 4 of kernel 1
     *  { { Eltwise_Add, PRelu } -> {"_act_eltwiseadd_act_prelu", {2, 4} } }
     */
    using Slots  = std::vector<unsigned int>;
    using Config = std::map<PostOpTypeSequence, std::tuple<NamePostfix, Slots>>;

public:
    explicit PostOpCLKernelUtils(const Config &config);

    /** Check if post op argument tensor shapes are compliant
     * All post ops must not alter the shape of the original dst tensor (even after broadcasting)
     *
     * @param[in] dst      Dst tensor to apply the post ops to
     * @param[in] post_ops Post ops
     *
     * @return true if shapes are compliant and false otherwise
     */
    static bool are_post_op_shapes_compliant(const ITensorInfo *dst, const experimental::PostOpList<ITensorInfo *> &post_ops);
    /** Check if the post op sequence is supported in the current configuration
     *
     * @param[in] post_ops Post ops
     *
     * @return true if the post op sequence is supported and false otherwise
     */
    bool is_post_op_sequence_supported(const PostOpList<ITensorInfo *> &post_ops) const;
    /** Helper function to set PostOp related build options
     * @note Convention
     *      1. Each post op "slot" is prefixed with "P<slot number>", followed by the usual parameters for that post op.
     *      E.g. If the first slot is an activation, we need to pass 3 definitions in this way:
     *          -P1_ACTIVATION_TYPE=...  -P1_ACTIVATION_A_VAL=...   -P1_ACTIVATION_B_VAL=...
     *
     *      2. For multi-ary post ops, to pass the position of the previous op's dest tensor,
     *         we append "_X_POS_<pos>" to the post op type.
     *      E.g. for a single post op add(dst, x), where dst is the result of the main op.
     *         In this case, the position of the previous op's dest is 0, so we pass
     *         -P1_ELTWISE_OP=ADD_X_POS_0
     *
     * @param[out] built_opts OpenCL kernel build options
     * @param[in]  post_ops   Post ops
     *
     */
    void set_post_ops_cl_build_options(CLBuildOptions &built_opts, const PostOpList<ITensorInfo *> &post_ops) const;
    /** Helper function to set PostOp kernel name
     *
     * @param[out] kernel_name OpenCL kernel name
     * @param[in]  post_ops    Post ops
     *
     */
    void set_post_ops_cl_kernel_name(std::string &kernel_name, const PostOpList<ITensorInfo *> &post_ops) const;

private:
    Config _supported_config{};
};
/** @} */ // end of group (EXPERIMENTAL_POST_OPS)

} // namespace experimental

} // arm_compute

#endif /* ARM_COMPUTE_CL_CLUTILS_H */
