/*
 * Copyright (c) 2017-2022 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/functions/CLGEMM.h"

#include "arm_compute/core/CL/CLHelpers.h"
#include "arm_compute/core/CL/CLKernelLibrary.h"
#include "arm_compute/core/Helpers.h"
#include "arm_compute/core/KernelDescriptors.h"
#include "arm_compute/core/TensorInfo.h"
#include "arm_compute/core/Types.h"
#include "arm_compute/core/Utils.h"

#include "src/core/helpers/MemoryHelpers.h"
#include "src/gpu/cl/operators/ClGemm.h"

namespace arm_compute
{
using namespace arm_compute::experimental;
using OperatorType = opencl::ClGemm;

struct CLGEMM::Impl
{
    const ICLTensor              *b{nullptr};
    std::unique_ptr<OperatorType> op{nullptr};
    MemoryGroup                   memory_group{};
    IWeightsManager              *weights_manager{nullptr};
    ITensorPack                   run_pack{};
    ITensorPack                   prep_pack{};
    MemoryRequirements            aux_mem_req{};
    WorkspaceData<CLTensor>       workspace_tensors{};
    bool                          is_prepared{false};
};

CLGEMM::CLGEMM(std::shared_ptr<IMemoryManager> memory_manager, IWeightsManager *weights_manager)
    : _impl(std::make_unique<Impl>())
{
    _impl->memory_group    = MemoryGroup(memory_manager);
    _impl->weights_manager = weights_manager;
}

CLGEMM::~CLGEMM() = default;

void CLGEMM::configure(const ICLTensor *a,
                       const ICLTensor *b,
                       const ICLTensor *c,
                       ICLTensor       *output,
                       float            alpha,
                       float            beta,
                       const GEMMInfo  &gemm_info)
{
    configure(CLKernelLibrary::get().get_compile_context(), a, b, c, output, alpha, beta, gemm_info);
}

void CLGEMM::configure(const CLCompileContext &compile_context,
                       const ICLTensor        *a,
                       const ICLTensor        *b,
                       const ICLTensor        *c,
                       ICLTensor              *output,
                       float                   alpha,
                       float                   beta,
                       const GEMMInfo         &gemm_info)
{
    ARM_COMPUTE_ERROR_ON_NULLPTR(a, b, output);

    _impl->b           = b;
    _impl->op          = std::make_unique<OperatorType>();
    _impl->is_prepared = gemm_info.retain_internal_weights();

    _impl->op->configure(compile_context, a->info(), b->info(), c != nullptr ? c->info() : nullptr, output->info(),
                         alpha, beta, gemm_info);
    _impl->aux_mem_req = _impl->op->workspace();

    // Manage/allocate auxilairy tensors
    if (_impl->is_prepared)
    {
        _impl->run_pack.add_const_tensor(ACL_SRC_0, a);
        _impl->run_pack.add_tensor(ACL_DST, output);
    }
    else
    {
        _impl->run_pack  = {{ACL_SRC_0, a}, {ACL_SRC_2, c}, {ACL_DST, output}};
        _impl->prep_pack = {{ACL_SRC_1, _impl->b}};

        _impl->workspace_tensors =
            manage_workspace<CLTensor>(_impl->op->workspace(), _impl->memory_group, _impl->run_pack, _impl->prep_pack);
    }
}

Status CLGEMM::validate(const ITensorInfo *a,
                        const ITensorInfo *b,
                        const ITensorInfo *c,
                        const ITensorInfo *output,
                        float              alpha,
                        float              beta,
                        const GEMMInfo    &gemm_info)
{
    return OperatorType::validate(a, b, c, output, alpha, beta, gemm_info);
}

void CLGEMM::run()
{
    prepare();

    MemoryGroupResourceScope scope_mg(_impl->memory_group);

    _impl->op->run(_impl->run_pack);
}

void CLGEMM::prepare()
{
    if (!_impl->is_prepared)
    {
        _impl->op->prepare(_impl->prep_pack);

        auto has_reshape =
            std::find_if(_impl->aux_mem_req.begin(), _impl->aux_mem_req.end(),
                         [](const MemoryInfo &m) -> bool { return m.lifetime == MemoryLifetime::Persistent; });

        if (has_reshape != std::end(_impl->aux_mem_req))
        {
            _impl->b->mark_as_unused();
        }
        else
        {
            // Pack the B matrix to be used as the underlying GEMM performs no reshapes
            _impl->run_pack.add_const_tensor(ACL_SRC_1, _impl->b);
        }
        _impl->is_prepared = true;
    }
}
} // namespace arm_compute
