概述
程序对象和内核对于使用OpenCL至关重要,本章包括以下内容:
- 程序和内核对象概述
- 创建程序对象,构建程序
- 程序构建选项
- 创建内核对象,设置内核参数
- 源代码和二进制程序创建
- 查询内核和程序对象
6.1 程序和内核对象概述
OpenCL应用将设备上并行执行的函数表述为内核。内核用OpenCL C语言编写,由_kernel限定符指示。为了向内核函数传递参数,应用必须创建一个内核对象。内核对象可以使用API函数处理,允许设置内核参数以及查询内核信息。
内核对象由程序对象创建。程序对象包含程序源代码中定义的内核函数集合。程序对象的主要作用之一是便于为程序关联的设备编译内核。另外,程序对象还有利于确定构建错误和查询程序信息。
程序对象就像是一个动态库,其中包含一组内核函数。内核对象则像是这个动态库中函数的句柄。程序对象可以由源代码(OpenCL C)或编译的程序二进制码创建。可以为程序对象关联的设备构建程序。然后使用内核对象访问已编译内核函数的属性,内核函数调用排队,并设置其参数。
6.2 程序对象
OpenCL中使用内核和程序对象的第一步是创建和构建一个程序对象。
6.2.1 创建和构建程序
要创建程序对象,可以传入OpenCL C源代码文本,或者利用程序二进制码来创建。应用程序将使用clCreateProgramWithSource()函数由源代码创建程序对象,另一种做法是由为设备预编译的二进制码创建程序对象。
cl_program clCreateProgramWithSource(cl_context context,
cl_uint count,
const char** strings,
const size_t* lengths,
cl_int* errcode_ret)
//strings包含count个字符串的指针。将这个参数中包含的所有字符串结合在一起,就构成了创建程序对象的完整的源代码
//lengths这是一个大小为count的数组,包含strings中各个元素的字符数。这个参数可以为NULL,在这种情况下则认为字符串是以null终止的。
调用clCreateProgramWithSource()会使用传入的源代码创建一个新的程序对象。返回值是与上下文关联的一个新程序对象。一般地,调用clCreateProgramWithSource()之后,下一步就是使用clBuildProgram()构建这个程序对象:
cl_int clBuildProgram(cl_program program,
cl_uint num_devices,
const cl_device_id* device_list,
const char* options,
void(CL_CALLBACK* pfn_notify)(cl_program program, void*
user_data),
void* user_data)
调用clBuildProgram()会为指定的所有设备构建程序对象。
6.2.4 管理和查询程序
使用一个程序后要将它清楚,可以通过调用clReleaseProgram()来删除程序。在内部,OpenCL会为每个程序对象存储一个引用计数。OpenCL中创建对象的函数返回对象时,其引用计数为1。调用clReleaseProgram()将使这个引用计数递减。如果引用计数达到0,则程序被删除。
cl_int clReleaseProgram(cl_program program)
如果用户希望手动增加OpenCL程序的引用计数,可以使用clRetainProgram()
cl_int clRetainProgram(cl_program program)
6.3 内核对象
程序对象是一个容器,存储与之关联的各个设备上各个内核的已编译的可执行代码。为了具体执行一个内核,必须能够向内核函数传递参数。这是内核对象的主要作用。内核对象是一些容器,可以用来向程序对象中包含的内核函数传递参数。内核对象还可以用来查询关于各个内核函数的信息。
6.3.1 创建内核对象和设置内核参数
创建内核对象的方法是将内核函数名传入clCreateKernel():
cl_kernel clCreateKernel(cl_program program,
const char* kernel_name,
cl_int* errcode_ret)
一旦创建,可以通过调用clSetKernelArg()将参数传入内核对象中包含的内核函数:
cl_int clSetKernelArg(cl_kernel kernel,
cl_uint arg_index,
size_t* arg_size,
const void* arg_value)
调用clSetKernelArg()时,传入的指针(包含参数值)由OpenCL是现在内部复制。这说明调用该函数后,完全可以将这个指针用作其他用途。传入内核的参数类型取决于内黑如何声明。
使用clCreateKernel()可以一次为一个内核函数创建内核对象,除此之外还有一种方法,可以使用clCreateKernelsInProgram()为程序中的所有内核函数创建对象:
cl_int clCreateKernelsInProgram(cl_program program,
cl_uint num_kernels,
cl_kernel* kernels,
cl_uint* num_kernels_ret)
使用该函数时需要调用这个函数两次:第一次确定程序中的内核数;第二次具体创建内核对象。
cl_int numKernels;
errNum = clCreateKernelsInProgram(program, NULL, NULL, &numKernels);
cl_kernel* kernels = new cl_kernel[numKernels];
errNum = clCreateKernelsInProgram(program, numKernels, kernels, &numKernels);
转载于:https://www.cnblogs.com/tcsong24/p/7649860.html
最后
以上就是幽默蜗牛为你收集整理的第六章 程序与内核的全部内容,希望文章能够帮你解决第六章 程序与内核所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复