/*
 * Copyright (c) 2020 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 <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 */
