本文基于NVIDIA GPU和VS2019讲解如何配置OpenCL环境和快速上手编程。

文章目录

  • 1.OpenCL安装在VS2019 上
    • 1.安装资源准备
    • 2.安装步骤
  • 2.OpenCL 快速入门
    • 1.原文和翻译
    • 2.代码改动和调试
  • 3.测试通过的代码

1.OpenCL安装在VS2019 上

1.安装资源准备

从NVIDIA 官网下载CUDA 并双击运行安装程序:

https://developer.nvidia.com/cuda-downloads?target_os=Windows&target_arch=x86_64&target_version=7&target_type=exelocal

然后在安装路径找到以下资源:
1 .\lib\x64\OpenCL.lib
OpenCL.lib
2.CL 头文件

CL 头文件
3.在显卡的默认驱动路径找到
OpenCL64.dll
在这里插入图片描述OpenCL64.dll

2.安装步骤

新建OpenCL_inc 和OpenCL_lib 目录。将上一步找到的资源分别复制到这两个目录。
其中OpenCL_inc 用来包含CL 头文件,OpenCL_lib 目录用来包含OpenCL.lib以及OpenCL.dll,OpenCL64.dll。

VS2019 环境配置:
1.
项目–> (项目名)属性 -->C/C+±->常规 -->附加包含目录 --> F:\OPENCL\code\OpenCL_inc
2.
项目–> (项目名)属性 -->连接器 --> 常规 --> 附加库目录 --> F:\OPENCL\code\OpenCL_lib
3.
项目–> (项目名)属性 -->连接器 -->输入–> 附加依赖项 --> OpenCL.lib

2.OpenCL 快速入门

1.原文和翻译

原文地址
参考翻译

2.代码改动和调试

尝试将vector_add_gpu.cl kernel文件直接以字符串的方式放在代码中,然后在kernel编译(即执行 clBuildProgram)后再获取PROGRAM SOURCE:

error = clGetProgramInfo(program, CL_PROGRAM_SOURCE, bufSize, programBuffer, &program_size_ret);

发现这样不使用.cl 文件也时可行的。但是需要注意的是将编译后的字符串打印出来时buffer长度需要+1。

3.测试通过的代码

