【发布时间】:2015-12-30 04:50:50
【问题描述】:
我正在尝试在 Mac 上学习 OpenCL,这似乎与我正在阅读的 OpenCL 书在实现上有一些差异。我希望能够在 GPU 上动态分配本地内存。我正在阅读的是我需要使用 clSetKernelArg 函数,但这在 Xcode 6.4 中不起作用。这是它的代码(别介意它是一个毫无意义的程序,只是试图学习共享内存的语法)。在 Xcode 中,内核被编写为类似于 CUDA 的独立 .cl 文件,因此这是一个单独的文件。
add.cl:
kernel void add(int a, int b, global int* c, local int* d)
{
d[0] = a;
d[1] = b;
*c = d[0] + d[1];
}
main.c:
#include <stdio.h>
#include <OpenCL/opencl.h>
#include "add.cl.h"
int main(int argc, const char * argv[]) {
int a = 3;
int b = 5;
int c;
int* cptr = &c;
dispatch_queue_t queue = gcl_create_dispatch_queue(CL_DEVICE_TYPE_GPU, NULL);
void* dev_c = gcl_malloc(sizeof(cl_int), NULL, CL_MEM_WRITE_ONLY);
// attempt to create local memory buffer
void* dev_d = gcl_malloc(2*sizeof(cl_int), NULL, CL_MEM_READ_WRITE);
// clSetKernelArg(add_kernel, 3, 2*sizeof(cl_int), NULL);
dispatch_sync(queue, ^{
cl_ndrange range = { 1, {0, 0, 0}, {1, 0, 0}, {1, 0, 0} };
// This gives a warning:
// Warning: Incompatible pointer to integer conversion passing 'cl_int *'
// (aka 'int *') to parameter of type 'size_t' (aka 'unsigned long')
add_kernel(&range, a, b, (cl_int*)dev_c, (cl_int*)dev_d);
gcl_memcpy((void*)cptr, dev_c, sizeof(cl_int));
});
printf("%d + %d = %d\n", a, b, c);
gcl_free(dev_c);
dispatch_release(queue);
return 0;
}
我尝试将clSetKernelArg 放在指定的位置,但它不喜欢第一个参数:
错误:将“void (^)(const cl_ndrange *, cl_int, cl_int, cl_int *, size_t)”传递给不兼容类型“cl_kernel”(又名“struct _cl_kernel *”)的参数
我看了又看,但在 Xcode 环境中找不到任何说明这一点的示例。你能指出我正确的方向吗?
【问题讨论】:
-
我应该澄清一下,add_kernel 调用中的警告指的是最后一个参数 (dev_d)。
-
add_kernel在哪里定义?我的猜测是在 add.cl.h 但你没有向我们展示。 .cl 文件也不是 Xcode 特定的,您可以使用任何编译器/IDE 来执行此操作。如果您愿意,您也可以内联编写 OpenCL 内核代码,就像在 Hello World Example 中所做的那样 -
add_kernel 由 Xcode cl 编译器定义。代码在 add.cl 中,编译器通过附加“_kernel”来创建 add_kernel 函数。