/*
 * Copyright (c) 2018-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.
 */
#ifndef ARM_COMPUTE_CLGATHERKERNEL_H
#define ARM_COMPUTE_CLGATHERKERNEL_H

#include "arm_compute/core/Types.h"
#include "src/core/CL/ICLKernel.h"

namespace arm_compute
{
class ICLTensor;

/** Interface for the kernel to perform tensor reshaping */
class CLGatherKernel : public ICLKernel
{
public:
    /** Default constructor */
    CLGatherKernel();
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    CLGatherKernel(const CLGatherKernel &) = delete;
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    CLGatherKernel &operator=(const CLGatherKernel &) = delete;
    /** Allow instances of this class to be moved */
    CLGatherKernel(CLGatherKernel &&) = default;
    /** Allow instances of this class to be moved */
    CLGatherKernel &operator=(CLGatherKernel &&) = default;
    /** Default destructor */
    ~CLGatherKernel() = default;
    /** Initialise the kernel's inputs and outputs
     *
     * @param[in]  input   Source tensor. Supported tensor rank: up to 4. Data type supported: All.
     * @param[in]  indices Indices tensor. Supported tensor rank: up to 1. Must be one of the following types: U32/S32. Each value must be in range [0, input.shape[@p axis])
     * @param[out] output  Destination tensor. Data type supported: Same as @p input
     * @param[in]  axis    (Optional) The axis in @p input to gather @p indices from. Negative values wrap around. Defaults to 0
     */
    void configure(const ICLTensor *input, const ICLTensor *indices, ICLTensor *output, int axis = 0);
    /** Initialise the kernel's inputs and outputs
     *
     * @param[in]  compile_context The compile context to be used.
     * @param[in]  input           Source tensor. Supported tensor rank: up to 4. Data type supported: All.
     * @param[in]  indices         Indices tensor. Supported tensor rank: up to 1. Must be one of the following types: U32/S32. Each value must be in range [0, input.shape[@p axis])
     * @param[out] output          Destination tensor. Data type supported: Same as @p input
     * @param[in]  axis            (Optional) The axis in @p input to gather @p indices from. Negative values wrap around. Defaults to 0
     */
    void configure(const CLCompileContext &compile_context, const ICLTensor *input, const ICLTensor *indices, ICLTensor *output, int axis = 0);

    /** Static function to check if given info will lead to a valid configuration of @ref CLGatherKernel
     *
     * @param[in] input   Source tensor info. Supported tensor rank: up to 4. Data type supported: All.
     * @param[in] indices Indices tensor info. Supported tensor rank: up to 4. Must be one of the following types: U32/S32. Each value must be in range [0, input.shape[@p axis])
     * @param[in] output  Destination tensor info. Data type supported: Same as @p input
     * @param[in] axis    (Optional) The axis in @p input to gather @p indices from. Negative values wrap around. Defaults to 0
     *
     * @return a status
     */
    static Status validate(const ITensorInfo *input, const ITensorInfo *indices, const ITensorInfo *output, int axis = 0);

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

private:
    const ICLTensor *_input;   /**< Source tensor */
    const ICLTensor *_indices; /**< Indices tensor */
    ICLTensor       *_output;  /**< Destination tensor */
    int              _axis;    /**< Axis index */
};
} // namespace arm_compute
#endif /*ARM_COMPUTE_CLGATHERKERNEL_H */
