OpenCL编程步骤(三):创建和编译程序

来源:互联网 发布:淘宝红包图片 编辑:程序博客网 时间:2024/04/30 14:21
OpenCL程序是由一组内核组成,而这些内核就是程序源码中以限定符__kernel声明的函数。__kernel函数可能会用到一些辅助函数以及常量数据,他们也是程序的一部分。

1、创建程序对象
cl_program clCreateProgramWithSource(cl_context context,
cl_uint count,
const char **strings,
const size_t *lengths,
cl_int *errcode_ret)
这个函数可以创建一个程序对象,并将strings中的源码装入到这个对象中。此程序对象关联的设备就是context所关联的设备。strings中的源码是OpenCL C程序源码、文档,或者是自定义的代码。
    context 是一个OpenCL上下文。
    strings 是一个字符串序列,有count个元素,字符串可选的以null结束。这些字符串就构成了源码。
    lengths 也是一个序列,其中的元素代表每个字符串中的字符个数(字符串的长度)。如果某个元素是零,则相应的字符串以null终止。如果lengths是NULL,则strings中的所有字符串都已null终止。所有大于零的值都不包括null终止符。
    errcode_ret会返回相应的错误码。如果为NULL,不返回错误码。

如果clCreateProgramWithSource成功创建了程序对象,则返回该对象,并将errcode_ret置为CL_SUCCESS。否则返回NULL,并将errcode_ret置为下面的错误码之一:
  • CL_INVALID_CONTEXT,context无效
  • CL_INVALID_VALUE,count是零,或者strings中任一项是NULL
  • CL_DEVICE_TYPE_DEFAULT:系统中默认的OpenCL设备。不能是CL_DEVICE_TYPE_CUSTOM类型的设备。
  • CL_DEVICE_TYPE_ALL:系统中所有的OpenCL设备。不包括CL_DEVICE_TYPE_CUSTOM类型的设备。
2、编译程序对象
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)
  • program  是程序对象。
  • device_list指向program所关联的设备。如果device_list是NULL,则会为program所关良的所有设备创建程序对象的执行体。否则,仅为此清单中的设备构建程序执行体。
  • num_devices即device_list中的设备数目。
  • options指向一个null终止的字符串,用来描述构建选项。
  • pfn_notify是应用所注册的回调函数。在构建完程序执行体后会被调用(不论成功还是失败)。如果pfn_notify不是NULL,一旦开始构建,clBuildProgram会立刻返回,而不必等待构建完成。如果上下文、所要编译连接的函数、设备清单以及构建选项都是有效的,以及实施构建所需的主机和设备资源都可用,那么就可以开始构建了。如果pfn_notify是NULL,直到构建完毕,clBuildProgram才会返回。对此函数的调用可能是异步的。应用需要保证此函数是线程安全的。
  • user_data在调用pfn_notify时作为参数传入,可以是NULL。
如果执行成功,则clBuildProgram会返回CL_SUCCESS。否则返回下列错误码之一:
  • CL_INVALID_PROGRAM,无效的program。
  • CL_INVALID_VALUE,device_list是NULL而num_devices大于零,或者device_list不是NULL而num_devices等于零。
  • CL_INVALID_VALUE,pfn_notity是NULL,而user_data不是NULL。
  • CL_INVALID_DEVICE,device_list中的OpenCL设备不是program所关联的设备
  • CL_INVALID_BINARY,program是用clCreateProgramWithBinary所创建的,但是没有为device_list中的设备装载相应的程序二进制妈。
  • CL_INVALID_BUILD_OPTIONS,options所制定的构建选项无效。
  • CL_INVALID_OPERATION,对于device_list中任一设备而言,之前调用clBuildProgram为program构建所对应的程序执行体的动作还未完成。
  • CL_COMPILER_AVAILABALE,如果是用clCreateProgramWithSource创建的program,但是没有可用的编译器,即CL_DEVICE_COMPILER_AVAILABLE是CL_FALSE
  • CL_BUILD_PROGRAM_FAILURE,构建程序对象失败。如果clBuildProgram没有将此错误返回,则在构建完成时会将其返回。
  • CL_INVALID_OPERATION,有附着到program上的内核对象。
  • CL_INVALID_OPERATION,program不是由clCreateProgramWithSource|Binary创建的。
  • CL_OUT_OF_RESOURCES,为设备上的OpenCL操作分配内存失败。
  • CL_OUT_OF_HOST_MEMORY,为主机上的OpenCL操作分配内存失败。

3、查询程序对象信息
cl_int clGetProgramInfo(cl_program program,
cl_program_info param_name,
size_t param_value_size,
void *param_value,
size_t *param_value_size_ret)
  • program,所要查看的程序对象。
  • param_name,指定所要查看的信息。
  • param_value,指向用来存放查询结果的内存。如果为NULL,则忽略。
  • param_value_size,param_value所指内存的大小。其值必须大于param_name所指定的返回类型。
  • param_value_size_ret,返回查询结果的实际大小。如果为NULL,则忽略。
