当前位置: 首页 > news >正文

OpenCL(贰):浅析CL内核程序接口函数

目录

        1.前言

        2.获取平台信息

1.cl_int类型

2.cl_platform_id类型

3.clGetPlatformIDs():查询系统OpenCL平台数量或获取具体的平台信息

4.clGetPlatformInfo():查询指定OpenCL平台的信息,例如平台名称、供应商、版本等

        3.设置OpenCL上下文Context属性

1.cl_context_properties类型

        4.创建上下文

1.cl_context类型

2.clCreateContextFromType():用于根据设备类型创建上下文的函数

        5.寻找OpenCL设备(GPU)

1.cl_device_id类型

2.clGetContextInfo():用于查询上下文cl_context的相关信息

        6.创建CL内核函数

        7.装载内核程序

1.cl_program类型

2.clCreateProgramWithSource():用于创建一个程序对象,该程序对象包含OpenCL C源代码

        8.生成CL程序并获取实例句柄

1.cl_kernel类型

2.clBuildProgram():用于编译OpenCL程序对象,生成针对目标设备的执行代码

        9.创建命令队列和缓冲区

1.cl_command_queue类型

2.cl_mem类型

3.clCreateCommandQueue():创建一个命令队列,用于在指定的 OpenCL 设备上执行命令

4.clCreateBuffer():创建一个 OpenCL 缓冲区内存对象,用于在 OpenCL 设备上存储数据

        10.将参数传入内核程序并传入命令队列

1.clSetKernelArg(): 用于为 OpenCL 内核的特定参数设置参数值。在执行内核之前,必须为内核的所有参数设置值

2.clEnqueueNDRangeKernel() :用于将内核执行命令排队到命令队列中

        11.执行命令队列并保存至主机

1.clFinish() :用于确保命令队列中的所有命令都已执行完毕。会阻塞主机线程,直到命令队列中的所有命令都完成执行

2.clEnqueueReadBuffer():用于将数据从设备的缓冲区读取到主机内存中。它可以是阻塞或非阻塞的,具体取决于blocking_read参数

        12.释放资源

1.clReleaseKernel():减少指定内核对象的引用计数。当引用计数降为零时,内核对象将被释放

2.clReleaseProgram():减少指定程序对象的引用计数。当引用计数降为零时,程序对象及其构建的对象(如内核)将被释放

3.clReleaseMemObject():减少指定内存对象的引用计数。当引用计数降为零时,内存对象将被释放

4.clReleaseCommandQueue():减少指定命令队列的引用计数。当引用计数降为零时,命令队列将被释放

5.clReleaseContext():减少指定上下文对象的引用计数。当引用计数降为零时,上下文及其关联的所有对象(如命令队列、内存对象、程序对象和内核对象)都将被释放


前言

        紧接文章《OpenCL(壹):了解OpenCL模型到编写第一个CL内核程序》的内容,本篇文章将针对上一篇提到的第一个CL内核程序中的函数接口进行刨析,解释每一个接口文档的作用。当然这或许比不上官方的文档,但是详细的解析有利于后续开发的翻阅,只有做好归纳总结才能为己所用,在开发中遇到的问题也会迎刃而解。附官方文档链接:

OpenCL2.1接口icon-default.png?t=O83Ahttps://registry.khronos.org/OpenCL/sdk/2.1/docs/man/xhtml/OpenCL2.1接口.pdficon-default.png?t=O83Ahttps://registry.khronos.org/OpenCL/sdk/2.1/docs/OpenCL-2.1-refcard.pdf


获取平台信息

        根据前文的程序,我们在main函数中第一步操作是获取平台的详细,代码如下:

