如何同时向OpenCL内核传递数组与int参数且int无需经buffer传递
OpenCL混合传递数组与标量参数实现方案
OpenCL完全支持同时传入缓冲区数组和非缓冲区的int类型标量参数,不需要为单个int值创建cl_mem缓冲区,具体修改分为内核代码修正和主机端逻辑调整两部分。
1. 内核代码修正
你给出的预期内核代码存在一个错误:__global地址空间修饰符仅用于全局内存中的缓冲区指针对象,基础类型标量参数不能加该修饰符。内核入参的标量默认属于__private私有地址空间,直接声明类型即可,修正后的内核代码如下:
const char *opencl_code = "__kernel void opencl_code(__global const int *src,\n" " const int value,\n" " __global float *result) {\n" " int gid = get_global_id(0);\n" " result[gid] = src[gid] - value;\n" "}";
2. 主机端代码调整
删除原有为myint创建缓冲区的逻辑,调整内核参数设置规则:
- 数组类参数仍按原有方式创建cl_mem缓冲区,调用
clSetKernelArg时传入cl_mem对象的地址,参数大小指定为sizeof(cl_mem) - int标量参数不需要创建缓冲区,调用
clSetKernelArg时直接传入本地int变量的地址,参数大小指定为sizeof(int)即可
修正后的主机端核心代码如下:
int myint = 100; // 仅需创建2个缓冲区:输入数组src、输出结果数组result cl_mem memObjects[2] = {0, 0}; memObjects[0] = clCreateBuffer(opencl_context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, sizeof(int) * ARR_SIZE, data, NULL); memObjects[1] = clCreateBuffer(opencl_context, CL_MEM_READ_WRITE, sizeof(float) * ARR_SIZE, NULL, NULL); cl_int opencl_errNum = 0; // 参数0:输入数组缓冲区 opencl_errNum |= clSetKernelArg(opencl_kernel, 0, sizeof(cl_mem), &memObjects[0]); // 参数1:int标量myint,直接传值无需缓冲区 opencl_errNum |= clSetKernelArg(opencl_kernel, 1, sizeof(int), &myint); // 参数2:输出结果数组缓冲区 opencl_errNum |= clSetKernelArg(opencl_kernel, 2, sizeof(cl_mem), &memObjects[1]); // 后续按原有流程执行内核入队、结果读回、资源释放即可
补充说明:所有OpenCL基础标量类型(int、float、char、long等)、向量类型(int4、float8等)、自定义结构体类型都可以通过这种方式直接传值,不需要创建缓冲区。
内容的提问来源于stack exchange,提问作者LittleTin
相关产品推荐
相关产品推荐

