我想在我的项目的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。
答案 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