cl_int status = 0;        //记录函数状态
size_t deviceListSize;    //记录设备个数
cl_uint numPlatforms;     //可用平台数量
cl_platform_id platform = NULL;    //存储平台ID
status = clGetPlatformIDs(0, NULL, &numPlatforms);    //获取平台个数
if (status != CL_SUCCESS) {    std::cout << "错误:获取设备失败" << std::endl;return EXIT_FAILURE;
}if (numPlatforms > 0) {    //个数大于0则便利平台信息cl_platform_id* platforms = (cl_platform_id*)malloc(numPlatforms * sizeof(cl_platform_id));    //创建内存存储平台信息status = clGetPlatformIDs(numPlatforms, platforms, NULL);    //获取平台IDif (status != CL_SUCCESS) {std::cout << "错误:获取平台ID失败" << std::endl;return -1;}for (unsigned int i = 0; i < numPlatforms; ++i) {    //遍历平台列表获取平台信息char pbuff[100];status = clGetPlatformInfo(platforms[i], CL_PLATFORM_VENDOR, sizeof(pbuff), pbuff, NULL);    //获取平台信息platform = platforms[i];if (!strcmp(pbuff, "GPU")) {    break;}}delete platforms;
}

        在这段代码中分别提到了几种OpenCL中的类型和函数,以下是具体的解释:

类型名称含义64位平台大小

cl_int类型

一个 32 位的有符号整数,用于返回状态码或作为参数的整型变量4字节

cl_platform_id类型

句柄类型,用于标识一个特定的OpenCL平台8字节

表1.OpenCL中的特定类型

        clGetPlatformIDs():查询系统OpenCL平台数量或获取具体的平台信息

cl_int clGetPlatformIDs(cl_uint num_entries,        //指定存储的平台数量的对象cl_platform_id *platforms,  //指定存储平台ID的对象cl_uint *num_platforms      //指定存储返回平台总数的对象
);返回值类型:cl_int1.CL_SUCCESS:函数成功执行。2.CL_INVALID_VALUE:传递的参数值无效。例如num_entries为0而platforms不为NULL3.CL_OUT_OF_HOST_MEMORY:主机内存不足,无法完成操作

        clGetPlatformInfo():查询指定OpenCL平台的信息,例如平台名称、供应商、版本等

cl_int clGetPlatformInfo(cl_platform_id platform,        //指定要查询的OpenCL平台cl_platform_info param_name,    //指定要查询的平台属性size_t param_value_size,        //指定param_value缓存的大小void *param_value,              //指向用于存储返回值的内存地址size_t *param_value_size_ret    //存储返回实际写入param_value的字节数
);返回值类型:cl_int1.CL_SUCCESS:函数成功执行。2.CL_INVALID_VALUE:传递的参数值无效。例如num_entries为0而platforms不为NULL3.CL_OUT_OF_HOST_MEMORY:主机内存不足,无法完成操作

                针对该接口函数中存在的cl_platform_info类型作以下补充:

枚举值含义
CL_PLATFORM_PROFILE返回平台的配置文件
CL_PLATFORM_VERSION返回平台的OpenCL版本
CL_PLATFORM_NAME返回台的名称
CL_PLATFORM_VENDOR返回平台的供应商名称
CL_PLATFORM_EXTENSIONS返回平台支持的扩展列表
CL_PLATFORM_HOST_TIMER_RESOLUTION返回主机定时器的分辨率/纳秒(2.1版本)
CL_PLATFORM_NUMERIC_VERSION返回平台的OpenCL版本号(3.1版本)
CL_PLATFORM_EXTENSIONS_WITH_VERSION返回支持的扩展及其版本(3.0版本)

表2.l_platform_info类型的补充


设置OpenCL上下文Context属性

        后续的小节都会根据编写的OpenCL程序代码进行讲解,就不再对其进行赘述

cl_context_properties cps[3] = {CL_CONTEXT_PLATFORM, (cl_context_properties)platform, 0 };
cl_context_properties* cprops = (NULL == platform) ? NULL : cps;
//Tip:此处的NULL == platform写法可以预防错误的代码编写导致赋值操作
类型名称含义64位平台大小

cl_context_properties类型

上下文属性类型,用于在创建上下文时配置额外的信息8字节

表3.OpenCL中的cl_context_properties类型

        补充以下针对cl_context_properties中的枚举类描述:

枚举量含义
CL_CONTEXT_PLATFORM指定上下文关联的平台
CL_GL_CONTEXT_KHR与OpenGL上下文共享的OpenGL上下文句柄
CL_EGL_DISPLAY_KHR指定 EGL 显示的句柄,用于OpenCL和EGL的互操作
CL_CONTEXT_INTEROP_USER_SYNC用于设置用户同步标志,指定 OpenCL 和其他图形 API 是否需要手动同步(布尔值)

