Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/68.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
如何在C中向OpenCL内核传递向量参数?_C_Vector_Parameter Passing_Opencl - Fatal编程技术网

如何在C中向OpenCL内核传递向量参数?

如何在C中向OpenCL内核传递向量参数?,c,vector,parameter-passing,opencl,C,Vector,Parameter Passing,Opencl,我在从C中的宿主代码向OpenCL内核函数传递向量类型(uint8)参数时遇到问题 在主机中,我将数据存储在一个数组中: 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_HO

我在从C中的宿主代码向OpenCL内核函数传递向量类型(uint8)参数时遇到问题

在主机中,我将数据存储在一个数组中:

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);
接下来,我将此缓冲区传递到内核:

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数据向量={1,2,3,4,5,6,7,8}

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

clSetKernelArg(内核,0,sizeof(cl_uint8),&dataVector)

内核函数的签名如下所示:

kernel void kernelFunction(constant uint8 *vectorPtr)
内核无效内核函数(常量uint8*vectorPtr)

但是,运行此代码会在
clSetKernelArg()
上出现
CL\u INVALID\u ARG\u SIZE
错误。如果我将
ARG\u SIZE
参数切换为
sizeof(cl\u uint8*)
,但随后在
clSetKernelArg()
内的
动态转换中出现
EXC\u BAD\u访问
错误,此错误就会消失

我的设备是:

苹果MacBookPro(2009年年中)
OSX 10.8美洲狮
英伟达GeForce 9400米
OpenCL1.0

CLH 1.0

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

如果要使用向量数据类型,必须声明:cl_uint8 dataArr,大小为1。 或者如果要使用大小为8的数组:
kernelvoid kernelFunction(常量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);


最小可运行示例

int2
被传递到内核。它最初创建为
cl\u 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;
}
#包括
#包括
#包括
内部主(空){
常量字符*源=
“uuu内核void main(uuu全局int2*out){\n”
“out[get_global_id(0)]++;\n”
“}\n”;
cl_命令_队列命令_队列;
语境;
cl_设备\u id设备;
cl_int输入[]={0,1,2,3};
const size\u t global\u work\u size=sizeof(input)/sizeof(cl\u int2);
cl_核;
cl_膜缓冲液;
cl_平台\u id平台;
CLU计划;
clGetPlatformIDs(1,&平台,NULL);
CLGetDeviceID(平台、CL_设备类型、全部、1和设备、空);
context=clCreateContext(NULL,1,&device,NULL,NULL,NULL);
command_queue=clCreateCommandQueue(上下文、设备、0、空);
buffer=clCreateBuffer(上下文,CL_MEM_READ_WRITE,CL_MEM_COPY_HOST_PTR,sizeof(输入),&input,NULL);
program=clCreateProgramWithSource(上下文,1,&source,NULL,NULL);
clBuildProgram(程序,1,&设备,”,NULL,NULL);
kernel=clCreateKernel(程序,“main”,NULL);
clSetKernelArg(内核,0,sizeof(cl_mem),&buffer);
clEnqueueNDRangeKernel(命令队列、内核、1、NULL和全局工作大小、NULL、0、NULL、NULL);
clFlush(命令队列);
clFinish(命令队列);
clenqueueredbuffer(命令队列,缓冲区,CL_TRUE,0,sizeof(输入),&input,0,NULL,NULL);
断言(输入[0]==1);
断言(输入[1]==2);
断言(输入[2]==3);
断言(输入[3]==4);
返回退出成功;
}

在Ubuntu 15.10 OpenCL 1.2 NVIDIA 352.53上测试。

啊,谢谢。我怀疑这是罪魁祸首,但我还没有找到在宿主代码中创建向量的任何示例。你知道怎么做吗?请参阅198页。我已经看过规格了。正如我所说,据我所知,没有从主机代码(如cl_uint8)创建向量并用值填充它的示例。cl_uint8数组;array.s[0]=0;array.s[1]=1;array.s[2]=2。。。或cl_uint8数组=(cl_uint8)(0,1,2,…);啊,不过没那么简单。我已经尝试了
(cl_uint8)(0,1,2,…)
构造,它在主机上不编译。您的另一个构造确实有效,正如前面提到的一样,但是当我使用
clSetKernelArg(kernel,0,sizeof(cl\u uint8),&testVector)
将这样一个构造的向量传递给内核时,我会得到一个EXC\u BAD\u访问错误。当clSetKernelArg的arg_size参数也是
sizeof(cl_mem)
sizeof(cl_uint*)
时,就会发生这种情况。我遗漏了什么?我不明白,你想传递一个向量还是一个向量数组?”kernel void kernelFunction(常量uint8*vectorPtr)“请删除*。
clSetKernelArg()
的最后一个参数的类型为
const void*
cl_uint8 dataVector={1,2,3,4,5,6,7,8}
clSetKernelArg(内核,0,sizeof(cl_uint8),&dataVector)
内核无效内核函数(常量uint8 vectorPtr)
Wow。我原以为所有的内核函数参数都必须是指针,但显然不是。你的代码运行得很好!编辑你的答案,我会标记为正确?