/*
 * Copyright (c) 2020-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_CL /* Needed by Utils.cpp to handle OpenCL exceptions properly */
#error "This example needs to be built with -DARM_COMPUTE_CL"
#endif /* ARM_COMPUTE_CL */

#include "CommonGemmExampleOptions.h"
#include "GemmTunerHelpers.h"
#include "arm_compute/core/Helpers.h"
#include "arm_compute/core/KernelDescriptors.h"
#include "arm_compute/core/KernelDescriptors.h"
#include "arm_compute/core/Types.h"
#include "arm_compute/core/utils/misc/ShapeCalculator.h"
#include "arm_compute/core/utils/quantization/AsymmHelpers.h"
#include "arm_compute/runtime/CL/CLScheduler.h"
#include "arm_compute/runtime/CL/CLTuner.h"
#include "src/core/gpu/cl/kernels/ClGemmLowpMatrixMultiplyReshapedOnlyRhsKernel.h"
#include "src/core/gpu/cl/kernels/ClGemmLowpReductionKernel.h"
#include "tests/CL/Helper.h"
#include "utils/Utils.h"
#include "utils/command_line/CommandLineOptions.h"
#include "utils/command_line/CommandLineParser.h"

#include <cstdlib>
#include <memory>

using namespace arm_compute;
using namespace utils;
using namespace arm_compute::opencl::kernels;
using namespace arm_compute::misc::shape_calculator;
using namespace gemm_tuner;

namespace
{
/** Structure holding all tunable gemm configs specific to this example/strategy */
struct GemmConfigs
{
    size_t m0{ 4 };                /**< Number of rows processed by the matrix multiplication */
    size_t n0{ 4 };                /**< Number of columns processed by the matrix multiplication */
    size_t k0{ 4 };                /**< Number of partial accumulations performed by the matrix multiplication */
    size_t h0{ 1 };                /**< Number of horizontal blocks of size (k0xn0) stored on the same output row */
    bool   interleave_rhs{ true }; /**< Interleave rhs matrix */
    bool   transpose_rhs{ true };  /**< Transpose rhs matrix */
};

/** Formatted output of the GemmConfigs type
 *
 * @param[out] os      Output stream.
 * @param[in]  configs Tunable configurations to output
 *
 * @return Modified output stream.
 */
::std::ostream &operator<<(::std::ostream &os, const GemmConfigs &configs)
{
    std::string false_str = std::string("false");
    std::string true_str  = std::string("true");

    os << "m0 : " << configs.m0 << std::endl;
    os << "n0 : " << configs.n0 << std::endl;
    os << "k0 : " << configs.k0 << std::endl;
    os << "h0 : " << configs.h0 << std::endl;
    os << "interleave_rhs : " << (configs.interleave_rhs ? true_str : false_str) << std::endl;
    os << "transpose_rhs : " << (configs.transpose_rhs ? true_str : false_str) << std::endl;
    return os;
}

/** Command line options for gemm configs */
class GemmConfigOptions
{
public:
    /** Constructor
     *
     * @param[in,out] parser A parser on which "parse()" hasn't been called yet.
     */
    GemmConfigOptions(CommandLineParser &parser)
        : m0(parser.add_positional_option<SimpleOption<size_t>>("m0", 4)),
          n0(parser.add_positional_option<SimpleOption<size_t>>("n0", 4)),
          k0(parser.add_positional_option<SimpleOption<size_t>>("k0", 4)),
          h0(parser.add_positional_option<SimpleOption<size_t>>("h0", 1)),
          interleave_rhs(parser.add_positional_option<SimpleOption<size_t>>("interleave_rhs", 1)),
          transpose_rhs(parser.add_positional_option<SimpleOption<size_t>>("transpose_rhs", 1))
    {
        m0->set_help("Number of rows processed by the matrix multiplication");
        n0->set_help("Number of columns processed by the matrix multiplication");
        k0->set_help("Number of partial accumulations performed by the matrix multiplication");
        h0->set_help("Number of horizontal blocks of size (k0xn0) stored on the same output row");
        interleave_rhs->set_help("Interleave rhs matrix (1) / Do not interleave rhs matrix (0)");
        transpose_rhs->set_help("Transpose rhs matrix (1) / Do not transpose rhs matrix (0)");
    }
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    GemmConfigOptions(const GemmConfigOptions &) = delete;
    /** Prevent instances of this class from being copied (As this class contains pointers) */
    GemmConfigOptions &operator=(const GemmConfigOptions &) = delete;
    /** Allow instances of this class to be moved */
    GemmConfigOptions(GemmConfigOptions &&) = default;
    /** Allow instances of this class to be moved */
    GemmConfigOptions &operator=(GemmConfigOptions &&) = default;
    /** Default destructor */
    ~GemmConfigOptions() = default;