clGetProgramInfo所支持的param_name
cl_program_info返回类型CL_PROGRAM_REFERENCE_COUNTcl_int返回program的引用计数
CL_PROGRAM_CONTEXTcl_context返回创建程序对象时所指的上下文。
CL_PROGRAM_NUM_DEVICEScl_uint返回program所关联的设备数幕
CL_PROGRAM_DEVICEScl_device_id[]返回program所关联的设备。可以是创建程序对象时所用上下文中的设备,也可以使clCreateProgramWithBinary所指定的设备中的一个子集
CL_PROGRAM_SOURCEchar[]返回传给clCreateProgramWithSource的程序源码。返回的字符串中将所有的源码串在一起,并以null终止。
如果program是用clCreateProgramWithBinary或者clCreateProgramWithBuiltinkernels创建的,可能返回空字符串。或者对应的程序源码,这取决于二进制码中是否有程序源码
param_value_size_ret中会返回源码中字符的实际数目,包含null终止字符。
CL_PROGRAM_BINARY_SIZESsize_t[]返回一个数组,内含program所关联的所有设备的程序二进制码的大小。数组的大小等于program所关联的设备的个数。如果任一设备没有对应的二进制码,则返回零。
如果program是用clCreateProgramWithBuiltinKernels创建的,可能数组中的所有元素都是零。
CL_PROGRAM_BINARIESunsigned char *[]返回一个数组,内涵program所关联的所有设备的二进制码。
param_value指向一个包含n个指针的数组,所有指针都有调用者分配,其中n是program所关联的设备的数目。对于每个指针分配多少内存,可以通过CL_PROGRAM_BINARY_SIZE来查询。
CL_PROGARM_NUM_KERNELSsize_t返回program中声明的内核总数。对于program所关联的设备来说,至少要为其中之一成功构建了可执行程序对象,然后才能使用此资讯。
CL_PROGRAM_KERNEL_NAMESchar []返回program中内核的名字,以分号间隔。对于progarm所关联的设备来说, 至少要为其中之一成功构建了可执行程序对象,然后才能使用此资讯。   

如果执行成功,clGetProgramInfo会返回CL_SUCCESS,否则返回下列错误码之一:
  • CL_INVALID_VALUE,parma_name无效,或者param_value_size小于param_name的返回类型的大小,且param_value不是NULL。
  • CL_INVALID_PROGRAM,program无效。
  • CL_INVALID_PROGRAM_EXECUTABLE,param_name是CL_PROGRAM_NUM_KERNELS 或者CL_PROGRAM_KERNEL_NAMES,并且在program所关联的设备中至少有一个设备所对应的程序执行体没有成功构建。
  • CL_OUT_OF_RESOURCES,为设备上的OpenCL操作分配内存失败。
  • CL_OUT_OF_HOST_MEMORY,为主机上的OpenCL操作分配内存失败。
4、查询编译程序信息
cl_int clGetProgramBuildInfo (cl_program program,
cl_device_id device,
cl_program_build_info param_name,
size_t param_value_szie,
void *param_value,
size_t *param_value_size_ret)
  • program,所要查询的程序对象。
  • device,指定要查询那个设备的构建信息。device必须是program所关联的设备。
  • param_name,指定要查询什么信息。
  • param_value,指向的内存用来存放查询结果。如果为NULL,可以忽略。
  • param_value_size,param_size所指向的内存的大小。其值必须大于对应的param_name所返回的类型的大小。
  • param_value_size_ret,返回查询结果的实际大小。如果为NULL,则忽略。
如果执行成功,clGetProgramBuildInfo会返回CL_SUCCESS。否则,返回下列错误吗之一:
  • CL_INVALID_DEVICE,device不是与program相关联的设备。
  • CL_INVALID_VALUE,param_name无效,或者param_value_size小于相应的param_name返回类型的大小,且param_value不是NULL。
  • CL_INVALID_PROGRAM,program无效。
  • CL_OUT_OF_RESOURCES,为设备上的OpenCL操作分配内存失败。
  • CL_OUT_OF_HOST_MEMORY,为主机上的OpenCL操作分配内存失败。

clGetProgramBuildInfo所支持的param_name
cl_program_build_info返回类型CL_PROGRAM_BUILD_STATUScl_build_status返回构建、编译或链接的状态,在program上为device最后事实的那个(clBuildProgram、clCompileProgram或clLinkProgram)。
可以是下列之一:
  • CL_BUILD_NONE,三个步骤都没有实施。
  • CL_BUILD_ERROR,最后实施的那个出错。
  • CL_BUILD_SUCCESS,最后实施的那个成功。
  • CL_BUILD_IN_PROGRESS,最后实施的那个还未完成。
