使用C++实现OpenCL探针


1111.png

OpenCL是一个并行计算工业标准,相比OpenGL,OpenCL的特长是并行计算,而OpenGL的特长是图像渲染。最近研究OpenCL的时候发现相关的工具还是比较少,学习和使用都不是很方便,因此特编写了一个简单的OpenCL探针。这款名叫《OpenCLMonitor》的软件可以列出计算机上所有支持OpenCL的设备,每个设备的信息,包括设备名称、设备厂商、工作组维度、工作组大小等等。《OpenCLMonitor》使用了OpenCL的C++语言API,相比C语言API,C++语言API使用更容易,传递的参数更少、代码长度更短。

OpenCLMonitor代码

// OpenCLMonitor.cpp : 此文件包含 "main" 函数。程序执行将在此处开始并结束。
//
//#define CL_HPP_ENABLE_EXCEPTIONS
#define CL_HPP_TARGET_OPENCL_VERSION 210

#include <iostream>
#include "cl/cl2.hpp"

#define PRINT_PLATFORM_INFO(PLATFORM, INFO_NAME) \
{\
    std::string platformInfo;\
    int rs = PLATFORM.getInfo(INFO_NAME, &platformInfo);\
    if (rs == CL_SUCCESS)\
    {\
        std::cout << #INFO_NAME << ":\t" << platformInfo << std::endl;\
    }\
    else\
    {\
        std::cout << #INFO_NAME << ":\t" << "error(" << rs << ")" << std::endl;\
    }\
}

