我遇到了一个非常奇怪的问题:
我的一个项目使用OpenCL,并在XCode中使用以下选项编译:
OPENCL_ARCHS : i386 x86_64 gpu_32 gpu_64
OPENCL_COMPILER_VERSION : CL1.2
然而,当我在10.8.5下运行它时,当我使用CL_DEVICE_TYPE_GPU时它会崩溃,当它在10.9.5时,它会在CL_DEVICE_TYPE_CPU上崩溃。但另一种方式是分别工作。
我所尝试的只是运行一个空的测试内核:
kernel void InitBlocks(global float* pointless) {
}
- (void)applicationDidFinishLaunching:(NSNotification *)notification {
gcdQueue = gcl_create_dispatch_queue(CL_DEVICE_TYPE_XPU, NULL);
cl_ndrange range = {
1,
{0, 0, 0},
{1, 0, 0},
{1, 0, 0}
};
dispatch_sync(gcdQueue, ^{
InitBlocks_kernel(&range, Nil);
});
}
无论何时我是否传递参数、稍后运行内核或实际在内部进行一些计算,这都无关紧要。它总是在调用中崩溃:
// Block function
void (^InitBlocks_kernel)(const cl_ndrange *ndrange, cl_float* unneccessary) =
^(const cl_ndrange *ndrange, cl_float* unneccessary) {
int err = 0;
cl_kernel k = bmap.map[0].kernel;
if (!k) {
initBlocks();
k = bmap.map[0].kernel;
}
if (!k)
gcl_log_fatal("kernel InitBlocks does not exist for device");
kargs_struct kargs;
gclCreateArgsAPPLE(k, &kargs);
err |= gclSetKernelArgMemAPPLE(k, 0, unneccessary, &kargs);
gcl_log_cl_fatal(err, "setting argument for InitBlocks failed");
err = gclExecKernelAPPLE(k, ndrange, &kargs);
gcl_log_cl_fatal(err, "Executing InitBlocks failed"); // <---- Here, err = -45
gclDeleteArgsAPPLE(k, &kargs);
};
我认为这意味着它无法加载特定目标设备/平台的机器代码。
但我知道它可以在CPU和GPU上运行,因为我用两个不同的Mac OS X版本(启动选项)在同一硬件上测试了这两个版本。每个版本只支持一个目标设备。我做错了什么?是我的源代码还是编译器选项?
希望我提供了足够的信息,有人对此有所了解。。。
这是预编译+自动Xcode集成的已知问题。不过,苹果似乎并不关心解决这个问题,他们自己的示例代码也会崩溃。解决方法是在运行时编译源代码。