启用OpenCL后无法在Magick ++中使用GPU

时间:2018-06-29 12:38:33

标签: image-processing imagemagick magick++

我想在我的项目的Magick ++函数中使用GPU。我已经使用this教程(已启用OpenCL)构建了ImageMagick。生成后的convert.exe文件说已启用OpenCL。我已经包含了必要的标头和库(CORE_RL_Magick ++ _。lib,CORE_RL_MagickCore_.lib,CORE_RL_MagickWand_.lib)。我还设置了IMAGEMAGICK_OPENCL_CACHE_DIR系统变量和路径(用于存储必要的文件)。我正在使用Windows和Visual Studio。
这是我的代码:

...
#include <Magick++.h>
#include <MagickCore/MagickCore.h>
#include <MagickWand/MagickWand.h>
#include <MagickCore\accelerate-private.h>
...

using namespace Magick;

int main(int argc, char *argv[])
{
    EnableOpenCL();
    InitializeMagick(NULL);
    EnableOpenCL(); // Executed this after InitializeMagick too to be sure. Maybe it's needed to be executed after InitializeMagick().

    Image img;
    img.read("F:/tmp/test/22/7.png");

    // These two functions should use GPU. But they don't. :
    img.gaussianBlur(15, 3);
    img.edge();
}

代码没有错误,但是如您所见,我的代码具有ImageMagick可以在其中使用GPU的功能。但事实并非如此。它仅使用CPU。另外,ImageMagick在IMAGEMAGICK_OPENCL_CACHE_DIR设置的路径中不会生成任何文件。
哪一部分错了?

修改:

C:\Users\User1>convert -version
Version: ImageMagick 7.0.8-4 Q16 x64 2018-06-29 http://www.imagemagick.org
Copyright: Copyright (C) 1999-2018 ImageMagick Studio LLC
License: http://www.imagemagick.org/script/license.php
Visual C++: 190024210
Features: Cipher DPC HDRI Modules OpenCL OpenMP
Delegates (built-in): bzlib cairo flif freetype gslib heic jng jp2 jpeg lcms lqr lzma openexr pangocairo png ps raw rsvg tiff webp xml zlib

此外,我的GPU支持OpenCL。

1 个答案:

答案 0 :(得分:1)

更新后的答案

如果设置MAGICK_OCL_DEVICE无效,和/或EnableOpenCl返回false,则无法将OpenCL内核加载到目标平台/设备中。 ImageMagick的行为是发出DelegateWarning(不是错误),然后故障回复到CPU。

我怀疑是这种情况,并且原因为什么被记录到名为magick_badcl_build.log的文件中,并且失败的实际OpenCL代码已写入magick_badcl.cl。这两个文件都应发布到developer forums上进行审核。

此外,环境变量应为MAGICK_OPENCL_CACHE_DIR,而不是IMAGEMAGICK_OPENCL_CACHE_DIR。我认为文档是错误的。

  

从opencl.c

     
 home=GetEnvironmentValue("MAGICK_OPENCL_CACHE_DIR");
 if (home == (char *) NULL)
 {
   home=GetEnvironmentValue("XDG_CACHE_HOME");
   if (home == (char *) NULL)
     home=GetEnvironmentValue("LOCALAPPDATA");
   if (home == (char *) NULL)
     home=GetEnvironmentValue("APPDATA");
   if (home == (char *) NULL)
     home=GetEnvironmentValue("USERPROFILE");
 }

原始答案

使用方法InitImageMagickOpenCL而不是EnableOpenCl来控制OpenCL设备管理(它将自动选择最佳设备,并且最佳设备通常是CPU)。

cl_uint platformCount;
cl_platform_id platforms[4];
cl_uint deviceCount;
cl_device_id devices[8];
cl_device_id * user_selected_GPU = nullptr;
clGetPlatformIDs(4, platforms, &platformCount);
// Grap the first GPU off the first platform.
// !!! Check docs as this is a _very_ bad example. !!!
if (platformCount > 0) {
    clGetDeviceIDs(platforms[0], CL_DEVICE_TYPE_GPU, 8, devices, &deviceCount);
    if (deviceCount > 0) {
        user_selected_GPU = devices[0];
    }
}
if (user_selected_GPU) {
    MagickCore::ExceptionInfo * exception = MagickCore::AcquireExceptionInfo();
    MagickCore::InitImageMagickOpenCL(
          MagickCore::MAGICK_OPENCL_DEVICE_SELECT_USER,
          user_selected_GPU,
          nullptr,
          exception
    );
} else {
    // No GPU found... 
}

通常,您无需费心定义要在哪个设备上运行,因为ImageMagick将获取系统和环境信息。例如,在我的Mac上,将始终从设备池中选择CPU。如果我想直接使用GPU,则可以在运行时使用环境变量进行定义。

 MAGICK_OCL_DEVICE=GPU ./my_opencl_enabled_magick_application