#define PRINT_DEVICE_INFO(DEVICE, INFO_NAME) \
{\
    int rs = CL_SUCCESS;\
    auto deviceInfo = DEVICE.getInfo<INFO_NAME>(&rs);\
    std::string infoNameStr(#INFO_NAME ":");\
    while (infoNameStr.size() < 40)\
    {\
        infoNameStr.push_back(' ');\
    }\
    if (rs == CL_SUCCESS)\
    {\
        std::cout << "\t" << infoNameStr << "\t" << deviceInfo << std::endl;\
    }\
    else\
    {\
        std::cout << "\t" << infoNameStr << "\t" << "error(" << rs << ")" << std::endl;\
    }\
}

#define PRINT_DEVICE_INFO_SIZE_T_ARRAY(DEVICE, INFO_NAME) \
{\
    int rs = CL_SUCCESS;\
    auto deviceInfo = DEVICE.getInfo<INFO_NAME>(&rs);\
    std::string infoNameStr(#INFO_NAME ":");\
    while (infoNameStr.size() < 40)\
    {\
        infoNameStr.push_back(' ');\
    }\
    if (rs == CL_SUCCESS)\
    {\
        std::cout << "\t" << infoNameStr << "\t"; \
        for (auto it = deviceInfo.begin(); it != deviceInfo.end(); it++)\
        {\
            std::cout << *it << ",";\
        }\
        std::cout << std::endl;\
    }\
    else\
    {\
        std::cout << "\t" << infoNameStr << "\t" << "error(" << rs << ")" << std::endl;\
    }\
}

int main()
{
    std::cout << "OpenCL monitor, powered by http://www.xiaoyunyun.net." << std::endl << std::endl;

    std::vector<cl::Platform> platforms;
    cl::Platform::get(&platforms);
    if (platforms.empty())
    {
        std::cout << "No OpenCL platform found." << std::endl;
        return 0;
    }
    for (int i = 0; i < platforms.size(); i++)
    {
        const cl::Platform& onePlatform = platforms[i];
        std::cout << "Platform " << i << std::endl;
        std::cout << "===============================================================" << std::endl;
        PRINT_PLATFORM_INFO(onePlatform, CL_PLATFORM_PROFILE);
        PRINT_PLATFORM_INFO(onePlatform, CL_PLATFORM_VERSION);
        PRINT_PLATFORM_INFO(onePlatform, CL_PLATFORM_NAME);
        PRINT_PLATFORM_INFO(onePlatform, CL_PLATFORM_VENDOR);
        PRINT_PLATFORM_INFO(onePlatform, CL_PLATFORM_EXTENSIONS);

        std::vector<cl::Device> devices;
        onePlatform.getDevices(CL_DEVICE_TYPE_ALL, &devices);
        if (devices.empty())
        {
            std::cout << "No OpenCL devices found." << std::endl;
            continue;
        }
        for (int j = 0; j < devices.size(); j++)
        {
            const cl::Device& device = devices[j];
            std::cout << "---------------------------------------------------------------" << std::endl;
            std::cout << "\tDevice " << j << std::endl;
            std::cout << "---------------------------------------------------------------" << std::endl;
            PRINT_DEVICE_INFO(device, CL_DEVICE_NAME);
            PRINT_DEVICE_INFO(device, CL_DEVICE_VENDOR);
            PRINT_DEVICE_INFO(device, CL_DEVICE_VENDOR_ID);
            PRINT_DEVICE_INFO(device, CL_DEVICE_VERSION);
            PRINT_DEVICE_INFO(device, CL_DRIVER_VERSION);
            PRINT_DEVICE_INFO(device, CL_DEVICE_TYPE);
            PRINT_DEVICE_INFO(device, CL_DEVICE_PROFILE);
            //PRINT_DEVICE_INFO(device, CL_DEVICE_PLATFORM);
            PRINT_DEVICE_INFO(device, CL_DEVICE_PROFILING_TIMER_RESOLUTION);
            PRINT_DEVICE_INFO(device, CL_DEVICE_ADDRESS_BITS);
            PRINT_DEVICE_INFO(device, CL_DEVICE_AVAILABLE);
            PRINT_DEVICE_INFO(device, CL_DEVICE_COMPILER_AVAILABLE);
            PRINT_DEVICE_INFO(device, CL_DEVICE_DOUBLE_FP_CONFIG);
            PRINT_DEVICE_INFO(device, CL_DEVICE_ENDIAN_LITTLE);
            PRINT_DEVICE_INFO(device, CL_DEVICE_ERROR_CORRECTION_SUPPORT);
            PRINT_DEVICE_INFO(device, CL_DEVICE_EXECUTION_CAPABILITIES);
            PRINT_DEVICE_INFO(device, CL_DEVICE_GLOBAL_MEM_CACHE_SIZE);
            PRINT_DEVICE_INFO(device, CL_DEVICE_GLOBAL_MEM_CACHE_TYPE);
            PRINT_DEVICE_INFO(device, CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE);
            PRINT_DEVICE_INFO(device, CL_DEVICE_GLOBAL_MEM_SIZE);
            //PRINT_DEVICE_INFO(device, CL_DEVICE_HALF_FP_CONFIG);
            PRINT_DEVICE_INFO(device, CL_DEVICE_IMAGE_SUPPORT);
            PRINT_DEVICE_INFO(device, CL_DEVICE_IMAGE2D_MAX_HEIGHT);
            PRINT_DEVICE_INFO(device, CL_DEVICE_IMAGE2D_MAX_WIDTH);
            PRINT_DEVICE_INFO(device, CL_DEVICE_IMAGE3D_MAX_DEPTH);
            PRINT_DEVICE_INFO(device, CL_DEVICE_IMAGE3D_MAX_HEIGHT);
            PRINT_DEVICE_INFO(device, CL_DEVICE_IMAGE3D_MAX_WIDTH);
            PRINT_DEVICE_INFO(device, CL_DEVICE_LOCAL_MEM_SIZE);
            PRINT_DEVICE_INFO(device, CL_DEVICE_LOCAL_MEM_TYPE);
            PRINT_DEVICE_INFO(device, CL_DEVICE_MAX_CLOCK_FREQUENCY);
            PRINT_DEVICE_INFO(device, CL_DEVICE_MAX_COMPUTE_UNITS);
            PRINT_DEVICE_INFO(device, CL_DEVICE_MAX_CONSTANT_ARGS);
            PRINT_DEVICE_INFO(device, CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE);
            PRINT_DEVICE_INFO(device, CL_DEVICE_MAX_MEM_ALLOC_SIZE);
            PRINT_DEVICE_INFO(device, CL_DEVICE_MAX_PARAMETER_SIZE);
            PRINT_DEVICE_INFO(device, CL_DEVICE_MAX_READ_IMAGE_ARGS);
            PRINT_DEVICE_INFO(device, CL_DEVICE_MAX_SAMPLERS);
            PRINT_DEVICE_INFO(device, CL_DEVICE_MAX_WORK_GROUP_SIZE);
            PRINT_DEVICE_INFO(device, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS);
            PRINT_DEVICE_INFO_SIZE_T_ARRAY(device, CL_DEVICE_MAX_WORK_ITEM_SIZES);
            PRINT_DEVICE_INFO(device, CL_DEVICE_MAX_WRITE_IMAGE_ARGS);
            PRINT_DEVICE_INFO(device, CL_DEVICE_MEM_BASE_ADDR_ALIGN);
            PRINT_DEVICE_INFO(device, CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE);
            PRINT_DEVICE_INFO(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR);
            PRINT_DEVICE_INFO(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT);
            PRINT_DEVICE_INFO(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT);
            PRINT_DEVICE_INFO(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_LONG);
            PRINT_DEVICE_INFO(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT);
            PRINT_DEVICE_INFO(device, CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE);
            PRINT_DEVICE_INFO(device, CL_DEVICE_QUEUE_PROPERTIES);
            PRINT_DEVICE_INFO(device, CL_DEVICE_SINGLE_FP_CONFIG);
            PRINT_DEVICE_INFO(device, CL_DEVICE_EXTENSIONS);
            std::cout << "---------------------------------------------------------------" << std::endl;
        }

        std::cout << "===============================================================" << std::endl;
        std::cout << std::endl;
    }
    system("pause");
    return 0;
}

以上代码在Visual Studio 2017、vcpkg+OpenCL1.21环境中编译通过。

可执行文件

如果你不想自己编译软件,可以在这里下载我编译好的可执行程序,下载地址:OpenCLMonitor.rar

使用方法

解压下载到的压缩包后双击OpenCLMonitor.exe运行,运行效果如下图所示:


捕获.PNG


芸芸小站首发,阅读原文:


最后编辑:2022年05月04日 ©版权所有,转载须保留原文链接

发表评论

正在加载 Emoji