OpenCL笔记
来源:互联网 发布:最好的seo课程 编辑:程序博客网 时间:2024/05/21 09:05
OpenCL笔记
Author: Leoeon
Date: 2014.06.02
Url: http://blog.csdn.net/Leoeon/article/details/52719164
- OpenCL笔记
- 主机设备交互
- 执行环境
- 缓冲对象
- 内存模型
- 执行函数
- 查看过程信息
- 释放
- 采样器
cl_int 调用状态;//函数调用后都应检查是否 调用状态==CL_SUCCESS
1.主机——设备交互
cl_uint 平台数目;cl_int 调用状态 = clGetPlatformIDs( 0, NULL, cl_uint* (&平台数目));cl_platform_id *平台列表 = (cl_platform_id*) malloc(平台数目*sizeof(cl_platform_id));cl_int 调用状态 = clGetPlatformIDs( cl_uint 平台数目, cl_platform_id* 平台列表, NULL); //获取指定系统上可用的计算平台
cl_uint 设备数目;cl_int 调用状态 = clGetDeviceIDs( cl_platform_id 平台列表[0], cl_device_type 设备类型, 0, NULL, cl_uint* (&设备数目))cl_device_id *设备列表 = (cl_device_id*)malloc(设备数目*sizeof(cl_device_id));cl_int 调用状态 = clGetDeviceIDs( cl_platform_id 平台列表[0], cl_device_type 设备类型, cl_uint 设备数目, cl_device_id* 设备列表, NULL); //获取指定平台上可用的计算设备 //设备类型: CL_DEVICE_TYPE_GPU:仅GPU CL_DEVICE_TYPE_CPU:仅CPU CL_DEVICE_TYPE_ACCELERATOR:OpenGL 专用加速器 CL_DEVICE_TYPE_DEFAULT:系统默认OpenCL设备 CL_DEVICE_TYPE_ALL:所有设备
2.执行环境
cl_context 上下文 = clCreateContext( const cl_context_properties* 上下文属性, cl_uint 设备数目, const cl_device_id* 设备列表, void(*回调函数), void* 回调函数实参, cl_int* (&调用状态)); //新建上下文,用于协调主机——设备之间的交互机制,即管理命令队列、内存、程序和内核等对象,并在上下文所指定的一个或多个设备上执行内核//或cl_context 上下文 = clCreateContextFromType ( cl_context_properties* 上下文属性, cl_device_type 设备类型,void(*回调函数), void* 回调函数实参, cl_int* (&调用状态)); //根据设备类型创建一个OpenCL上下文,此设备类型用来标识要使用的设备 //上下文属性指向一个列表,其中有上下文属性名称及其对应的值。每个属性名称后面紧跟其对应的期望值 //void(*回调函数)( const char* errinfo, const void* private_info, size_t cb, void* 回调函数形参);
cl_command_queue 命令队列 = clCreateCommandQueue( cl_context 上下文, cl_device_id 设备列表[0], cl_command_queue_properties 队列属性, cl_int* (&调用状态)); //新建命令队列并关联到设备 //每个命令队列只关联一个设备 //队列属性: CL_QUEUE_PROFILING_ENABLE:程序剖析 CL_QUEUE_OUT_OF_ORDER_EXEC_MODE_ENABLE:乱序执行命令。(由用户指定依赖关系以确保正确的执行顺序)cl_int clSetCommandQueueProperty ( cl_command_queue 命令队列, cl_command_queue_properties 队列属性, cl_bool 能否, cl_command_queue_properties* 之前的属性); //使能或禁止命令队列的属性 //能否: CL_TRUE:允许 CL_FALSE:禁止
3.缓冲对象
以数组形式读写内存
cl_mem 内存空间 = clCreateBuffer( cl_context 上下文, cl_mem_flags 读写状态, size_t 内存大小, void* host_ptr, cl_int* (&调用状态)); //为设备分配内存缓冲区cl_int 调用状态 = clEnqueueWriteBuffer( cl_command_queue 命令队列, cl_mem 内存空间, cl_bool 阻塞状态, size_t 偏移量, size_t 内存大小, const void* 写数组名指针, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event); //将主机端数据传入设备内存中cl_int 调用状态 = clEnqueueReadBuffer( cl_command_queue 命令队列, cl_mem 内存空间, cl_bool 阻塞状态, size_t 偏移量, size_t 内存大小, const void* 读数组名指针, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_event* event); //将设备内存中数据传回主机端cl_int clEnqueueCopyBuffer (cl_command_queue 命令队列, cl_mem 旧内存空间, cl_mem 新内存空间, size_t 旧偏移量, size_t 新偏移量, size_t 内存大小, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event); //将旧内存空间拷贝到新内存空间中
以imag形式读写内存
cl_mem clCreateImage2D( cl_context 上下文, cl_mem_flags 读写状态, const cl_image_format* 图像格式描述符, size_t 图像宽, size_t 图像高, size_t 一维宽切片字节数, void* 应用已分配图像数据, cl_int* (&调用状态));cl_mem clCreateImage3D( cl_context 上下文, cl_mem_flags 读写状态, const cl_image_format* 图像格式描述符, size_t 图像宽, size_t 图像高, size_t 图像深, size_t 一维宽切片字节数, size_t 二维宽高切片的字节数, void* 应用已分配图像数据, cl_int* (&调用状态)); //创建图像对象typedef struct _cl_image_format { cl_channel_order 通道数目和布局; cl_channel_type 通道数据类型大小;} cl_int clEnqueueWriteImage( cl_command_queue 命令队列, cl_mem 图像空间, cl_bool 阻塞状态, const size_t 偏移量[3], const size_t 三维边长[3], size_t row_pitch, size_t slice_pitch, void* 主机内存, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event); //将主机端数据传入设备内存中cl_int clEnqueueReadImage( cl_command_queue 命令队列, cl_mem 图像空间, cl_bool 阻塞状态, const size_t 偏移量[3], const size_t 三维边长[3], size_t row_pitch, size_t slice_pitch, void* 主机内存, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event); //将设备内存中数据传回主机端cl_int clEnqueueCopyImage (cl_command_queue 命令队列, cl_mem 旧图像空间, cl_mem 新图像空间, const size_t 旧偏移量[3], const size_t 新偏移量[3], const size_t 三维边长[3], cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event); //将旧图像空间拷贝到新图像空间中
cl_int clEnqueueCopyImageToBuffer( cl_command_queue 命令队列, cl_mem 旧图像空间, cl_mem 新内存空间, const size_t 旧偏移量[3], const size_t 旧三维边长[3], size_t 新偏移量, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event); //将图像空间拷贝到内存空间中cl_int clEnqueueCopyBufferToImage( cl_command_queue 命令队列, cl_mem 旧内存空间, cl_mem 新图像空间, size_t 旧偏移量, const size_t 新偏移量[3], const size_t 新三维边长[3], cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event); //将内存空间拷贝到图像空间中
void* 主机地址 = clEnqueueMapBuffer( cl_command_queue 命令队列, cl_mem 内存空间, cl_bool 阻塞状态, cl_map_flags MAP读写状态, size_t 偏移量, size_t 内存大小, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event, cl_int* (&调用状态)); //将内存空间的某个区域映射到主机地址空间中,并返回一个指向映射区域的指针void* 主机地址 = clEnqueueMapImage( cl_command_queue 命令队列, cl_mem 图像空间, cl_bool 阻塞状态, cl_map_flags MAP读写状态, const size_t 偏移量[3], const size_t 三维边长[3], size_t*(&一维宽切片字节数), size_t*(&二维宽高切片的字节数), cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event, cl_int *errcode_ret); //将图像空间的某个区域映射到主机地址空间中,并返回一个指向映射区域的指针cl_int clEnqueueUnmapMemObject (cl_command_queue 命令队列, cl_mem 内存/图像空间, void* 主机地址, cl_uint num_events_in_wait_list, const cl_event *event_wait_list, cl_event *event); //对之前所映射的内存对象区域进行解映射
读写状态:
CL_MEM_READ_ONLY:只读 CL_MEM_WRITE_ONLY:只写 CL_MEM_READ_WRITE:读写 CL_MEM_USE_HOST_PTR: CL_MEM_ALLOC_HOST_PTR: CL_MEM_COPY_HOST_PTR:从host_ptr处拷贝数据
如果在创建缓冲对象或图像对象时,mem_flags中设置了CL_MEM_USE_HOST_PTR,就会:
当clEnqueueMapBuffer或clEnqueueMapImage的命令完成时,保证clCreateBuffer或clCreateImage{2D|3D}中的host_ptr含有所映射区域的最新内容。
MAP读写状态:CL_MAP_READ 或 CL_MAP_WRITE
内存大小 以字节为单位
图像宽、图像高单位为像素
读写偏移量 和 三维边长 以像素为单位
阻塞状态:
CL_TRUE:阻塞clEnqueueWriteBuffer函数返回直到写操作完成
CL_FALSE:允许clEnqueueWriteBuffer函数返回先于写操作完成
event_wait_list和num_events_in_wait_list指定在执行此命令前必须完成的事件,event返回一个事件对象用来标识此读写命令,也可以用来查询或等待此命令的完成
4.内存模型
全局内存:__global,设备中所有计算单位共享
常量内存:__constant,设备中所有计算单位共享
本地内存:__local,workgroup共享
私有内存:__private,只对单个work-item可见
const char* 核代码 = { "__kernel ", "void 核函数名( __global 形参){} "}//或const char* 核代码文件路径 = shrFindFilePath( "核函数文件名.cl", NULL);const char* 核代码 = oclLoadProgSource( 核代码文件路径, "", &文件长度);
get_work_dim(); //返回线程调度的维数get_num_groups(第几维); //返回该维上全局中work-group的数目get_global_size(第几维); //返回该维上全局中work-item的数目get_local_size(第几维); //返回该维上work-group中work-item的数目get_group_id(第几维); //返回该维上当前work-group在全局中的索引get_global_id(第几维); //返回该维上当前work-item在全局中的索引get_local_id(第几维); //返回该维上当前work-item在work-group中的索引
5.执行函数
cl_program 核代码对象 = clCreateProgramWithSource( cl_context 上下文, cl_uint 核代码串数量, (const char**)&核代码, const size_t* 核代码串长度, cl_int* (&调用状态)); //生成相关代码//或cl_program 核代码对象 = clCreateProgramWithBinary( cl_context 上下文, cl_uint 设备数目, const cl_device_id* 设备列表, const size_t* 二进制代码长度, const unsigned char **每个设备中二进制代码, cl_int* 设备装载调用状态列表, cl_int* (&调用状态)); //生成相关二进制代码
cl_int 调用状态 = clBuildProgram( cl_program 核代码对象, cl_uint 设备数目, const cl_device_id* 设备列表, const char* 编译选项, void (*回调函数), void* 回调函数实参); //编译设备中的代码(运行阶段编译) //void (*回调函数)(cl_program, void* 回调函数形参)
cl_kernel 核对象 = clCreateKernel( cl_program 核代码对象, const char* "核函数名", cl_int* (&调用状态)); //提取代码入口点//或cl_int clCreateKernelsInProgram( cl_program 核代码对象, cl_uint 核对象数目, cl_kernel* 核对象列表, cl_uint* 核代码对象中核对象数目); //为 program 中所有核函数创建核对象
cl_int 调用状态 = clSetKernelArg( cl_kernel 核对象, 第几个参数, 参数大小, 实参指针); //传入实参
cl_int 调用状态 = clEnqueueNDRangeKernel( cl_command_queue 命令队列, cl_kernel 核对象, cl_uint 新建work-item的维度, const size_t* work-item的全局ID, const size_t* NDRange中每维work-item数量, const size_t* workgroup中每维work-item的数量, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_int* event); //请求在设备上执行核对象//或cl_int clEnqueueTask( cl_command_queue 命令队列, cl_kernel 核对象, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_int* event); //请求在设备上执行核对象。核对象在执行时仅使用单个工作项//或cl_int clEnqueueNativeKernel (cl_command_queue 命令队列, void (*可被主机调用的函数)(void *), void* 调用主机函数时所用的实参列表, size_t 主机函数参数个数, cl_uint 主机函数所传递的缓冲对象的数目, const cl_mem* 主机函数所传递的缓冲对象, const void** 主机函数参数存储内存对象句柄的位置, cl_uint num_events_in_wait_list, const cl_event* event_wait_list, cl_int* event); //执行一个原生的(不是用 OpenCL 编译器编译的)C/C++函数 //设备的 CL_DEVICE_EXECUTON_CAPABILITIES 中必须设置了 CL_EXEC_NATIVE_KERNEL
cl_int 调用状态 = clFlush( cl_command_queue 命令队列); //阻塞直到命令队列中所有命令被移出队列,未必执行完毕cl_int 调用状态 = clFinish( cl_command_queue 命令队列); //阻塞至命令队列中的所有命令完成
6.查看过程信息
查询的通用用法示例:
cl_int clGetProgramBuildInfo( cl_program 核代码对象, cl_device_id 设备列表[0], cl_program_build_info 参数名, 0, NULL, size_t* (&查询返回值实际字节数));char* 查询返回值 = new char[查询返回值实际字节数+1];cl_int clGetProgramBuildInfo( cl_program 核代码对象, cl_device_id 设备列表[0], cl_program_build_info 参数名, size_t 查询返回值实际字节数, void* 查询返回值, NULL);查询返回值[查询返回值实际字节数] = "\0";
cl_int clGetPlatformInfo ( cl_platform_id 平台列表[0], cl_platform_info 查询信息, size_t 查询返回值字节数, void* 查询返回值, size_t* 查询返回值实际字节数); //确定具体使用哪一个已定义的实现平台 //查询信息: CL_PLATFORM_PROFILE:实现所支持的简档名称,有FULL_PROFILE(实现支持 OpenCL 规范)和EMBEDDED_PROFILE(实现支持 OpenCL嵌入式简档)两种 CL_PLATFORM_VERSION:OpenCL版本 CL_PLATFORM_NAME:平台名字 CL_PLATFORM_VENDOR:平台供应商 CL_PLATFORM_EXTENSIONS:平台所支持的扩展名字的列表cl_int clGetDeviceInfo ( cl_device_id 设备列表[0], cl_device_info 查询信息, size_t 查询返回值字节数, void* 查询返回值, size_t* 查询返回值实际字节数); //获取一个 OpenCL 设备的特定信息
cl_int clRetainContext (cl_context 上下文); //增大上下文的引用计数cl_int clReleaseContext ( cl_context 上下文); //减小上下文的引用计数cl_int clGetContextInfo (cl_context 上下文, cl_context_info param_name, cl_device_info 查询信息, size_t 查询返回值字节数, void* 查询返回值, size_t* 查询返回值实际字节数); //查询上下文相关信息 //查询信息: CL_CONTEXT_REFERENCE_COUNT:上下文的引用计数 CL_CONTEXT_DEVICES:上下文中的设备列表 CL_CONTEXT_PROPERTIES:上下文属性
cl_int clRetainCommandQueue( cl_command_queue 命令队列); //增大命令队列的引用计数cl_int clReleaseCommandQueue( cl_command_queue 命令队列); //减小命令队列的引用计数cl_int clGetCommandQueueInfo( cl_command_queue 命令队列, cl_context_info param_name, cl_device_info 查询信息, size_t 查询返回值字节数, void* 查询返回值, size_t* 查询返回值实际字节数); //查询命令队列相关信息 //查询信息: CL_QUEUE_CONTEXT:创建命令队列时所指定的上下文 CL_QUEUE_DEVICE:创建命令队列时所指定的设备 CL_QUEUE_REFERENCE_COUNT:命令队列的引用计数 CL_QUEUE_PROPERTIES:命令队列的队列属性
cl_int clRetainMemObject( cl_mem 内存空间); //增大内存空间的引用计数cl_int clReleaseMemObject( cl_mem 内存空间); //减小内存空间的引用计数
cl_int clGetSupportedImageFormats( cl_context 上下文, cl_mem_flags 读写状态, cl_mem_object_type 图像类型, cl_uint 图像格式支持列表内存最多可以存储多少条图像格式, cl_image_format* 图像格式支持列表, cl_uint* 所支持图像格式的实际数目); //获取OpenCL实现所支持的图像格式列表 //图像类型:CL_MEM_OBJECT_IMAGE2D 或 CL_MEM_OBJECT_IMAGE3D
cl_int clGetMemObjectInfo( cl_mem 内存/图像空间, cl_mem_info 查询信息, size_t 查询返回值字节数, void* 查询返回值, size_t* 查询返回值实际字节数); //获取内存/图像空间共有的信息cl_int clGetImageInfo (cl_mem 图像空间, cl_image_info 查询信息, size_t 查询返回值字节数, void* 查询返回值, size_t* 查询返回值实际字节数); //获取图像空间特有的信息
cl_int clRetainProgram( cl_program 核代码对象); //增大核代码对象的引用计数cl_int clReleaseProgram( cl_program 核代码对象); //减小核代码对象的引用计数cl_int clGetProgramInfo( cl_program 核代码对象, cl_program_info 查询信息, size_t 查询返回值字节数, void* 查询返回值, size_t* 查询返回值实际字节数); //获取程序对象的信息 cl_int clGetProgramBuildInfo( cl_program 核代码对象, cl_device_id 设备列表[0], cl_program_build_info 查询信息, size_t 查询返回值字节数, void* 查询返回值, size_t* 查询返回值实际字节数); //查看编译信息
cl_int clRetainKernel( cl_kernel 核对象); //增大核对象的引用计数cl_int clReleaseKernel( cl_kernel 核对象); //减小核对象的引用计数cl_int clGetKernelInfo (cl_kernel 核对象, cl_kernel_info 查询信息, size_t 查询返回值字节数, void* 查询返回值, size_t* 查询返回值实际字节数); //查看核对象信息cl_int clGetKernelWorkGroupInfo (cl_kernel 核对象, cl_device_id 设备列表[0], cl_kernel_work_group_info 查询信息, size_t 查询返回值字节数, void* 查询返回值, size_t* 查询返回值实际字节数); //查看某设备上核对象信息
cl_ulong startTime;clGetEventProfilingInfo( ev, CL_PROFILING_COMMAND_START, sizeof(cl_ulong), &startTime, NULL);
7.释放
clReleaseKernel(核对象);clReleaseProgram(核代码对象);clUnloadCompiler (void);clReleaseCommandQueue(命令队列);clReleaseMemObject(内存空间);clReleaseContext(上下文);
8.采样器
cl_sampler 采样器 = clCreateSampler( cl_context 上下文, cl_bool 是否规范化, cl_addressing_mode 处理越界图像坐标方式, cl_filter_mode 读取图像时所采用的滤波模式, cl_int* (&调用状态)) //创建一个采样器对象 //是否规范化:CL_TRUE 或 CL_FALSE //处理越界图像坐标方式:CL_ADDRESS_REPEAT、CL_ADDRESS_CLAMP_TO_EDGE、CL_ADDRESS_CLAMP、CL_ADDRESS_NONE //读取图像时所采用的滤波模式:CL_FILTER_NEAREST 或 CL_FILTER_LINEARcl_int clRetainSampler (cl_sampler 采样器); //增大采样器的引用计数cl_int clReleaseSampler (cl_sampler 采样器); //减小采样器的引用计数cl_int clGetSamplerInfo (cl_sampler 采样器, cl_mem_info 查询信息, size_t 查询返回值字节数, void* 查询返回值, size_t* 查询返回值实际字节数); //获取采样器相关信息
0 0
- OPencl 笔记
- OpenCL笔记
- OpenCL笔记
- opencl笔记
- OpenCL 笔记
- OpenCL 笔记3 OpenCL和CUDA
- OpenCL 学记笔记
- OpenCL学习笔记(1)
- OpenCl 笔记2 Optimization
- OPencl学习笔记
- OPencl学习笔记2
- OPencl学习笔记3
- OpenCL学习笔记(一)
- OpenCl 笔记1 Memory Model
- OpenCL 笔记4 projector application
- OpenCL 笔记5 reconstruction application
- ubuntu 安装opencl失败笔记
- OpenCL driver Ubuntu16.04笔记
- php设计模式(工厂模式)
- C++ hdu 2055 An easy problem
- JSON学习入门
- 【C++研发面试笔记】3. 命名空间与内存管理
- 进入OS前的两步之PendSV(任务切换)
- OpenCL笔记
- Linux - C数据库编程(预习内容四)
- 嵌入式系统学习(九)-用过内核驱动操作GPIO
- Struts2 formBean传值
- map应用:反片语
- STL(七):stack 与 queue
- 嵌入式Linux移植之initramfs
- linux如何用fdisk命令分区
- 拓扑排序 - Topological Sort