#include <iostream>
#include <string>//#include <oclUtils.h>
#include "CL\opencl.h"
#include <time.h>
#include <windows.h>using namespace std;
string getPlatformName(const cl_platform_id pid) {size_t param_value_size;clGetPlatformInfo(pid, CL_PLATFORM_NAME, 0, NULL, &param_value_size);char* param_value = new char[param_value_size];clGetPlatformInfo(pid, CL_PLATFORM_NAME, param_value_size, param_value, NULL);return param_value;
}size_t shrRoundUp(size_t localWorkSize, size_t numItems) {size_t result = localWorkSize;while (result < numItems)result += localWorkSize;return result;
}void vector_add_cpu(const float* const src_a,const float* const src_b,float* const res,const int size)
{for (int i = 0; i < size; i++) {res[i] = src_a[i] + src_b[i];}
}int main() {cl_uint num_platforms;cl_int error = 0;cl_context context;cl_command_queue queue;cl_device_id device;cl_platform_id platformNvidia;// PlatformclGetPlatformIDs(0, NULL, &num_platforms);cl_platform_id* platforms = new cl_platform_id[num_platforms];clGetPlatformIDs(num_platforms, platforms, NULL);for (cl_uint i = 0; i < num_platforms; i++) {string platname = getPlatformName(platforms[i]);cout << "<" << i << "> " << "Platform name is :" << platname << endl;}platformNvidia = platforms[1];string platname1 = getPlatformName(platformNvidia);cout << "<" << platname1 << "> " << "choose Platform 1 :" << platname1 << endl;//Devicecl_uint num_devices;error = clGetDeviceIDs(platformNvidia, CL_DEVICE_TYPE_GPU, 1, &device, &num_devices);if (error != CL_SUCCESS) {cout << "Error getting device ids: " << error << endl;exit(error);}cout << "num of devices is : "<< num_devices << endl;//contextcontext = clCreateContext(0, 1, &device, NULL, NULL, &error);if (error != CL_SUCCESS) {cout << "Error creating context: " << error << endl;exit(error);}// Command-queuequeue = clCreateCommandQueue(context, device, 0, &error);if (error != CL_SUCCESS) {cout << "Error creating command queue: " << error << endl;exit(error);}///memoryconst int size = 123456;float* src_a_h = new float[size];float* src_b_h = new float[size];float* res_h = new float[size];//cl_mem_ion_host_ptr ion_src_a;// init vectorsfor (int i = 0; i < size; i++){src_a_h[i] = src_b_h[i] = (float) i;}const int mem_size = sizeof(float) * size;//allocate device buffercl_mem src_a_d = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, mem_size, src_a_h, &error );cl_mem src_b_d = clCreateBuffer(context, CL_MEM_READ_ONLY | CL_MEM_COPY_HOST_PTR, mem_size, src_b_h, &error );cl_mem res_d = clCreateBuffer(context, CL_MEM_WRITE_ONLY, mem_size, NULL, &error);// create the programconst char* programSource ="__kernel void vector_add_gpu(__global const float* src_a, ""    __global const float* src_b, ""   __global float* res, ""   const int num)         \n                                           ""{ \n                                                                   "" /* get_global_id(0) 返回正在执行的这个线程的ID。      \n              ""   许多线程会在同一时间开始执行同一个kernel,             \n             "" 每个线程都会收到一个不同的ID,所以必然会执行一个不同的计算。*/   \n   ""    const int idx = get_global_id(0);                                 \n  ""                                                                      \n ""    /* 每个work-item都会检查自己的id是否在向量数组的区间内。           \n ""   如果在,work-item就会执行相应的计算。*/                            \n "" if (idx < num)                                                     \n ""       res[idx] = src_a[idx] + src_b[idx];                      \n  "" }                                                                    \n  ";printf("programSource\n %s \n", programSource);cl_program program = clCreateProgramWithSource(context, 1, reinterpret_cast<const char**>(&programSource), NULL, &error);if (error != CL_SUCCESS) {cout << "Error creating program: " << error << endl;exit(error);}//builds the programerror = clBuildProgram(program, 1, &device, NULL, NULL, NULL);if (error != CL_SUCCESS) {cout << "Error Build program: " << error << endl;exit(error);}// check the kernel codesize_t bufSize = strlen(programSource) +1;         //为什么大一个字节char* programBuffer = (char*)malloc(bufSize);size_t program_size_ret;error = clGetProgramInfo(program, CL_PROGRAM_SOURCE, bufSize, programBuffer, &program_size_ret);if (error != CL_SUCCESS){cout << "Error clGetProgramInfo:" << error << endl;}printf("  program_size_ret %ld\n", program_size_ret);printf("bufSize = %ld  \n", bufSize);printf("Print Program Source:\n");printf("\n %s \n", programBuffer);// shows the logchar* build_log;size_t log_size;// 1st get the log_sizeclGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, 0, NULL, &log_size);build_log = new char[log_size + 1];cout << log_size << "log_size" << endl;//2nd get logclGetProgramBuildInfo(program, device, CL_PROGRAM_BUILD_LOG, log_size, build_log, NULL);build_log[log_size] = '\0';cout << build_log <<"build log" <<endl;delete[] build_log;//extacting the kernelcl_kernel vector_add_k = clCreateKernel(program, "vector_add_gpu", &error);if (error != CL_SUCCESS) {cout << "Error extacting the kernel: " << error << endl;exit(error);}// Enqueuing parameterserror = clSetKernelArg(vector_add_k, 0, sizeof(cl_mem), &src_a_d);if (error != CL_SUCCESS){cout << "Error Enqueuing 0 parameters:" << error << endl;}error |= clSetKernelArg(vector_add_k, 1, sizeof(cl_mem), &src_b_d);if (error != CL_SUCCESS){cout << "Error Enqueuing 1 parameters:" << error << endl;}error |= clSetKernelArg(vector_add_k, 2, sizeof(cl_mem), &res_d);if (error != CL_SUCCESS){cout << "Error Enqueuing 2 parameters:" << error << endl;}error |= clSetKernelArg(vector_add_k, 3, sizeof(int), &size);if (error != CL_SUCCESS){cout << "Error Enqueuing 3 parameters:" << error << endl;}//launching the kernelconst size_t local_ws = 512;  // Number of work-items per work-groupconst size_t global_ws = shrRoundUp(local_ws, size);ULONGLONG t1 = GetTickCount64();error = clEnqueueNDRangeKernel(queue, vector_add_k, 1, NULL, &global_ws, &local_ws, 0, NULL, NULL);ULONGLONG t2 = GetTickCount64();cout << "GPU cost time :" << (t2 - t1) <<endl;if (error != CL_SUCCESS){cout << "Error Enqueuing EnqueueNDRangeKernel:" << error << endl;}float* check = new float[size];clEnqueueReadBuffer(queue, res_d, CL_TRUE, 0, mem_size, check, 0, NULL, NULL);// Checking with the CPU results;ULONGLONG t3 = GetTickCount64();vector_add_cpu(src_a_h, src_b_h, res_h, size);   ULONGLONG t4 = GetTickCount64();cout << "CPU cost time :" << (t4 - t3) << endl;for (int i = 0; i < size; i++){if (check[i] != res_h[i]){printf("calc ERROR GPU value is %f CPU value is %f  \n", check[i], res_h[i]);}}cout << "Congratulations, it's working! \n" << endl;// Cleaning updelete[] src_a_h;delete[] src_b_h;delete[] res_h;delete[] check;clReleaseKernel(vector_add_k);clReleaseCommandQueue(queue);clReleaseContext(context);clReleaseMemObject(src_a_d);clReleaseMemObject(src_b_d);clReleaseMemObject(res_d);return 0;
}