表4.cl_context_properties中的枚举类描述


创建上下文

cl_context context = clCreateContextFromType(cprops, CL_DEVICE_TYPE_GPU, NULL, NULL, &status);
if (status != CL_SUCCESS) {std::cout << "错误:为GPU生成上下文失败" << std::endl;return EXIT_FAILURE;
}

        针对此段代码中提到类型cl_context做以下解释:

类型名称含义64位平台大小

cl_context类型

OpenCL中上下文类型,用于管理设备、内存、程序和命令队列等资源8字节

表5.cl_context类型的补充

        clCreateContextFromType():用于根据设备类型创建上下文的函数

cl_context clCreateContextFromType(const cl_context_properties *properties, //指定上下文的属性列表,通常用于指定平台cl_device_type device_type,              //指定要包含的设备类型void (CL_CALLBACK *pfn_notify)(const char *errinfo, const void *private_info, size_t cb, void *user_data),    //错误通知回调函数,当上下文在运行时发生错误时调用void *user_data,     //传递给回调函数的用户数据,可用于上下文特定的操作cl_int *errcode_ret  //返回错误代码的指针。如果为NULL,错误代码将被忽略
);返回值:cl_context
成功时返回创建的OpenCL上下文,失败时返回 NULL

                在函数中存在一个cl_device_type类型,具体解释如下:

枚举值含义
CL_DEVICE_TYPE_DEFAULT默认设备类型(由平台决定)
CL_DEVICE_TYPE_CPUCPU设备
CL_DEVICE_TYPE_GPUGPU设备
CL_DEVICE_TYPE_ACCELERATOR专用加速器设备
CL_DEVICE_TYPE_CUSTOM自定义设备
CL_DEVICE_TYPE_ALL所有可用设备

6.cl_device_type类型


寻找OpenCL设备(GPU)

//获取设备个数
status = clGetContextInfo(context, CL_CONTEXT_DEVICES, 0, NULL, &deviceListSize);
if (status != CL_SUCCESS) {std::cout << "错误:寻找可用的设备个数失败" << std::endl;return EXIT_FAILURE;
}
cl_device_id* devices = (cl_device_id*)malloc(deviceListSize);
if (devices == 0) {std::cout << "错误:当前可用设备数为0" << std::endl;return EXIT_FAILURE;
}//获取设备列表
status = clGetContextInfo(context, CL_CONTEXT_DEVICES, deviceListSize, devices, NULL);
if (status != CL_SUCCESS) {std::cout << "错误:获取设备信息失败" << std::endl;return EXIT_FAILURE;
}

        针对代码中的cl_device_id类型作以下解释:

类型名称含义64位平台大小

cl_device_id类型

句柄类型,用于表示OpenCL设备的唯一标识符8字节

7.cl_device_id类型

        clGetContextInfo():用于查询上下文cl_context的相关信息

cl_int clGetContextInfo(cl_context context,            //指定要查询的OpenCL上下文cl_context_info param_name,    //指定要查询的信息类型size_t param_value_size,       //指定param_value缓冲区的大小void *param_value,             //存储返回的参数值size_t *param_value_size_ret   //返回实际写入的字节数
);返回值类型:cl_int1.CL_SUCCESS:函数成功执行。2.CL_INVALID_VALUE:传递的参数值无效。例如num_entries为0而platforms不为NULL3.CL_OUT_OF_HOST_MEMORY:主机内存不足,无法完成操作

                在函数中存在cl_context_info枚举类型,指定该枚举类型主要用于设置返回值param_value的类型,对此作以下解释:

枚举值含义param_value的类型
CL_CONTEXT_REFERENCE_COUNT上下文的引用计数,表示当前引用该上下文的对象数量cl_uint
CL_CONTEXT_DEVICES与上下文关联的设备列表cl_device_id[]
CL_CONTEXT_PROPERTIES上下文的属性列表,包括平台信息或其他属性cl_context_properties[]
CL_CONTEXT_NUM_DEVICES上下文中设备的数量cl_uint

