河南网站建设公司哪个好呀百度网址大全官方下载
- 作者: 五速梦信息网
- 时间: 2026年03月21日 10:54
当前位置: 首页 > news >正文
河南网站建设公司哪个好呀,百度网址大全官方下载,产品外观设计公司,wordpress获取分类文章选择OpenCL平台并创建一个上下文 建立OpenCL的第一步是选择一个平台。第2章介绍过#xff0c;OpenCL使用了ICD模型#xff0c;其中可以有多个OpenCL实现在一个系统上并存。类似于HelloWorld示例#xff0c;这个矢量相加程序展示了选择OpenCL平台的一种最简单的方法#xf…选择OpenCL平台并创建一个上下文 建立OpenCL的第一步是选择一个平台。第2章介绍过OpenCL使用了ICD模型其中可以有多个OpenCL实现在一个系统上并存。类似于HelloWorld示例这个矢量相加程序展示了选择OpenCL平台的一种最简单的方法选择第一个可用的平台。 首先调用cl::Platform::get()得到平台列表 std::vectorcl::Platform platformList; cl::Platform::get(platformList);得到平台列表之后这个例子会调用cl::Context()创建一个上下文。cl::Context ()调用会尝试由一个GPU设备创建上下文。如果失败程序会产生一个异常这个程序使用了OpenCL C包装器异常特性以一个错误消息终止。创建上下文的代码如下 cl_context_properties cprops; cl::Context context(CL_DEVICE_TYPE_GPU, cprops); 选择一个设备并创建命令队列 选择一个平台并创建上下文之后矢量相加应用程序的下一步是选择一个设备并创建一个命令队列。第一个任务是查询与之前所创建上下文关联的设备集合。可以通过cl::Context::getInfoCL_CONTEXT_DEVICES ()调用来查询这会返回与上下文关联的设备std::vector。 在继续学习后面的内容之前先来了解getInfo()方法因为它遵循了C包装器API中通用的一种模式。一般来说对于一个支持查询接口的CAPl对象例如查询接口为clGetXXInfo()其中xx是所查询C API对象的名任何表示这样一个CAPI对象的C包装器API对象都有相应的一个接口形式如下 template cl_int typename detail::param_traitsdetail::cl_XX_info, name::param_type cl::Object::getInfo(void);乍一看可能会让你有些害怕因为这里使用了一种称为特征类(traits)的C模板技术这里用于关联clGetXXInfo()提供的共享功能不过由于使用这些getInfo()函数的程序在实际中从来不需要引用特征类组件所以对于开发人员编写的代码没有任何影响。需要指出的重要一点是所有对应一个底层C API对象的C包装器API对象都有一个模板方法名为getInfo()以查询的cl_xx_info枚举值作为其模板参数。其效果是可以静态检查所请求的值是否合法也就是说一个特定的getInfo()方法只接受相应cl_xx_info枚举中定义的值。通过使用这种特征类技术getInfo()函数可以自动推导出结果类型。 再来看矢量相加示例要为关联的一组设备查询一个上下文可以用CL_CONTEXT_DEVICES限定相应的cl::Context::getInfo()返回std::vectorcl::Device。通过以下代码可以说明 //Query the set of devices attached to the context std::vectorcl::Device device context.getInfoCL_CONTEXT_DEVICES();注意利用C包装器API查询方法现在不再需要先查询上下文来找出需要多大的空间存储设备列表然后再提供另一个查询调用得到具体的设备。所有这些都隐藏在C包装器API的一个简单的通用接口中。 选择设备集合之后可以用cl::CommandQueue()创建一个命令队列为简单起见这里选择第一个设备 //Create command-queue cl::CommandQueue queue(context, device[0], 0);创建和构建程序对象 矢量相加示例中的下一步是使用cl::Program()由OpenCL C内核源代码创建一个程序对象矢量相加示例的内核源代码在本章最后的代码清单2-1中给出这里不再重复。程序对象用内核源代码加载然后使用cl::Program::build()编译这个代码以便在与上下文关联的设备上执行。下面给出相应的代码 cl::Program::Sources sources(1,std::make_pair(kernelSourceCode,0)); cl::Program program(context, sources); program.build(devices);与其他C包装器API调用类似如果出现错误则会有一个异常程序将退出。 创建内核和内存对象 要执行OpenCL计算内核需要在OpenCL设备上可访问的内存中分配内核函数的参数这里就是缓冲区对象。这些缓冲区对象使用cl::Buffer()创建。对于输入缓冲区我们使用CL_MEM_COPY_FROM_HOST_PTR来避免额外的调用来移动输人数据。对于输出缓冲区即矢量相加的结果则使用CL_MEM_USE_HOST_PTR这要求将结果缓冲区映射到宿主机内存以便访问结果。可以使用以下代码来分配这些缓冲区 cl::Buffer aBuffer cl::Buffer(context,CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,BUFFER_SIZE * sizeof(int),(void *) A[0]);cl::Buffer bBuffer cl::Buffer(context,CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,BUFFER_SIZE * sizeof(int),(void *) B[0]);cl::Buffer cBuffer cl::Buffer(context,CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,BUFFER_SIZE * sizeof(int),(void *) C[0]);利用cl::Kernel()调用创建内核对象 cl::Kernel kernel(program, vadd);执行矢量相加内核 既然已经创建了内核和内存对象矢量相加程序终于可以将内核人队等待执行了。内核函数的所有参数都要使用cl::Kernel:setArg()方法来设置。根据C API中的clSetKernelArg()这个函数的第一个参数是内核函数参数索引。vadd()内核有3个参数a、b和c)分别对应索引0、1和2。将之前创建的内存对象传入这个内核对象 kernel.setArg(0, aBuffer); kernel.setArg(1, bBuffer); kernel.setArg(2, cBuffer);与以往一样设置内核参数之后矢量相加示例使用命令队列将内核入队等待在设备上执行。这是通过调用cl::CommandQueue::enqueueNDRangeKernel()完成的。全局和局部工作大小使用cl::Range()传递。 对于局部工作大小使用cl::Range()对象的一个特殊实例cl::NullRange顾名思义它对应于C API中传递NULL允许运行时为设备确定最佳的工作组大小和请求的全局工作大小。 queue.enqueueNDRangeKernel(kernel,cl::NullRange,cl::NDRange(BUFFER_SIZE),cl::NullRange);将内核入队等待执行并不意味着内核会立即执行。可以使用cl::CommandQueue::flush()或cl::CommandQueue::finish()强制提交到设备立即执行。不过由于这个矢量相加示例只是要显示结果所以它使用了一个阻塞的cl::CommandQueue::enqueueMapBuffer()将输出缓冲区映射到一个宿主机指针 int * output (int *)queue.enqueueMapBuffere(cBuffer,CL_TRUE, //blockCL_MAP_READ,0,BUFFER_SIZE * sizeof(int));宿主机应用程序再处理output 指向的数据一旦完成必须用cl::CommandQueue::enqueueUnmapMemObj()调用释放映射的内存 err queue.enqueueUnmapMemObject(cBuffer,(void *)output);代码示例 #define __CL_ENABLE_EXCEPTIONS#include CL/cl.hpp#include cstdio #include cstdlib #include iostream#define BUFFER_SIZE 20int A[BUFFER_SIZE]; int B[BUFFER_SIZE]; int C[BUFFER_SIZE];static char kernelSourceCode[] kernel void \n vadd(global int * a, __global int * b, __global int * c) \n { \nsize_t i get_global_id(0); \n\nc[i] a[i] b[i]; \n } \n ;int main(void) {cl_int err;// Initialize A, B, Cfor (int i 0; i BUFFER_SIZE; i) {A[i] i;B[i] i * 2;C[i] 0;}try {std::vectorcl::Platform platformList;// Pick platformcl::Platform::get(platformList);// Pick first platformcl_context_properties cprops[] {CL_CONTEXT_PLATFORM, (cl_context_properties)(platformList[0])(), 0 };cl::Context context(CL_DEVICE_TYPE_GPU, cprops);// Query the set of devices attched to the contextstd::vectorcl::Device devices context.getInfoCL_CONTEXT_DEVICES();// Create and program from sourcecl::Program::Sources sources(1, std::make_pair(kernelSourceCode, 0));cl::Program program(context, sources);// Build programprogram.build(devices);// Create buffer for A and copy host contentscl::Buffer aBuffer cl::Buffer(context,CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,BUFFER_SIZE * sizeof(int),(void*)A[0]);// Create buffer for B and copy host contentscl::Buffer bBuffer cl::Buffer(context,CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR,BUFFER_SIZE * sizeof(int),(void*)B[0]);// Create buffer for that uses the host ptr Ccl::Buffer cBuffer cl::Buffer(context,CL_MEM_WRITE_ONLY | CL_MEM_USE_HOST_PTR,BUFFER_SIZE * sizeof(int),(void)C[0]);// Create kernel objectcl::Kernel kernel(program, vadd);// Set kernel argskernel.setArg(0, aBuffer);kernel.setArg(1, bBuffer);kernel.setArg(2, cBuffer);// Create command queuecl::CommandQueue queue(context, devices[0], 0);// Do the workqueue.enqueueNDRangeKernel(kernel,cl::NullRange,cl::NDRange(BUFFER_SIZE),cl::NullRange);// Map cBuffer to host pointer. This enforces a sync with // the host backing space, remember we choose GPU device.int output (int*)queue.enqueueMapBuffer(cBuffer,CL_TRUE, // block CL_MAP_READ,0,BUFFER_SIZE * sizeof(int));for (int i 0; i BUFFER_SIZE; i) {std::cout C[i] ;}std::cout std::endl;// Finally release our hold on accessing the memoryerr queue.enqueueUnmapMemObject(cBuffer,(void*)output);// There is no need to perform a finish on the final unmap// or release any objects as this all happens implicitly with// the C Wrapper API.}catch (cl::Error err) {std::cerr ERROR: err.what() ( err.err() ) std::endl;return EXIT_FAILURE;}return EXIT_SUCCESS; }
- 上一篇: 河南网站建设yijuce江苏专业网站制作
- 下一篇: 河南网站建设价格与方案wordpress阅读时间
相关文章
-
河南网站建设yijuce江苏专业网站制作
河南网站建设yijuce江苏专业网站制作
- 技术栈
- 2026年03月21日
-
河南网站建设yijuce关于市场营销的案例
河南网站建设yijuce关于市场营销的案例
- 技术栈
- 2026年03月21日
-
河南网站公司自助建站平台便宜
河南网站公司自助建站平台便宜
- 技术栈
- 2026年03月21日
-
河南网站建设价格与方案wordpress阅读时间
河南网站建设价格与方案wordpress阅读时间
- 技术栈
- 2026年03月21日
-
河南网站建设哪家有网页设计师证书考试内容
河南网站建设哪家有网页设计师证书考试内容
- 技术栈
- 2026年03月21日
-
河南网站建设运营域名注册公司虹口网站建设
河南网站建设运营域名注册公司虹口网站建设
- 技术栈
- 2026年03月21日
