【问题标题】:How can I change the device on which OpenCL-code will be executed with Umat in OpenCV?如何更改将在 OpenCV 中使用 Umat 执行 OpenCL 代码的设备?
【发布时间】:2016-01-29 18:50:08
【问题描述】:

众所周知,OpenCV 3.0 支持新类 cv::Umat,它提供透明 API (TAPI) 以自动使用 OpenCL:http://code.opencv.org/projects/opencv/wiki/Opencv3#tapi

cv::Umat和TAPI有两个介绍:

但如果我有:

  1. Intel CPU Core i5 (Haswell) 4xCores (OpenCL Intel CPUs with SSE 4.1, SSE 4.2 or AVX support)
  2. 英特尔集成高清显卡supports OpenCL 1.2
  3. 第一个 nVidia GPU GeForce GTX 970 (Maxwell) supports OpenCL 1.2 和 CUDA
  4. 第二个 nVidia GPU GeForce GTX 970 ...

如果我在 OpenCV 中打开 OpenCL,那么如何更改将执行 OpenCL 代码的设备:8 核 CPU、集成高清显卡、第一个 nVidia GPU 或第二个 nVidia GPU?

我如何选择这 4 种设备中的任何一种来使用 OpenCL 以通过 cv::Umat 进行并行执行算法?

例如,我如何在 4xCores 的 CPU Core-i5 和 cv::Umat 上使用 OpenCL 加速?

【问题讨论】:

  • docs.opencv.org/modules/ocl/doc/introduction.html "用户也可以使用 cv::ocl::setDevice 函数(带有 cv::ocl::getOpenCLPlatforms 和 cv::ocl::getOpenCLDevices)。这个函数初始化 OpenCL 运行时和将传递的设备设置为计算设备。”
  • @DarkZeros 谢谢!是的,它可能适用于 OpenCV 2.4.12,但 cv::ocl::setDevice 不在出现 cv:Umat 的 OpenCV 3.0 中。有命名空间ocldocs.opencv.org/master/d5/d96/namespacecv_1_1ocl.html#gsc.tab=0 也有class Deviceenum-s TYPE_VENDOR_docs.opencv.org/master/d7/d9f/… 和函数attachContext()/initializeContextFromHandle()。但是没有设置全局变量以使用所需的Device 的功能。如何在 OpenCV3.0 中为整个程序、此线程或此 cv::Umat 设置 Device

标签: opencv image-processing opencl x86-64 opencv3.0


【解决方案1】:

我使用类似的东西来检查用于 OpenCL 支持的版本和硬件。

ocl::setUseOpenCL(true);
if (!ocl::haveOpenCL())
{
    cout << "OpenCL is not available..." << endl;
    //return;
}

cv::ocl::Context context;
if (!context.create(cv::ocl::Device::TYPE_GPU))
{
    cout << "Failed creating the context..." << endl;
    //return;
}

cout << context.ndevices() << " GPU devices are detected." << endl; //This bit provides an overview of the OpenCL devices you have in your computer
for (int i = 0; i < context.ndevices(); i++)
{
    cv::ocl::Device device = context.device(i);
    cout << "name:              " << device.name() << endl;
    cout << "available:         " << device.available() << endl;
    cout << "imageSupport:      " << device.imageSupport() << endl;
    cout << "OpenCL_C_Version:  " << device.OpenCL_C_Version() << endl;
    cout << endl;
}

然后你可以设置你喜欢使用的硬件,使用这个

cv::ocl::Device(context.device(1));

希望对你有所帮助。

【讨论】:

  • 谢谢!这就是我一直在寻找的。 cv::ocl::Device(context.device(1)); - 它对整个程序有影响,还是只影响 OpenCV2.4 中的 gpu::setDevice(i) 的当前线程? IE。在循环for (int i = 0; i &lt; context.ndevices(); i++) { cv::ocl::Device device = context.device(i); } 中,我可以将每个device.vendorID()enum { UNKNOWN_VENDOR =0, VENDOR_AMD =1, VENDOR_INTEL =2, VENDOR_NVIDIA =3 } 进行比较,只找到需要的,然后通过device.vendorName() 将其名称命名为cv::String。并为每个线程使用cv::ocl::Device(context.device(i));
  • 我设置了 cv::ocl::Device(context.device(1)) 因为我有支持 OpenCL1.1 的 Nvidia GT520M,但我的集成 Intel HD Graphics 3000 不支持 OpenCL。是的,它对整个程序都有影响,因为您必须将其设置为您首选的显卡才能用于 OpenCL。
  • 即所以我不能使用来自其他 CPU 线程的 2 个 nVidia GPU?或者我可以以某种方式只为当前的 CPU 线程设置 OCL 上下文,而不像在 CUDA 中那样影响其他 CPU 线程?
  • 嗯...我不确定您使用的是哪种线程技术。您可以尝试在不同的线程中调用 2 个 GPU,看看它是否有效。我猜你每次想要更改对不同 GPU 的访问时都必须更改代码中 GPU 的上下文。我通常使用 Qt 线程或增强线程,因为我可以等待线程完成其工作并将其与主线程。不太确定这个想法。但让我知道它是否有效。
  • 我可以强制一个算法在 CPU 上运行,另一个在 GPU 上运行吗?
【解决方案2】:

您还可以使用环境变量方法在代码中设置所需的 OpenCL 设备,如下所示(示例是第一个 GPU 设备):

if (putenv("OPENCV_OPENCL_DEVICE=:GPU:0") != 0 || !cv::ocl::useOpenCL())
{
    std::cerr << "Failed to set a desired OpenCL device" << std::endl;
    std::cerr << "Press any key to exit..." << std::endl;
    getchar();
    return 1;
}

调用 cv::ocl::useOpenCL() 将强制 OpenCV 将默认 OpenCL 设备设置为在该调用之前设置的环境变量 OPENCV_OPENCL_DEVICE 中指定的设备。

我通过在 opencv_core310d.dll!cv::ocl::selectOpenCLDevice() 第 2256 行 (opencv\source\modules\core\src\ocl.cpp) 设置断点来检查这是否真的发生:

static cl_device_id selectOpenCLDevice()
{
    std::string platform, deviceName;
    std::vector<std::string> deviceTypes;

    const char* configuration = getenv("OPENCV_OPENCL_DEVICE");
    if (configuration &&
            (strcmp(configuration, "disabled") == 0 ||
             !parseOpenCLDeviceConfiguration(std::string(configuration), platform, deviceTypes, deviceName)
            ))
        return NULL;

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-11-22
    • 2016-03-04
    • 2015-11-12
    • 2020-02-14
    • 2013-12-19
    • 1970-01-01
    相关资源
    最近更新 更多