表8.cl_context_info枚举类型


创建CL内核函数

#define KERNEL(...)#__VA_ARGS__		//使用#__VA_ARGS_宏将传入KERNEL宏的实参转为字符串//编写内核函数,该内核函数将转换为字符串并由指针kernelSourseCode指向
const char* kernelSourceCode = KERNEL(__kernel void wildpointer(__global uint * buffer) {    //__kernel用于声明OpenCL内核函数size_t gidx = get_global_id(0);size_t gidy = get_global_id(1);size_t lidx = get_local_id(0);buffer[gidx + 4 * gidy] = (1 << gidx) | (0x10 << gidy);}
);

        这段代码主要是将我们需要使用GPU执行的函数转换为字符串,后续通过将函数和参数传入内核程序来指定运行内容,其中要注意的是我们编写的CL内核函数为wildpointer,这在后续我们获取内核实例的句柄需要保持一致。我们也可以不使用这种方式编写内核函数,我们可以编写一个cl文件在需要载入内核程序时进行调用


装载内核程序

//装载内核程序,编译CL程序,生成OpenCL内核实例
size_t sourceSize[] = { strlen(kernelSourceCode) };    //获取函数字符串长度
cl_program program = clCreateProgramWithSource(context, 1, &kernelSourceCode, sourceSize, &status);
if (status != CL_SUCCESS) {std::cout << "错误:将二进制文件装载到内核程序失败" << std::endl;return EXIT_FAILURE;
}

        在这段代码中,存在一个cl_program类型,具体解释如下:

类型名称含义64位平台大小

cl_program类型

用于表示一个OpenCL程序对象,并可通过编译、链接生成可执行的OpenCL内核8字节

表9.cl_program类型

        clCreateProgramWithSource():用于创建一个程序对象,该程序对象包含OpenCL C源代码

cl_program clCreateProgramWithSource(cl_context context,      //程序对象的上下文cl_uint count,           //函数的字符长度const char **strings,    //指向包含OpenCL C源代码的指针const size_t *lengths,   //每个字符串的长度数组cl_int *errcode_ret      //返回函数的错误码
);返回值类型:cl_program
成功时返回创建的程序对象,失败时返回NULL

生成CL程序并获取实例句柄

//为指定的OpenCL设备生成CL程序
status = clBuildProgram(program, 1, devices, NULL, NULL, NULL);
if (status != CL_SUCCESS) {std::cout << "错误:编译CL程序失败" << std::endl;return EXIT_FAILURE;
}//获取内核实例的句柄
cl_kernel kernel = clCreateKernel(program, "wildpointer", &status);
if (status != CL_SUCCESS) {std::cout << "错误:在程序上初始化内核程序失败" << std::endl;return EXIT_FAILURE;
}

        在代码中存在一个cl_kernel类型,具体解释如下:

类型名称含义64位平台大小

cl_kernel类型

表示一个内核对象的句柄类型。内核是 OpenCL 程序的基本执行单位,通常是一个通过编译后生成的函数,用来在设备上执行计算任务8字节

表10.cl_kernel类型

        clBuildProgram():用于编译OpenCL程序对象,生成针对目标设备的执行代码

cl_int clBuildProgram(cl_program program,     //要编译的OpenCL程序对象cl_uint num_devices,    //编译程序的设备个数const cl_device_id *device_list,    //设备列表const char *options,    //编译时的选项字符串,例如优化选项、定义宏等void (*pfn_notify)(cl_program, void *user_data),    //回调函数指针,在编译后调用void *user_data    //传递给回调函数的参数
);返回值类型:cl_int1.CL_SUCCESS:函数成功执行2.CL_INVALID_PROGRAM:无效的程序对象3.CL_INVALID_DEVICE:无效的词语4.CL_INVALID_VALUE:传递的参数值无效。例如num_entries为0而platforms不为NULL5.CL_OUT_OF_HOST_MEMORY:主机内存不足,无法完成操作

        参数options的选项见下表:

选项

含义
-cl-fast-relaxed-math快速浮点计算,用于性能优先的浮点计算
-cl-no-signed-zeros简化符号的处理逻辑,无法使用+0和-0
-cl-mad-enable实现硬件级别乘加指令优化
-I<dir>包含路径,用于指定头文件的搜索目录
-Werror将警告视为错误,确保编译过程无警告
-D<macro>=<value>定义宏变量,用于在源代码中进行条件编译

表11.参数options


创建命令队列和缓冲区

//创建OpenCL命令队列
cl_command_queue commandQueue = clCreateCommandQueue(context, devices[0], 0, &status);
if (status != CL_SUCCESS) {std::cout << "错误:初始化命令队列失败" << std::endl;return EXIT_FAILURE;
}//创建OpenCL缓冲区
unsigned int* outbuffer = new unsigned int[4 * 4];
memset(outbuffer, 0, 4 * 4 * 4);
cl_mem outputBuffer = clCreateBuffer(context, CL_MEM_ALLOC_HOST_PTR, 4 * 4 * 4, NULL, &status);
if (status != CL_SUCCESS) {std::cout << "错误:初始化OpenCL缓冲区失败" << std::endl;return EXIT_FAILURE;
}

        在代码中存在一个cl_command_queue和cl_mem类型,具体解释如下:

类型名称含义64位平台大小

cl_command_queue类型

命令队列类型,用于在OpenCL设备上执行命令,确保命令按顺序执行,如内核执行、内存传输等
8 字节

cl_mem类型


内存对象类型,用于在OpenCL设备上存储数据,允许数据在主机和设备之间进行传输,可以是缓冲区、图像等
8 字节

表12.cl_command_queue和cl_mem类型

        clCreateCommandQueue():创建一个命令队列,用于在指定的 OpenCL 设备上执行命令

cl_command_queue clCreateCommandQueue(cl_context context,    //OpenCL上下文,指定命令队列将要使用的设备和环境cl_device_id device,   //指定命令队列将要执行命令的设备cl_command_queue_properties properties,    //命令队列的属性,用于指定命令队列的行为cl_int *errcode_ret    //返回函数的错误码
);返回值类型:cl_command_queue
返回一个 cl_command_queue 类型的指针,指向创建的命令队列对象。如果创建失败,返回 NULL

        参数cl_command_queue_properties的选项见下表:

选项

含义

CL_QUEUE_OUT_OF_ORDER_EXCE_MODE_ENABLE

无序执行命令

CL_QUEUE_PROFILING_ENABLE

命令队列中的命令将启用性能分析

CL_QUEUE_ON_DEVICE

指示这是一个设备队列

CL_QUEUE_ON_DEVICE_DEFAULT

默认的设备队列

        clCreateBuffer():创建一个 OpenCL 缓冲区内存对象,用于在 OpenCL 设备上存储数据

cl_mem clCreateBuffer(cl_context context,    //OpenCL上下文,指定命令队列将要使用的设备和环境cl_mem_flags flags,    //内存对象的标志,用于指定内存对象的访问权限和行为size_t size,           //内存对象的大小void *host_ptr,        //指向主机内存的指针,NULL则在设备上分配内存;非NULL则使用主机内存cl_int *errcode_ret    //返回函数的错误码
);

        参数cl_mem_flags的选项见下表:

选项含义

CL_MEM_READ_WRITE

默认标志,指定内存对象可以被内核读写

CL_MEM_WRITE_ONLY

指定内存对象只能被内核写入,不能读取

CL_MEM_READ_ONLY

指定内存对象只能被内核读取,不能写入

CL_MEM_USE_HOST_PTR

只有在host_ptr不为NULL时有效。指示OpenCL实现使用host_ptr指向的内存作为内存对象的存储

CL_MEM_ALLOC_HOST_PTR

指示OpenCL实现从主机可访问的内存中分配内存

CL_MEM_COPY_HOST_PTR

只有在host_ptr不为NULL时有效。指示OpenCL实现为内存对象分配内存,并从host_ptr指向的内存中复制数据


将参数传入内核程序并传入命令队列

//将参数传入内核程序
status = clSetKernelArg(kernel, 0, sizeof(cl_mem), (void*)&outputBuffer);
if (status != CL_SUCCESS) {std::cout << "错误:设置内核参数失败" << std::endl;return EXIT_FAILURE;
}//将内核程序插入命令队列
size_t globalThreads[] = {4, 4};
size_t localThread[] = {2, 2};
status = clEnqueueNDRangeKernel(commandQueue, kernel, 2, NULL, globalThreads, localThread, 0, NULL, NULL);
if (status != CL_SUCCESS) {std::cout << "错误:内核程序插入命令队列失败" << std::endl;return EXIT_FAILURE;
}

        clSetKernelArg(): 用于为 OpenCL 内核的特定参数设置参数值。在执行内核之前,必须为内核的所有参数设置值

cl_int clSetKernelArg(cl_kernel kernel,     //内核程序对象cl_uint arg_index,    //参数的索引,从0开始,表示内核参数列表中的位置size_t arg_size,      //参数值的大小const void *arg_value //指向参数值的指针
);返回值类型:cl_int1.CL_SUCCESS:函数成功执行2.CL_INVALID_PROGRAM:无效的程序对象3.CL_INVALID_DEVICE:无效的词语4.CL_INVALID_VALUE:传递的参数值无效。例如num_entries为0而platforms不为NULL5.CL_OUT_OF_HOST_MEMORY:主机内存不足,无法完成操作

        clEnqueueNDRangeKernel() :用于将内核执行命令排队到命令队列中

cl_int clEnqueueNDRangeKernel(cl_command_queue command_queue,    //命令队列对象cl_kernel kernel,    //执行的内核程序对象cl_uint work_dim,    //工作项的维度,范围为1到3const size_t *global_work_offset,  //全局工作项的起始偏移量const size_t *global_work_size,    //每个维度的全局工作项数量const size_t *local_work_size,     //每个工作组中的工作项数量cl_uint num_events_in_wait_list,   //等待事件列表中的事件数量const cl_event *event_wait_list,   //事件对象列表,用于等待之前的一些事件完成cl_event *event       //用于异步传输的事件对象
);返回值类型:cl_int1.CL_SUCCESS:函数成功执行2.CL_INVALID_PROGRAM:无效的程序对象3.CL_INVALID_DEVICE:无效的词语4.CL_INVALID_VALUE:传递的参数值无效。例如num_entries为0而platforms不为NULL5.CL_OUT_OF_HOST_MEMORY:主机内存不足,无法完成操作

执行命令队列并保存至主机

//执行命令队列中的命令
status = clFinish(commandQueue);
if (status != CL_SUCCESS) {std::cout << "错误:完全命令队列" << std::endl;return EXIT_FAILURE;
}//将设备的缓冲区中的数据保存至主机
status = clEnqueueReadBuffer(commandQueue, outputBuffer, CL_TRUE, 0, 4 * 4 * 4, outbuffer, 0, NULL, NULL);
if (status != CL_SUCCESS) {std::cout << "错误:读取缓冲区队列失败" << std::endl;return EXIT_FAILURE;
}

        clFinish() :用于确保命令队列中的所有命令都已执行完毕。会阻塞主机线程,直到命令队列中的所有命令都完成执行

cl_int clFinish(cl_command_queue command_queue    //命令队列对象,指定了要等待其命令完成的队列
);返回值类型:cl_int1.CL_SUCCESS:函数成功执行2.CL_INVALID_PROGRAM:无效的程序对象3.CL_INVALID_DEVICE:无效的词语4.CL_INVALID_VALUE:传递的参数值无效。例如num_entries为0而platforms不为NULL5.CL_OUT_OF_HOST_MEMORY:主机内存不足,无法完成操作

        clEnqueueReadBuffer():用于将数据从设备的缓冲区读取到主机内存中。它可以是阻塞或非阻塞的,具体取决于blocking_read参数

cl_int clEnqueueReadBuffer(cl_command_queue command_queue,    //命令队列对象cl_mem buffer,            //数据缓冲区对象cl_bool blocking_read,    //指示读取操作是否阻塞size_t offset,            //缓冲区中的偏移量size_t size,              //读取的数据大小void *ptr,                //指向主机内存的指针,用于存储读取的数据cl_uint num_events_in_wait_list,    //等待事件列表中的事件数量const cl_event *event_wait_list,    //事件对象列表,用于等待这些事件完成后再执行读取命令cl_event *event           //事件对象,用于查询读取命令的执行状态
);返回值类型:cl_int1.CL_SUCCESS:函数成功执行2.CL_INVALID_PROGRAM:无效的程序对象3.CL_INVALID_DEVICE:无效的词语4.CL_INVALID_VALUE:传递的参数值无效。例如num_entries为0而platforms不为NULL5.CL_OUT_OF_HOST_MEMORY:主机内存不足,无法完成操作

释放资源

status = clReleaseKernel(kernel);
status = clReleaseProgram(program);
status = clReleaseMemObject(outputBuffer);
status = clReleaseCommandQueue(commandQueue);
status = clReleaseContext(context);

        clReleaseKernel():减少指定内核对象的引用计数。当引用计数降为零时,内核对象将被释放

cl_int clReleaseKernel(cl_kernel kernel    //要释放的内核对象
);

        clReleaseProgram():减少指定程序对象的引用计数。当引用计数降为零时,程序对象及其构建的对象(如内核)将被释放

cl_int clReleaseProgram(cl_program program    //要释放的程序对象
);

        clReleaseMemObject():减少指定内存对象的引用计数。当引用计数降为零时,内存对象将被释放

cl_int clReleaseMemObject(cl_mem memobj    //要释放的内存对象,例如缓冲区或图像
);    

        clReleaseCommandQueue():减少指定命令队列的引用计数。当引用计数降为零时,命令队列将被释放

cl_int clReleaseCommandQueue(cl_command_queue command_queue    //要释放的命令队列
);

        clReleaseContext():减少指定上下文对象的引用计数。当引用计数降为零时,上下文及其关联的所有对象(如命令队列、内存对象、程序对象和内核对象)都将被释放

cl_int clReleaseContext(cl_context context    //要释放的上下文对象
);

http://www.lryc.cn/news/516803.html

相关文章:

  • Leetcode 3407. Substring Matching Pattern
  • 学英语学压测:02jmeter组件-测试计划和线程组ramp-up参数的作用
  • Vue笔记-001-声明式渲染
  • 26考研资料分享 百度网盘
  • .NET 8 + Ocelot + Consul 实现代理网关、服务发现
  • 使用 Nginx 轻松处理跨域请求(CORS)
  • 【LeetCode Hot100 二分查找】搜索插入位置、搜索二维矩阵、搜索旋转排序数组、寻找两个正序数组的中位数
  • 使用MediaPipe Face Mesh 面部动作检测
  • 【Vue】<script setup>和 <script>区别是什么?在使用时的写法区别?
  • 微服务框架,Http异步编程中,如何保证数据的最终一致性
  • vue3-dom-diff算法
  • 年会抽奖Html
  • ubuntu16 重启之后lvm信息丢失故障恢复
  • 【华为OD-E卷 - 热点网站统计 100分(python、java、c++、js、c)】
  • Ubuntu下安装Android Sdk
  • 【JVM】总结篇-类的加载篇之 类的加载器 和ClassLoader分析
  • 怎样修改el-table主题样式
  • MySQL(二)MySQL DDL数据库定义语言
  • Spring Boot 项目启动报 NoClassDefFoundError 异常的原因分析与解决方案 - jackson 版本不一致
  • 原型与原型链
  • 【Linux】信号处理
  • 5个不同类型的mysql数据库安装
  • python学习笔记—12—布尔类型、if语句
  • 分数阶傅里叶变换代码 MATLAB实现
  • 《数据结构》期末考试测试题【中】
  • openwrt 清缓存命令行
  • RP2K:一个面向细粒度图像的大规模零售商品数据集
  • .NET Core FluentAPI
  • 【C++数据结构——查找】顺序查找(头歌实践教学平台习题)【合集】
  • HTTP Scheme 通常指的是在 URL 中用于指定使用 HTTP 协议的方案(scheme)