/*
 * Copyright (c) 2019 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_LWS_LIST_H
#define ARM_COMPUTE_CL_LWS_LIST_H

#include "arm_compute/core/CL/OpenCL.h"
#include "arm_compute/core/Error.h"
#include "arm_compute/core/Helpers.h"
#include "arm_compute/runtime/CL/CLTunerTypes.h"
#include "support/ToolchainSupport.h"
#include <memory>

namespace arm_compute
{
namespace cl_tuner
{
constexpr unsigned int max_lws_supported_x{ 64u };
constexpr unsigned int max_lws_supported_y{ 32u };
constexpr unsigned int max_lws_supported_z{ 32u };

/** Interface for LWS lists */
class ICLLWSList
{
public:
    /** Constructor */
    ICLLWSList() = default;
    /** Copy Constructor */
    ICLLWSList(const ICLLWSList &) = default;
    /** Move Constructor */
    ICLLWSList(ICLLWSList &&) noexcept(true) = default;
    /** Assignment */
    ICLLWSList &operator=(const ICLLWSList &) = default;
    /** Move Assignment */
    ICLLWSList &operator=(ICLLWSList &&) noexcept(true) = default;
    /** Destructor */
    virtual ~ICLLWSList() = default;

    /** Return the LWS value at the given index.
     *
     * @return LWS value at the given index
     */
    virtual cl::NDRange operator[](size_t) = 0;

    /** LWS list size.
     *
     * @return LWS list size
     */
    virtual size_t size() = 0;
};

/** Non instantiable base class for LWS combinations that use Index2Cooard mapping */
class CLLWSList : public ICLLWSList
{
protected:
    /* Shape of 3-D search space */
    TensorShape search_space_shape{ 0, 0, 0 };

    /** Constructor */
    CLLWSList() = default;
    /** Copy Constructor */
    CLLWSList(const CLLWSList &) = default;
    /** Move Constructor */
    CLLWSList(CLLWSList &&) noexcept(true) = default;
    /** Assignment */
    CLLWSList &operator=(const CLLWSList &) = default;
    /** Move Assignment */
    CLLWSList &operator=(CLLWSList &&) noexcept(true) = default;
    /** Destructor */
    virtual ~CLLWSList() = default;

    // Inherited methods overridden:
    virtual size_t size() override;
};

/** Exhaustive list of all possible LWS values */
class CLLWSListExhaustive : public CLLWSList
{
public:
    /** Prevent default constructor calls */
    CLLWSListExhaustive() = delete;
    /** Constructor */
    CLLWSListExhaustive(const cl::NDRange &gws);
    /** Copy Constructor */
    CLLWSListExhaustive(const CLLWSListExhaustive &) = default;
    /** Move Constructor */
    CLLWSListExhaustive(CLLWSListExhaustive &&) noexcept(true) = default;
    /** Assignment */
    CLLWSListExhaustive &operator=(const CLLWSListExhaustive &) = default;
    /** Move Assignment */
    CLLWSListExhaustive &operator=(CLLWSListExhaustive &&) noexcept(true) = default;
    /** Destructor */
    ~CLLWSListExhaustive() = default;

    // Inherited methods overridden:
    cl::NDRange operator[](size_t) override;
};

/** A subset of LWS values that are either factors of gws when gws[2] < 16 or power of 2 */
class CLLWSListNormal : public CLLWSList
{
public:
    /** Constructor */
    CLLWSListNormal(const cl::NDRange &gws);
    /** Copy Constructor */
    CLLWSListNormal(const CLLWSListNormal &) = default;
    /** Move Constructor */
    CLLWSListNormal(CLLWSListNormal &&) noexcept(true) = default;
    /** Assignment */
    CLLWSListNormal &operator=(const CLLWSListNormal &) = default;
    /** Move Assignment */
    CLLWSListNormal &operator=(CLLWSListNormal &&) noexcept(true) = default;
    /** Destructor */
    ~CLLWSListNormal() = default;

    // Inherited methods overridden:
    cl::NDRange operator[](size_t) override;

protected:
    std::vector<unsigned int> _lws_x{};
    std::vector<unsigned int> _lws_y{};
    std::vector<unsigned int> _lws_z{};

    /** Prevent default constructor calls */
    CLLWSListNormal() = default;

private:
    /** Utility function used to initialize the LWS values to test.
     *  Only the LWS values which are power of 2 or satisfy the modulo conditions with GWS are taken into account by the CLTuner
     *
     * @param[in, out] lws         Vector of LWS to test
     * @param[in]      gws         Size of the specific GWS
     * @param[in]      lws_max     Max LWS value allowed to be tested
     * @param[in]      mod_let_one True if the results of the modulo operation between gws and the lws can be less than one.
     */
    void initialize_lws_values(std::vector<unsigned int> &lws, unsigned int gws, unsigned int lws_max, bool mod_let_one);
};

/** A minimal subset of LWS values that only have 1,2 and 4/8 */
class CLLWSListRapid : public CLLWSListNormal
{
public:
    /** Prevent default constructor calls */
    CLLWSListRapid() = delete;
    /** Constructor */
    CLLWSListRapid(const cl::NDRange &gws);
    /** Copy Constructor */
    CLLWSListRapid(const CLLWSListRapid &) = default;
    /** Move Constructor */
    CLLWSListRapid(CLLWSListRapid &&) noexcept(true) = default;
    /** Assignment */
    CLLWSListRapid &operator=(const CLLWSListRapid &) = default;
    /** Move Assignment */
    CLLWSListRapid &operator=(CLLWSListRapid &&) noexcept(true) = default;
    /** Destructor */
    virtual ~CLLWSListRapid() = default;

private:
    /** Utility function used to initialize the LWS values to test.
     *  Only the LWS values that have 1,2 and 4/8 for each dimension are taken into account by the CLTuner
     *
     * @param[in, out] lws     Vector of LWS to test
     * @param[in]      lws_max Max LWS value allowed to be tested
     */
    void initialize_lws_values(std::vector<unsigned int> &lws, unsigned int lws_max);
};

/** Factory to construct an ICLLWSList object based on the CL tuner mode */
class CLLWSListFactory final
{
public:
    /** Construct an ICLLWSList object for the given tuner mode and gws configuration.
     *
     * @return unique_ptr to the requested ICLLWSList implementation.
     */
    static std::unique_ptr<ICLLWSList> get_lws_list(CLTunerMode mode, const cl::NDRange &gws)
    {
        switch(mode)
        {
            case CLTunerMode::EXHAUSTIVE:
                return arm_compute::support::cpp14::make_unique<CLLWSListExhaustive>(gws);
            case CLTunerMode::NORMAL:
                return arm_compute::support::cpp14::make_unique<CLLWSListNormal>(gws);
            case CLTunerMode::RAPID:
                return arm_compute::support::cpp14::make_unique<CLLWSListRapid>(gws);
            default:
                return nullptr;
        }
    }
};
} // namespace cl_tuner
} // namespace arm_compute
#endif /*ARM_COMPUTE_CL_LWS_LIST_H */
