/*
 * Copyright (c) 2019-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.
 */
#include "arm_compute/runtime/CL/tuners/CLTuningParametersList.h"

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 };

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

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

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

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

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

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

    // Inherited methods overridden:
    CLTuningParams 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 */
    CLTuningParametersListNormal() = 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 CLTuningParametersListRapid : public CLTuningParametersListNormal
{
public:
    /** Prevent default constructor calls */
    CLTuningParametersListRapid() = delete;
    /** Constructor */
    CLTuningParametersListRapid(const cl::NDRange &gws);
    /** Copy Constructor */
    CLTuningParametersListRapid(const CLTuningParametersListRapid &) = default;
    /** Move Constructor */
    CLTuningParametersListRapid(CLTuningParametersListRapid &&) noexcept(true) = default;
    /** Assignment */
    CLTuningParametersListRapid &operator=(const CLTuningParametersListRapid &) = default;
    /** Move Assignment */
    CLTuningParametersListRapid &operator=(CLTuningParametersListRapid &&) noexcept(true) = default;
    /** Destructor */
    virtual ~CLTuningParametersListRapid() = 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);
};

size_t CLTuningParametersList::size()
{
    return search_space_shape.total_size();
}

CLTuningParams CLTuningParametersListExhaustive::operator[](size_t index)
{
    ARM_COMPUTE_ERROR_ON(index >= size());
    auto coords = index2coords(search_space_shape, index);
    return CLTuningParams(coords[0] + 1U, coords[1] + 1U, coords[2] + 1U);
}

CLTuningParametersListExhaustive::CLTuningParametersListExhaustive(const cl::NDRange &gws)
{
    ARM_COMPUTE_UNUSED(gws);
    search_space_shape = TensorShape(max_lws_supported_x,
                                     max_lws_supported_y,
                                     max_lws_supported_z);
}

CLTuningParams CLTuningParametersListNormal::operator[](size_t index)
{
    ARM_COMPUTE_ERROR_ON(index >= size());
    auto coords = index2coords(search_space_shape, index);
    return CLTuningParams(_lws_x[coords[0]], _lws_y[coords[1]], _lws_z[coords[2]]);
}

CLTuningParametersListNormal::CLTuningParametersListNormal(const cl::NDRange &gws)
{
    auto lws_x_max = std::min(static_cast<unsigned int>(gws[0]), max_lws_supported_x);
    auto lws_y_max = std::min(static_cast<unsigned int>(gws[1]), max_lws_supported_y);
    auto lws_z_max = std::min(static_cast<unsigned int>(gws[2]), max_lws_supported_z);

    // Initialize the LWS values to test
    initialize_lws_values(_lws_x, gws[0], lws_x_max, gws[2] > 16); // Explore lws that are not factors of gws only when gws[2] > 16
    initialize_lws_values(_lws_y, gws[1], lws_y_max, gws[2] > 16); // Explore lws that are not factors of gws only when gws[2] > 16
    initialize_lws_values(_lws_z, gws[2], lws_z_max, false);

    search_space_shape = TensorShape(_lws_x.size(), _lws_y.size(), _lws_z.size());
}

void CLTuningParametersListNormal::initialize_lws_values(std::vector<unsigned int> &lws, unsigned int gws, unsigned int lws_max, bool mod_let_one)
{
    lws.push_back(1);

    for(unsigned int i = 2; i <= lws_max; ++i)
    {
        // Power of two condition
        const bool is_power_of_two = (i & (i - 1)) == 0;

        // Condition for the module accordingly with the mod_let_one flag
        const bool mod_cond = mod_let_one ? (gws % i) <= 1 : (gws % i) == 0;

        if(mod_cond || is_power_of_two)
        {
            lws.push_back(i);
        }
    }
}

CLTuningParametersListRapid::CLTuningParametersListRapid(const cl::NDRange &gws)
{
    auto lws_x_max = std::min(static_cast<unsigned int>(gws[0]), 8u); // Limit exploration to 1 - 8
    auto lws_y_max = std::min(static_cast<unsigned int>(gws[1]), 4u); // Limit exploration to 1 - 4
    auto lws_z_max = std::min(static_cast<unsigned int>(gws[2]), 4u); // Limit exploration to 1 - 4

    // Initialize the LWS values to test
    initialize_lws_values(_lws_x, lws_x_max);
    initialize_lws_values(_lws_y, lws_y_max);
    initialize_lws_values(_lws_z, lws_z_max);

    search_space_shape = TensorShape(_lws_x.size(), _lws_y.size(), _lws_z.size());
}

void CLTuningParametersListRapid::initialize_lws_values(std::vector<unsigned int> &lws, unsigned int lws_max)
{
    lws.push_back(1);

    for(unsigned int i = 2; i <= lws_max; i *= 4)
    {
        lws.push_back(i);
    }
}

std::unique_ptr<ICLTuningParametersList> get_tuning_parameters_list(CLTunerMode mode, const cl::NDRange &gws)
{
    switch(mode)
    {
        case CLTunerMode::EXHAUSTIVE:
            return std::make_unique<CLTuningParametersListExhaustive>(gws);
        case CLTunerMode::NORMAL:
            return std::make_unique<CLTuningParametersListNormal>(gws);
        case CLTunerMode::RAPID:
            return std::make_unique<CLTuningParametersListRapid>(gws);
        default:
            return nullptr;
    }
}
} // namespace cl_tuner
} // namespace arm_compute
