Не могу использовать графический процессор в Magick ++ после включения OpenCL - PullRequest
0 голосов
/ 29 июня 2018

Я хотел использовать GPU в функциях Magick ++ моего проекта. Я построил ImageMagick, используя этот учебник (OpenCL включен). Файл 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. Но это не так. Он использует только процессор. Кроме того, 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

Кроме того, мой графический процессор поддерживает OpenCL.

1 Ответ

0 голосов
/ 29 июня 2018

Обновленный ответ

Если настройка MAGICK_OCL_DEVICE не имеет никакого эффекта и / или EnableOpenCl возвращает false, то ядра OpenCL не могут быть загружены на целевую платформу / устройство. Поведение ImageMagick - DelegateWarning (не ошибка) и возврат к процессору.

Я подозреваю, что это так, и причины , почему записываются в файл с именем magick_badcl_build.log, а фактический код OpenCL, который не удался, записывается в magick_badcl.cl. Оба файла должны быть опубликованы на форумах для разработчиков для ознакомления.

Кроме того, переменная окружения должна быть 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 для управления управлением устройством OpenCL, а не EnableOpenCl (который автоматически выберет лучшее устройство, а лучшим устройством обычно является процессор).

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 процессор всегда будет выбран из пула устройств. Если я предпочитаю использовать GPU напрямую, я могу определить это во время выполнения с помощью переменных среды.

 MAGICK_OCL_DEVICE=GPU ./my_opencl_enabled_magick_application
...