CL_PROGRAM_BUILD_OPTIONSchar[]返回构建、编译或链接的选项,即最后实施的那个的参数options。如果状态是CL_BUILD_NONE,则返回空字串。
CL_PROGRAM_BUILD_LOGchar []返回最后实施的那个的日志。如果状态是CL_BUILD_NONE,则返回空字符串。
CL_PROGRAM_BINARY_TYPEcl_program_binary_type返回device所对应的二进制码。可以是下列之一:
  • CL_PROGRAM_BINARY_TYPE_NONE,没有对应的二进制码。
  • CL_PROGRAM_BINARY_TYPE_COMPILED_OBJECT,有编译过的二进制码。如果program是使用clCreateProgramWithSource创建并使用clComplieProgram编译的,或者是用clCreateProgramWithBinary装载的编译过的二进制码,都是这种情况。
  • CL_PROGRAM_BINARY_TYPE_LIBRARY,有庫的二元碼。如果用 clLinkProgram 創建 program 時指定了鏈接選項 -create-library,或者是用 clCreateProgramWithBinary 裝載的庫的二元碼,都屬於這種情況。
  • CL_PROGRAM_BINARY_TYPE_EXECUTABLE,有可執行的二元碼。如果用 clLinkProgram 創建 program 時沒有指定鏈接選項 -create-library,或者是用 clCreateProgramWithBinary 裝載的可執行的二元碼,都屬於這種情況。

5、创建程序的另一种方法
cl_program clCreateProgramWithBinary (cl_context context,
cl_uint num_devices,
const cl_device_id *device_list,
const unsigned char **binaries,
cl_int *binary_status,
cl_int *errcode_ret)
clCreateProgramWithBinary 会创建一个程序对象,并将binary中的内容装载到此对象中。
cl_program clCreateProgramWithBuiltInKernels(
cl_context context,
cl_uint num_devices,
const cl_device_id *device_list,
const char *kernel_names,
cl_int *errcode_ret)
clCreateProgramWithBuiltInKernels 会创建一个程序对象,并将内建内核的相关资讯装载到此对象中。  
  
6、编译和链接的分离
  • 编译阶段、链接阶段的分离。编译阶段可以将程序源码编译成二进制目标码,而链接阶段可以将其与其他目标码链接成程序执行体。
  • 潜入头文件。。对于程序源码所包含的头文件来说,构建选项 -I可以用来指定搜索路径。 也可以在目标码中内嵌头文件的源码。
  • 库。可以使用连接器将目标码和库连接成程序执行体,或者创建一个新的库。
cl_int clCompileProgram(
cl_program program,
cl_uint num_devices,
const cl_device_id *device_list,
const char *options,
cl_uint num_input_headers,
const cl_program *input_headers,
const char **header_include_names,
void (CL_CALLBACK *pfn_notify)(
cl_program program,
void *user_data),
void *user_data)
这个函数是用来编译程序源码的。便以前会记性预处理。编译工作的目标设备是program所关联的所有设备或那些指定的设备。

cl_program clLinkProgram (cl_context context,
cl_uint num_devices,
const cl_device_id *device_list,
const char *options,
cl_uint num_input_programs,
const cl_program *input_programs,
void (CL_CALLBACK *pfn_notify)(
cl_program program,
void *user_data),
void *user_data,
cl_int *errcode_ret)
这个函数可以把一组目标码和库链接成执行体,并创建一个包含这个执行体的程序对象。

7、编译选项

预处理选项:
  • -D name
    • 预定义宏name,其值为1。
  • -D name = definition
    • 预定义宏name为definition。
  • -I dir
    • 在头文件搜索路径中包含目录dir
浮点数选项:
  • -cl-single-precision-constant
    • 将双精度浮点常数视为单精度浮点常数。
  • -cl-demorms-are-zero
    • 对于双精度和单精度数,这个选项指定非规格化数可以刷新为零
  • -cl-fp32-correctly-rounded-divide-sqrt
    • 对于程序源码中的单精度浮点除法和sqrt而言,应用可以使用此选项来保证对它们的正确舍入。
优化选项:
  • -cl-opt-disable
    • 禁用所有优化。缺省情况下优化是打开的。
  • -cl-mad-enable
    • 允许mad代替a*b+c。mad会用较低的精确度来计算a*b+c。
  • -cl-no-signed-zeros
    • 允许在进行浮点运算时忽略零的正负。
  • -cl-unsafe-math-optimizations
    • 允许对浮点算术的优化:
      • 假定参数和结果都是有效的;
      • 可能违反IEEE754的标准
      • 可能违反对梵净度浮点数的数值符合性的要求
    • 此选项包含了-cl-no-signed-zeros和-cl-mad-enable。
  • -cl-finite-math-only
    • 在执行浮点算术运算时,可以假定参数和结果不是NAN或这无穷大无穷小。
  • -cl-fast-relaxed-math
    • 相当于-cl-finite-math-only和-cl-unsafe-math-optimizations的组合。
请求或抑制警告的选项
  • -w
    • 禁止所有的警告信息。
  • -Werror
    • 把所有警告都当成错误。
控制OpenCL C版本的选项
  • -cl-std = version
    • 确定所使用的OpenCL C语言的版本。
0 0
原创粉丝点击