/*
 * Copyright (c) 2016-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/core/CL/CLKernelLibrary.h"

#include "arm_compute/core/Error.h"

#include "src/gpu/cl/ClKernelLibrary.h"

#include <algorithm>
#include <array>
#include <fstream>
#include <utility>
#include <vector>
namespace arm_compute
{
CLKernelLibrary::CLKernelLibrary() : _compile_context()
{
    opencl_is_available(); // Make sure the OpenCL symbols are initialised *before* the CLKernelLibrary is built
}
CLKernelLibrary &CLKernelLibrary::get()
{
    static CLKernelLibrary _kernel_library;
    return _kernel_library;
}
Kernel CLKernelLibrary::create_kernel(const std::string           &kernel_name,
                                      const std::set<std::string> &build_options_set) const
{
    const opencl::ClKernelLibrary &klib         = opencl::ClKernelLibrary::get();
    const std::string              program_name = klib.program_name(kernel_name);
    auto                           program      = klib.program(program_name);
    const std::string             &kernel_path  = CLKernelLibrary::get().get_kernel_path();
    return _compile_context.create_kernel(kernel_name, program_name, program.program, kernel_path, build_options_set,
                                          program.is_binary);
}
std::string CLKernelLibrary::get_program_name(const std::string &kernel_name) const
{
    return opencl::ClKernelLibrary::get().program_name(kernel_name);
}
void CLKernelLibrary::init(std::string kernel_path, cl::Context context, cl::Device device)
{
    _compile_context = CLCompileContext(context, device);
    opencl::ClKernelLibrary::get().set_kernel_path(kernel_path);
}
void CLKernelLibrary::set_kernel_path(const std::string &kernel_path)
{
    opencl::ClKernelLibrary::get().set_kernel_path(kernel_path);
}
cl::Context &CLKernelLibrary::context()
{
    return _compile_context.context();
}
const cl::Device &CLKernelLibrary::get_device()
{
    return _compile_context.get_device();
}
void CLKernelLibrary::set_device(cl::Device device)
{
    _compile_context.set_device(device);
}
void CLKernelLibrary::set_context(cl::Context context)
{
    _compile_context.set_context(context);
}
std::string CLKernelLibrary::get_kernel_path()
{
    return opencl::ClKernelLibrary::get().kernel_path();
}
void CLKernelLibrary::clear_programs_cache()
{
    _compile_context.clear_programs_cache();
}
const std::map<std::string, cl::Program> &CLKernelLibrary::get_built_programs() const
{
    return _compile_context.get_built_programs();
}
void CLKernelLibrary::add_built_program(const std::string &built_program_name, const cl::Program &program)
{
    _compile_context.add_built_program(built_program_name, program);
}
bool CLKernelLibrary::fp16_supported() const
{
    return _compile_context.fp16_supported();
}
bool CLKernelLibrary::int64_base_atomics_supported() const
{
    return _compile_context.int64_base_atomics_supported();
}
bool CLKernelLibrary::is_wbsm_supported()
{
    return _compile_context.is_wbsm_supported();
}
std::pair<std::string, bool> CLKernelLibrary::get_program(const std::string &program_name) const
{
    auto program_info = opencl::ClKernelLibrary::get().program(program_name);
    return std::make_pair(std::move(program_info.program), program_info.is_binary);
}
size_t CLKernelLibrary::max_local_workgroup_size(const cl::Kernel &kernel) const
{
    return _compile_context.max_local_workgroup_size(kernel);
}
cl::NDRange CLKernelLibrary::default_ndrange() const
{
    return _compile_context.default_ndrange();
}
std::string CLKernelLibrary::get_device_version()
{
    return _compile_context.get_device_version();
}
cl_uint CLKernelLibrary::get_num_compute_units()
{
    return _compile_context.get_num_compute_units();
}
CLCompileContext &CLKernelLibrary::get_compile_context()
{
    return _compile_context;
}
} // namespace arm_compute