    SimpleOption<size_t> *m0;             /**< Number of rows processed by the matrix multiplication option */
    SimpleOption<size_t> *n0;             /**< Number of columns processed by the matrix multiplication option */
    SimpleOption<size_t> *k0;             /**< Number of partial accumulations performed by the matrix multiplication option */
    SimpleOption<size_t> *h0;             /**< Number of horizontal blocks of size (k0xn0) stored on the same output row option */
    SimpleOption<size_t> *interleave_rhs; /**< Interleave rhs matrix option (1 enable; 0 disable) */
    SimpleOption<size_t> *transpose_rhs;  /**< Transpose rhs matrix option (1 enable; 0 disable) */
};

/** Consumes the gemm configuration options and creates a structure containing all information
 *
 * @param[in] options Options to consume
 *
 * @return Structure containing the gemm configurations
 */
GemmConfigs consume_gemm_configs(const GemmConfigOptions &options)
{
    GemmConfigs configs;
    configs.m0             = options.m0->value();
    configs.n0             = options.n0->value();
    configs.k0             = options.k0->value();
    configs.h0             = options.h0->value();
    configs.interleave_rhs = options.interleave_rhs->value() != 0;
    configs.transpose_rhs  = options.transpose_rhs->value() != 0;
    return configs;
}

} // namespace

using ClGemmLowpMatrixMultiplyReshapedOnlyRhs = test::CLSynthetizeOperator<ClGemmLowpMatrixMultiplyReshapedOnlyRhsKernel>;
using ClGemmLowpMatrixAReduction              = test::CLSynthetizeOperator<ClGemmLowpMatrixAReductionKernel>;