VS2019 OpenCL安装和快速入门相关推荐

  1. Tushare介绍、安装及快速入门

    Tushare介绍.安装及快速入门 Tushare是一个免费.开源的python财经数据接口包.主要实现对股票等金融数据从数据采集.清洗加工 到 数据存储的过程,能够为金融分析人员提供快速.整洁.和多 ...

  2. Python测试框架pytest(01)简介、安装、快速入门

    1.简介 pytest 是成熟的功能齐全的 Python 测试工具,可帮助你编写更好的程序. pytest 是一个使构建简单和可伸缩的测试变得容易的框架.测试具有表达性和可读性,不需要样板代码.几分钟 ...

  3. Kafka 安装及快速入门

    转载请注明原创地址为:http://www.54tianzhisheng.cn/2018/01/04/Kafka/ 介绍 官网:http://kafka.apache.org/ Apache Kafk ...

  4. 001-ant design安装及快速入门【基于纯antd的基本项目搭建】

    一.安装使用 1.1.安装 推荐使用 npm 或 yarn 的方式进行开发 npm install antd --save yarn add antd 1.2.浏览器引入 在浏览器中使用 script ...

  5. Docker快速安装与快速入门

    一.软件版本 操作系统:Centos 7.0 二.开始安装: http://www.daocloud.io/ 由于国内的源比较卡,所以我们推荐使用daocloud的方式,注册安装即可: [root@l ...

  6. 第二节:简易安装 和 快速入门Vue.js

    上一节我们介绍了Vue.js框架,这一节,我们可以来试着动手写点小代码了. 1 简易安装 要使用Vue.js,我们得先把它安装到我们的项目中,说明了简易安装,我们讲解的肯定是最简单的方法,先不管那些高 ...

  7. selenium安装_Selenium快速入门知识1-环境安装

    Selenium可以通过Python开发,也可以通过Java.JavaScript等各种语言进行开发,本节仅对Python进行讲解. 如前面所属Selenium3.X对于2.X而言一个最基本的变化在于 ...

  8. 3D绘图程序库Pangolin安装以及快速入门,使用教程介绍详细,使用Pangolin绘制点云、直线、轨迹等,设置按钮,进行多窗口、多线程操作,以及Pangolin怎么使用等等

    1. Pangolin介绍 常见的3D绘图的程序库有很多,MATLAB.Python的Matplotlib.OpenGL.在Linux上常用的一个3D绘图库是Pangolin,它是基于OpenGL完成 ...

  9. Istio1.12:安装和快速入门

    前言 Istio 使用功能强大的 Envoy 服务代理扩展了 Kubernetes,以建立一个可编程的.可感知的应用程序网络.Istio 与 Kubernetes 和传统工作负载一起使用,为复杂的部署 ...

  10. dubbo+zookeeper安装及快速入门

    环境安装 zookeeper 下载地址:(https://zookeeper.apache.org/doc/r3.4.14/) 1.运行apache-zookeeper-3.5.6-bin\bin\z ...

最新文章

  1. 阿里云服务器ECS Ubuntu16.04 初次使用配置教程(图形界面安装)
  2. ASP.NET.4.5.1+MVC5.0系统角色和权限讲解
  3. Oracle Dg 重建,DG Failover之后原主库恢复成standby重建加入DG
  4. pyhton3 os模块
  5. ubuntu修改mysql的绑定端口
  6. 2016年,我的和自己谈谈
  7. 仿IOS应用APP下载页源码
  8. 为制造业构建Teams Power App 2:创建客户UI
  9. CocoaPods安装以及遇到的坑
  10. 以太坊Solidity发布0.8.3版本
  11. sql out apply_在SQL Server中CROSS APPLY和OUTER APPLY之间的区别
  12. pyjion python3.6_Pyjion的代码质量一例 [20160221]
  13. opengl es坐标变换2
  14. 如何高效,安全,稳定的管理多个亚马逊,facebook,google等帐号? 如何配合使用VMlogin防关联,反指纹浏览器操作,同时多开多个帐号?911 S5 多端口转发如何设置?
  15. 在火狐浏览器打开xpath_Firefox火狐插件firebug和xpath checker提取关键词
  16. 抗体链接InP/ZnS量子点|量子点InP/ZnS表面修饰抗体偶联服务-齐岳生物
  17. SkeyeVSS综合安防Onvif、RTSP、GB28181视频云服务H5无插件直播点播卡顿的解决方案
  18. 10019---【Java并发之】BlockingQueue
  19. 基于微信小程序的租车小程序 毕业设计毕业论文 开题报告和效果图(基于微信小程序毕业设计题目选题课题)
  20. Docker的常用命令大全

热门文章

  1. css如何把图片设置成梯形,css实现梯形
  2. 相亲交友小程序制作方案
  3. 【系统】VMware虚拟机安装黑苹果系统macOS 12.5详细步骤
  4. linux操作系统原理【3】
  5. 制作多媒体网页html代码,Director制作多媒体网页
  6. Visual Studio 2008系列教程(一):VS 2008安装详解!
  7. hua图软件 mac_sai mac中文版|sai绘画软件 For Mac下载 v3.0 官方版 - 121苹果网
  8. 蚂蚁课堂:lombok
  9. 通信原理第六章思维导图
  10. 自定义封装无人值守Windows10镜像