<2022-04-13 Wed>
支持windows平台
支持windows平台需要做的:
- 为
GraphicsMagick/VisualMagick/configure/configure.exe增加“Enable OpenCL”多选框。

- 从“VisualMagick”拷贝
OpenCL/CL头文件。 vs报错:error C2004: expected 'defined(id)',因为它不支持这样的语法:
#if defined(/*MAGICKCORE_OPENMP_SUPPORT*/HAVE_OPENMP)
- 一些函数的
MagickExport得去掉,因为重定义。 MAGICKCORE_WINDOWS_SUPPORT替换为MSWINDOWS。
修改量较大,所有修改见commit:build 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。
文章讲述了在支持Windows平台的GraphicsMagick/VisualMagick项目中遇到的问题,包括如何为OpenCL添加配置选项、解决内核缓存文件生成错误以及修复aligned_free与free的不匹配问题。作者提供了代码修改和性能优化建议。
457

被折叠的 条评论
为什么被折叠?



