5

我无法将向量类型 (uint8) 参数从 C 中的主机代码传递给 OpenCL 内核函数。

在主机中,我有一个数组中的数据:

cl_uint dataArr[8] = { 1, 2, 3, 4, 5, 6, 7, 8 };

(我的真实数据不仅仅是 [1, 8];这只是为了便于解释。)

然后我将数据传输到缓冲区以传递给内核:

cl_mem kernelInputData = clCreateBuffer(context,
    CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(cl_uint)*8, dataArr, NULL);

接下来,我将此缓冲区传递给内核:

clSetKernelArg(kernel, 0, sizeof(cl_mem), &kernelInputData);

内核函数的签名看起来像这样:

kernel void kernelFunction(constant uint8 *vectorPtr)

但是,内核似乎没有从指向kernelInputData. 当我从内核中传回值时,我看到它vectorPtr指向具有这种结构的东西:( 1, 2, 3, 4, 5, ?, ?, ? )问号通常 4293848814在哪里,但有时是0. 无论哪种方式,都不是他们应该的样子。

我究竟做错了什么?


编辑:

我已经从使用数组切换到主机端的 cl_uint8 。我现在有:

cl_uint8 dataVector = { 1, 2, 3, 4, 5, 6, 7, 8 };

我将这个向量传递给内核,如下所示:

clSetKernelArg(kernel, 0, sizeof(cl_uint8), &dataVector);

内核函数的签名看起来像这样:

kernel void kernelFunction(constant uint8 *vectorPtr)

但是,运行此代码会给我一个CL_INVALID_ARG_SIZE错误clSetKernelArg()ARG_SIZE如果我将参数切换为,则此错误消失,sizeof(cl_uint8 *)但随后我EXC_BAD_ACCESS__dynamic_cast.clSetKernelArg()

我的设备是:

Apple Macbook Pro(2009 年中)
OSX 10.8 Mountain Lion
NVIDIA GeForce 9400M
OpenCL 1.0
CLH 1.0

4

2 回答 2

8

您正在定义一个大小为 8 的 cl_uint 数组。 cl_mem 的创建和内核参数的设置是正确的。但是您的内核参数不正确:您尝试读取 cl_uint8 数组而不是 cl_uint。

如果要使用向量数据类型,则必须声明: cl_uint8 dataArr of size 1。或者如果要使用大小为 8 的数组:kernel void kernelFunction(constant uint *vectorPtr, uint size):

编辑:

内核参数cl_uint8 dataVector不是指针。所以,正确的代码是:

cl_uint8 dataVector = { 1, 2, 3, 4, 5, 6, 7, 8 };
clSetKernelArg(kernel, 0, sizeof(cl_uint8), &dataVector);

kernel void kernelFunction(constant uint8 vectorPtr)
于 2012-10-29T08:58:25.780 回答
1

最小可运行示例

int2传递给内核。它最初是作为一个数组创建的cl_int

#include <assert.h>
#include <stdlib.h>

#include <CL/cl.h>

int main(void) {
    const char *source =
        "__kernel void main(__global int2 *out) {\n"
        "      out[get_global_id(0)]++;\n"
        "}\n";
    cl_command_queue command_queue;
    cl_context context;
    cl_device_id device;
    cl_int input[] = {0, 1, 2, 3};
    const size_t global_work_size = sizeof(input) / sizeof(cl_int2);
    cl_kernel kernel;
    cl_mem buffer;
    cl_platform_id platform;
    cl_program program;

    clGetPlatformIDs(1, &platform, NULL);
    clGetDeviceIDs(platform, CL_DEVICE_TYPE_ALL, 1, &device, NULL);
    context = clCreateContext(NULL, 1, &device, NULL, NULL, NULL);
    command_queue = clCreateCommandQueue(context, device, 0, NULL);
    buffer = clCreateBuffer(context, CL_MEM_READ_WRITE | CL_MEM_COPY_HOST_PTR, sizeof(input), &input, NULL);
    program = clCreateProgramWithSource(context, 1, &source, NULL, NULL);
    clBuildProgram(program, 1, &device, "", NULL, NULL);
    kernel = clCreateKernel(program, "main", NULL);
    clSetKernelArg(kernel, 0, sizeof(cl_mem), &buffer);
    clEnqueueNDRangeKernel(command_queue, kernel, 1, NULL, &global_work_size, NULL, 0, NULL, NULL);
    clFlush(command_queue);
    clFinish(command_queue);
    clEnqueueReadBuffer(command_queue, buffer, CL_TRUE, 0, sizeof(input), &input, 0, NULL, NULL);

    assert(input[0] == 1);
    assert(input[1] == 2);
    assert(input[2] == 3);
    assert(input[3] == 4);
    return EXIT_SUCCESS;
}

在 Ubuntu 15.10 OpenCL 1.2 NVIDIA 352.53 上测试。

于 2016-03-30T21:44:30.987 回答