GraphicsMagick 的 OpenCL 开发记录(二十一)

<2022-04-13 Wed>

支持windows平台

支持windows平台需要做的:

  1. GraphicsMagick/VisualMagick/configure/configure.exe增加“Enable OpenCL”多选框。
    在这里插入图片描述
  2. 从“VisualMagick”拷贝OpenCL/CL头文件。
  3. vs报错:error C2004: expected 'defined(id)',因为它不支持这样的语法:
#if defined(/*MAGICKCORE_OPENMP_SUPPORT*/HAVE_OPENMP)
  1. 一些函数的MagickExport得去掉,因为重定义。
  2. MAGICKCORE_WINDOWS_SUPPORT替换为MSWINDOWS

修改量较大,所有修改见commitbuild ok with opencl on Windows

<2022-04-14 周四>

windows平台不能生成内核的.bin文件

问题出在CacheOpenCLKernel()函数中:

static void CacheOpenCLKernel(MagickCLDevice device,char *filename,
  ExceptionInfo *exception)
{
  cl_uint
    status;

  size_t
    binaryProgramSize;

  unsigned char
    *binaryProgram;

  status=openCL_library->clGetProgramInfo(device->program,
    CL_PROGRAM_BINARY_SIZES,sizeof(size_t),&binaryProgramSize,NULL);
  if (status != CL_SUCCESS)
    return;
  binaryProgram=(unsigned char*) AcquireQuantumMemory(1,binaryProgramSize);
  if (binaryProgram == (unsigned char *) NULL)
    {
      (void) ThrowException(exception,
        ResourceLimitError,MemoryAllocationFailed,"CacheOpenCLKernel");
      return;
    }
  status=openCL_library->clGetProgramInfo(device->program,
    CL_PROGRAM_BINARIES,sizeof(unsigned char*),&binaryProgram,NULL);
  if (status == CL_SUCCESS)
    {
      (void) LogMagickEvent(AccelerateEvent,GetMagickModule(),
        "Creating cache file: \"%s\"",filename);
      (void) BlobToFile(filename,binaryProgram,binaryProgramSize,exception);
    }
  binaryProgram=(unsigned char *) RelinquishMagickMemory(binaryProgram);
}

因为clGetProgramInfo()的返回值是-30对应CL_INVALID_VALUE错误,修改之后可以临时解决:

static void CacheOpenCLKernel(MagickCLDevice device, char* filename,
  ExceptionInfo* exception)
{
  cl_uint
    status;

  size_t
    * binaryProgramSize,
    num_binaries;

  unsigned char
    ** binaryProgram;

  status = openCL_library->clGetProgramInfo(device->program, CL_PROGRAM_BINARY_SIZES,
    0, 0, &num_binaries);
  if (status != CL_SUCCESS)
    return;
  num_binaries = num_binaries / sizeof(size_t);
  binaryProgramSize = (size_t*)malloc(num_binaries * sizeof(size_t));
  binaryProgram = (const unsigned char**)calloc(num_binaries, sizeof(unsigned char*));
  status = openCL_library->clGetProgramInfo(device->program,
    CL_PROGRAM_BINARY_SIZES, num_binaries * sizeof(size_t), binaryProgramSize, NULL);
  LogMagickEvent(AccelerateEvent, GetMagickModule(), "clGetProgramInfo return: %d", status);
  if (status != CL_SUCCESS)
    return;
  for (int i = 0; i < num_binaries; ++i) {
    if (binaryProgramSize[i]) {
      binaryProgram[i] = (unsigned char*)AcquireQuantumMemory(1, binaryProgramSize[i]);
      if (binaryProgram[i] == (unsigned char*)NULL)
      {
        (void)ThrowException(exception,
          ResourceLimitError, MemoryAllocationFailed, "CacheOpenCLKernel");
        return;
      }
      status = openCL_library->clGetProgramInfo(device->program,
        CL_PROGRAM_BINARIES, num_binaries * sizeof(unsigned char*), binaryProgram, NULL);
      if (status == CL_SUCCESS)
      {
        (void)LogMagickEvent(AccelerateEvent, GetMagickModule(),
          "Creating cache file: \"%s\"", filename);
        (void)BlobToFile(filename, binaryProgram[i], binaryProgramSize[i], exception);
      }
      binaryProgram = (unsigned char*)RelinquishMagickMemory(binaryProgram);
    }
  }
}

_aligned_free()free()不匹配的问题

windows平台下这个问题出现了,之前相同代码在linux上运行的很好。

经调查发现是因为在DestroyMagickCLCacheInfoAndPixels()函数中使用的是:

MagickFreeAlignedMemory(pixels);

来清除在pixel_cache.c:OpenCache()中由:

MagickReallocMemory(PixelPacket *,cache_info->pixels,(size_t) offset);

申请的内存,造成不匹配。

因此DestroyMagickCLCacheInfoAndPixels()中改为MagickFreeMemory()来释放内存。这里的做法不同于ImageMagick,在GraphicsMagick中未使用对齐的内存,就像pixel_cache.c:DestroyCacheInfo()那样释放内存一样,才不会出问题。

  /*
    Release Cache Pixel Resources
  */
  if (MemoryCache == cache_info->type)
    {
#if defined(HAVE_OPENCL)
      if (cache_info->opencl != (MagickCLCacheInfo) NULL)
        {
          cache_info->opencl=RelinquishMagickCLCacheInfo(cache_info->opencl,
            MagickTrue);
          cache_info->pixels=(Quantum *) NULL;
        }
#else
      MagickFreeMemory(cache_info->pixels);
      LiberateMagickResource(MemoryResource,cache_info->length);
#endif
    }

OpenCL中不使用对齐内存对性能影响很大,这可以作为一个性能优化点。

此外MAGICKCORE_HAVE__ALIGNED_MALLOC宏应该被替换为HAVE__ALIGNED_MALLOC

  • 10
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值