/*
 * 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_CLDEVICE_H
#define ARM_COMPUTE_CLDEVICE_H

#include "arm_compute/core/CL/CLHelpers.h"
#include "arm_compute/core/CL/CLTypes.h"
#include "arm_compute/core/GPUTarget.h"
#include "arm_compute/core/IDevice.h"

#include <set>
#include <sstream>
#include <string>

namespace arm_compute
{
/**  OpenCL device type class
 *
 *   Initializes and stores all the information about a cl device,
 *   working mainly as a cache mechanism.
 * */
class CLDevice : public IDevice
{
public:
    /** Default Constructor */
    CLDevice()
        : _device(cl::Device()), _options()
    {
    }

    /** Constructor
     *
     * @param[in] cl_device OpenCL device
     */
    CLDevice(const cl::Device &cl_device)
        : _device(), _options()
    {
        _device = cl_device;

        // Get device target
        std::string device_name = _device.getInfo<CL_DEVICE_NAME>();
        _options.gpu_target     = get_target_from_name(device_name);

        // Fill extensions
        std::string extensions = _device.getInfo<CL_DEVICE_EXTENSIONS>();

        std::istringstream iss(extensions);
        for(std::string s; iss >> s;)
        {
            _options.extensions.insert(s);
        }

        // SW workaround for G76
        if(_options.gpu_target == GPUTarget::G76)
        {
            _options.extensions.insert("cl_arm_integer_dot_product_int8");
        }

        // Get device version
        _options.version = get_cl_version(_device);

        // Get compute units
        _options.compute_units = _device.getInfo<CL_DEVICE_MAX_COMPUTE_UNITS>();

        // Get device version
        _options.device_version = _device.getInfo<CL_DEVICE_VERSION>();
    }

    /** Returns the GPU target of the cl device
     *
     * @return The GPU target
     */
    const GPUTarget &target() const
    {
        return _options.gpu_target;
    }

    /** Returns the number of compute units available
     *
     * @return Number of compute units
     */
    size_t compute_units() const
    {
        return _options.compute_units;
    }

    /** Returns the underlying cl device object
     *
     * @return A cl device
     */
    const cl::Device &cl_device() const
    {
        return _device;
    }

    /** Returns the device's CL version
     *
     * @return CLVersion of the device
     */
    CLVersion version() const
    {
        return _options.version;
    }

    /** Returns the device version as a string
     *
     * @return CLVersion of the device
     */
    std::string device_version() const
    {
        return _options.device_version;
    }

    // Inherrited methods
    DeviceType type() const override
    {
        return DeviceType::CL;
    }

    bool supported(const std::string &extension) const override
    {
        return _options.extensions.count(extension) != 0;
    }

private:
    cl::Device             _device;  /**< OpenCL device. */
    struct CLDeviceOptions _options; /**< OpenCL device options */
};

} // namespace arm_compute

#endif /* ARM_COMPUTE_CLDEVICE_H */
