/*
 * Copyright (c) 2017-2021 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_CLTUNER_H
#define ARM_COMPUTE_CLTUNER_H

#include "arm_compute/core/CL/OpenCL.h"
#include "arm_compute/core/utils/misc/Macros.h"
#include "arm_compute/runtime/CL/CLTunerTypes.h"
#include "arm_compute/runtime/CL/CLTuningParams.h"
#include "arm_compute/runtime/CL/ICLTuner.h"

#include <unordered_map>

namespace arm_compute
{
class ICLKernel;

/** Basic implementation of the OpenCL tuner interface */
class CLTuner : public ICLTuner
{
public:
    /** Constructor
     *
     * @param[in] tune_new_kernels Find the optimal local workgroup size for kernels which are not present in the table ?
     * @param[in] tuning_info      (Optional) opencl parameters to tune
     *
     */
    CLTuner(bool tune_new_kernels = true, CLTuningInfo tuning_info = CLTuningInfo());

    /** Destructor */
    ~CLTuner() = default;

    /** Setter for tune_new_kernels option
     *
     * @param[in] tune_new_kernels Find the optimal local workgroup size for kernels which are not present in the table ?
     */
    void set_tune_new_kernels(bool tune_new_kernels);

    /** Tune kernels that are not in the tuning parameters table
     *
     * @return True if tuning of new kernels is enabled.
     */
    bool tune_new_kernels() const;

    /** Setter for tune parameters option
     *
     * @param[in] tuning_info opencl parameters to tune
     */
    void set_tuning_parameters(CLTuningInfo tuning_info);

    /** Set OpenCL tuner mode
     *
     * @param[in] mode Indicates how exhaustive the search for the optimal tuning parameters should be while tuning. Default is Exhaustive mode
     */
    void set_tuner_mode(CLTunerMode mode);

    /** Get the current OpenCL tuner mode
     *
     * @return tuner_mode Indicates how exhaustive the search for the optimal tuning parameters should be while tuning
     *
     * @deprecated This function is deprecated and is intended to be removed in 21.05 release
     */
    CLTunerMode get_tuner_mode() const;

    /** Manually add a LWS for a kernel
     *
     * @param[in] kernel_id   Unique identifiant of the kernel
     * @param[in] optimal_lws Optimal local workgroup size to use for the given kernel
     *
     * @deprecated This function is deprecated and is intended to be removed in 21.05 release
     */
    ARM_COMPUTE_DEPRECATED_REL_REPLACE(21.02, add_tuning_params)
    void add_lws_to_table(const std::string &kernel_id, cl::NDRange optimal_lws);

    /** Manually add tuning parameters for a kernel
     *
     * @param[in] kernel_id             Unique identifiant of the kernel
     * @param[in] optimal_tuning_params Optimal tuning parameters to use for the given kernel
     */
    void add_tuning_params(const std::string &kernel_id, CLTuningParams optimal_tuning_params);

    /** Import LWS table
     *
     * @param[in] lws_table The unordered_map container to import
     *
     * @deprecated This function is deprecated and is intended to be removed in 21.05 release
     */
    ARM_COMPUTE_DEPRECATED_REL_REPLACE(21.02, import_tuning_params)
    void import_lws_table(const std::unordered_map<std::string, cl::NDRange> &lws_table);

    /** Import tuning parameters table
     *
     * @param[in] tuning_params_table The unordered_map container to import
     */
    void import_tuning_params(const std::unordered_map<std::string, CLTuningParams> &tuning_params_table);

    /** Give read access to the LWS table
     *
     * @return The lws table as unordered_map container
     *
     * @deprecated This function is deprecated and is intended to be removed in 21.05 release
     */
    ARM_COMPUTE_DEPRECATED_REL_REPLACE(21.02, tuning_params_table)
    const std::unordered_map<std::string, cl::NDRange> &lws_table();

    /** Give read access to the tuning params table
     *
     * @return The tuning params table as unordered_map container
     */
    const std::unordered_map<std::string, CLTuningParams> &tuning_params_table() const;

    /** Set the OpenCL kernel event
     *
     * @note The interceptor can use this function to store the event associated to the OpenCL kernel
     *
     * @param[in] kernel_event The OpenCL kernel event
     */
    void set_cl_kernel_event(cl_event kernel_event);

    /** clEnqueueNDRangeKernel symbol */
    std::function<decltype(clEnqueueNDRangeKernel)> real_clEnqueueNDRangeKernel;

    /** Load the tuning parameters table from file. It also sets up the tuning read from the file
     *
     * @param[in] filename Load the tuning parameters table from this file.(Must exist)
     *
     */
    void load_from_file(const std::string &filename);

    /** Save the content of the tuning parameters table to file
     *
     * @param[in] filename Save the tuning parameters table to this file. (Content will be overwritten)
     *
     * @return true if the file was created
     */
    bool save_to_file(const std::string &filename) const;

    // Inherited methods overridden:
    void tune_kernel_static(ICLKernel &kernel) override;
    void tune_kernel_dynamic(ICLKernel &kernel) override;
    void tune_kernel_dynamic(ICLKernel &kernel, ITensorPack &tensors) override;

    /** Is the kernel_event set ?
     *
     * @return true if the kernel_event is set.
     */
    bool kernel_event_is_set() const;

private:
    /** Find optimal tuning parameters using brute-force approach
     *
     * @param[in]     kernel  OpenCL kernel to be tuned with tuning parameters
     * @param[in,out] tensors Tensors for the kernel to operate on
     *
     * @return The optimal tuning parameters to use
     */
    CLTuningParams find_optimal_tuning_params(ICLKernel &kernel, ITensorPack &tensors);

    std::unordered_map<std::string, CLTuningParams> _tuning_params_table;
    std::unordered_map<std::string, cl::NDRange>    _lws_table;
    cl::Event    _kernel_event;
    bool         _tune_new_kernels;
    CLTuningInfo _tuning_info;
};
} // namespace arm_compute
#endif /*ARM_COMPUTE_CLTUNER_H */
