zoukankan      html  css  js  c++  java
  • 第六章 程序与内核

    程序对象和内核对于使用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);
    

      

  • 相关阅读:
    P3332 [ZJOI2013]K大数查询
    树上最短路---------------树链剖分,优化建边。
    BZOJ_4386
    2016_1_13(3)
    2016_1_13(2)
    2016_1_13
    BZOJ_1698
    BZOJ_4152
    BZOJ_3110
    BZOJ_2141
  • 原文地址:https://www.cnblogs.com/tcsong24/p/7649860.html
Copyright © 2011-2022 走看看