class CLGEMMLowpMatrixMultiplyReshapedOnlyRHSFusedOutputStageFixedpointExample : public Example
{
public:
    bool do_setup(int argc, char **argv) override
    {
        // Default parameters
        CommonGemmExampleParams params;
        GemmConfigs             configs;

        // Parse command line options
        CommandLineParser        parser;
        CommonGemmExampleOptions param_options(parser, DataType::QASYMM8);
        GemmConfigOptions        config_options(parser);

        parser.parse(argc, argv);
        if(param_options.help->is_set() && param_options.help->value())
        {
            parser.print_help(argv[0]);
            return false;
        }
        if(!parser.validate())
        {
            // Invalid arguments. Use default parameters and configs
            std::cerr << "Invalid arguments." << std::endl;
            parser.print_help(argv[0]);
            std::cerr << "Falling back to default parameters and configs" << std::endl;
        }
        else
        {
            params  = consume_common_gemm_example_parameters(param_options);
            configs = consume_gemm_configs(config_options);
        }

        std::cout << "Gemm parameters:" << std::endl;
        std::cout << params << std::endl;
        std::cout << "Gemm configurations:" << std::endl;
        std::cout << configs << std::endl;

        tuner.set_tuner_mode(params.tuner_mode);

        CLScheduler::get().default_init(&tuner);

        lhs.allocator()->init(TensorInfo(TensorShape(params.K, params.M, params.B), 1, params.data_type));
        rhs.allocator()->init(TensorInfo(TensorShape(params.N, params.K, params.B), 1, params.data_type));
        bias.allocator()->init(TensorInfo(TensorShape(params.N), 1, DataType::S32));
        dst.allocator()->init(TensorInfo(TensorShape(params.N, params.M, params.B), 1, params.data_type));

        // Set arbitrary quantization information (non-zero offset to ensure offset contribution stage is included)
        // Could be extended in the future to include a user-controlled option for offset == 0
        const QuantizationInfo q_info
        {
            0.012, 3
        };
        lhs.info()->set_quantization_info(q_info);
        rhs.info()->set_quantization_info(q_info);
        bias.info()->set_quantization_info(q_info);
        dst.info()->set_quantization_info(q_info);

        GEMMLHSMatrixInfo lhs_info;
        lhs_info.m0 = configs.m0;
        lhs_info.k0 = configs.k0;

        GEMMRHSMatrixInfo rhs_info;
        rhs_info.n0                 = configs.n0;
        rhs_info.k0                 = configs.k0;
        rhs_info.h0                 = configs.h0;
        rhs_info.interleave         = configs.interleave_rhs;
        rhs_info.transpose          = configs.transpose_rhs;
        rhs_info.export_to_cl_image = false; // CL image not supported for quantized cases yet

        rhs_reshaped.allocator()->init(TensorInfo(compute_rhs_reshaped_shape(*rhs.info(), rhs_info), 1, params.data_type));
        rhs_reshaped.info()->set_quantization_info(q_info);
        if(rhs_info.export_to_cl_image)
        {
            if(!examples::gemm_tuner_helpers::update_padding_for_cl_image(rhs_reshaped.info()))
            {
                std::cerr << "cl_image is not supported on the device, disable export_to_cl_image" << std::endl;
                return false;
            }
        }

        // Configure output stage for quantized case
        GEMMLowpOutputStageInfo gemmlowp_output_stage;
        gemmlowp_output_stage.type             = GEMMLowpOutputStageType::QUANTIZE_DOWN_FIXEDPOINT;
        gemmlowp_output_stage.output_data_type = dst.info()->data_type();
        gemmlowp_output_stage.gemmlowp_offset  = 0;
        {
            gemmlowp_output_stage.is_quantized_per_channel = false;
            // Num_filters is 1 unless quantized type is of per_channel type. Could be extended in the future to support per-channel quantization.
            const unsigned int num_filters = 1;

            dst_multipliers.allocator()->init(TensorInfo(TensorShape(num_filters), 1, DataType::S32));
            dst_shifts.allocator()->init(TensorInfo(TensorShape(num_filters), 1, DataType::S32));

            gemmlowp_output_stage.gemmlowp_multipliers.resize(num_filters);
            gemmlowp_output_stage.gemmlowp_shifts.resize(num_filters);
            quantization::compute_quantized_multipliers_and_shifts(lhs.info(),
                                                                   rhs.info(),
                                                                   dst.info(),
                                                                   gemmlowp_output_stage.gemmlowp_multipliers.data(),
                                                                   gemmlowp_output_stage.gemmlowp_shifts.data());
            gemmlowp_output_stage.gemmlowp_multiplier = gemmlowp_output_stage.gemmlowp_multipliers[0];
            gemmlowp_output_stage.gemmlowp_shift      = gemmlowp_output_stage.gemmlowp_shifts[0];

            // No fused activation
            PixelValue min_val{};
            PixelValue max_val{};
            std::tie(min_val, max_val) = get_min_max(dst.info()->data_type());

            auto min_activation = min_val.get<int32_t>();
            auto max_activation = max_val.get<int32_t>();

            // Set the GEMMLowp output stage info
            gemmlowp_output_stage.gemmlowp_offset    = dst.info()->quantization_info().uniform().offset;
            gemmlowp_output_stage.gemmlowp_min_bound = min_activation;
            gemmlowp_output_stage.gemmlowp_max_bound = max_activation;
        }

        GEMMKernelInfo gemm_info;
        gemm_info.m                       = params.M;
        gemm_info.n                       = params.N;
        gemm_info.k                       = params.K;
        gemm_info.depth_output_gemm3d     = 0;
        gemm_info.reinterpret_input_as_3d = false;
        gemm_info.broadcast_bias          = true;
        gemm_info.fp_mixed_precision      = false;
        gemm_info.has_pad_y               = false;
        gemm_info.mult_transpose1xW_width = configs.h0;
        gemm_info.lhs_info                = lhs_info;
        gemm_info.rhs_info                = rhs_info;
        gemm_info.a_offset                = lhs.info()->quantization_info().uniform().offset;
        gemm_info.b_offset                = rhs.info()->quantization_info().uniform().offset;
        gemm_info.output_stage            = gemmlowp_output_stage;

        // Initialize Matrix A reduction kernel only if _b_offset is not equal to 0
        if(gemm_info.b_offset != 0)
        {
            const TensorInfo info_vector_sum_row(compute_reductionB_shape(*lhs.info()), 1, DataType::S32);
            vector_sum_row.allocator()->init(info_vector_sum_row);

            mtx_a_reduction = std::make_unique<ClGemmLowpMatrixAReduction>();

            if(!mtx_a_reduction->validate(lhs.info(), vector_sum_row.info(), GEMMLowpReductionKernelInfo{}))
            {
                std::cerr << "Invalid arguments for CLGEMMLowpMatrixAReductionKernel." << std::endl;
                return false;
            }

            mtx_a_reduction->configure(lhs.info(), vector_sum_row.info(), GEMMLowpReductionKernelInfo{});
        }
        // Initialize matrix B reduction kernel only if _a_offset is not equal to 0
        if(gemm_info.a_offset != 0)
        {
            const TensorInfo info_vector_sum_col(compute_reductionA_shape(*rhs.info()), 1, DataType::S32);
            vector_sum_col.allocator()->init(info_vector_sum_col);
            // There's no need for a Matrix B reduction kernel as this is assumed to be run only once in the prepare stage
        }

        // Validate argments
        if(!gemm.validate(lhs.info(), rhs_reshaped.info(), dst.info(), gemm_info, gemm_info.a_offset == 0 ? nullptr : vector_sum_col.info(),
                          gemm_info.b_offset == 0 ? nullptr : vector_sum_row.info(), bias.info(), dst_multipliers.info(), dst_shifts.info()))
        {
            std::cerr << "Invalid arguments for ClGemmLowpMatrixMultiplyReshapedOnlyRhsKernel." << std::endl;
            return false;
        }

        // Configure function
        gemm.configure(lhs.info(), rhs_reshaped.info(), dst.info(), gemm_info,
                       gemm_info.a_offset == 0 ? nullptr : vector_sum_col.info(), gemm_info.b_offset == 0 ? nullptr : vector_sum_row.info(),
                       bias.info(), dst_multipliers.info(), dst_shifts.info());

        // Allocate tensors
        lhs.allocator()->allocate();
        rhs.allocator()->allocate();
        rhs_reshaped.allocator()->allocate();
        bias.allocator()->allocate();
        dst.allocator()->allocate();
        vector_sum_col.allocator()->allocate();
        vector_sum_row.allocator()->allocate();
        dst_multipliers.allocator()->allocate();
        dst_shifts.allocator()->allocate();

        return true;
    }
    void do_run() override
    {
        if(mtx_a_reduction != nullptr)
        {
            ITensorPack red_pack({ { ACL_SRC, &lhs }, { ACL_DST, &dst } });
            mtx_a_reduction->run(red_pack);
        }

        ITensorPack gemm_pack({ { ACL_SRC_0, &lhs }, { ACL_SRC_1, &rhs }, { ACL_BIAS, &bias }, { ACL_VEC_COL_SUM, &vector_sum_col }, { ACL_VEC_ROW_SUM, &vector_sum_row }, { ACL_SHIFTS, &dst_shifts }, { ACL_MULTIPLIERS, &dst_multipliers }, { ACL_DST, &dst } });
        gemm.run(gemm_pack);

        // Make sure all the OpenCL jobs are done executing:
        CLScheduler::get().sync();
    }

    void do_teardown() override
    {
    }

private:
    CLTensor                                    lhs{};
    CLTensor                                    rhs{};
    CLTensor                                    rhs_reshaped{};
    CLTensor                                    bias{};
    CLTensor                                    dst{};
    CLTensor                                    vector_sum_col{};
    CLTensor                                    vector_sum_row{};
    CLTensor                                    dst_multipliers{};
    CLTensor                                    dst_shifts{};
    CLTuner                                     tuner{};
    ClGemmLowpMatrixMultiplyReshapedOnlyRhs     gemm{};
    std::unique_ptr<ClGemmLowpMatrixAReduction> mtx_a_reduction{ nullptr };
};

/** Main test program for gemmlowp reshaped rhs only with fused output stage fixedpoint
 *
 * @param[in] argc Number of arguments
 * @param[in] argv Arguments ( [optional] M, [optional] N, [optional] K, [optional] B, [optional] m0, [optional] n0, [optional] k0, [optional] h0, [optional] interleave_rhs, [optional] transpose_rhs )
 */
int main(int argc, char **argv)
{
    return run_example<CLGEMMLowpMatrixMultiplyReshapedOnlyRHSFusedOutputStageFixedpointExample>(argc, argv);
}
