Windows下opencl环境配置

转自:http://blog.sina.com.cn/s/blog_735f29100101fsky.html

首先声明我这篇主要是根据下面网站的介绍, 加以修改和详细描述,一步一步在我自己的电脑上实现的,

首先要将显卡驱动更新到最新版,以支持opencl 。要看显卡支不支持opencl,可以下一个 GPU_Caps_Viewer_Setup 软件看一看

首先要下载安装opencl库。我这里下载的是英特尔的。英伟达和AMD的也都差不多。
首先下载INTEL版的opencl驱动:
直接安装即可。
然后下载intel版本的opencl开发工具包
我这里默认安装到  G:\Program Files\Intel\OpenCL SDK  目录下。
安装完成后   G:\ProgramFiles\Intel\OpenCL SDK\3.0   目录下出现以下文档( include和lib等
Windows下opencl环境配置

安装好VC 2012
Alt+F7进行属性设置,或者建完项目后右键项目进行属性设置。
新建Win控制台空项目。右键进行属性设置。

在属性页里面找到“C/C++”的“常规”项,点击,右边有“附加包含目录”,然后编辑,添加目录:
Windows下opencl环境配置



.在属性页里面找到“连接器”,点击其“常规”项,右边有“附加库目录”,然后也是编辑,添加目录:
Windows下opencl环境配置

 在输入选项只用,右边“附加依赖项”,编辑,添加lib文件:OpenCL.lib
Windows下opencl环境配置

这里要注意一点,如果你用的是64位的系统的话,如果你把OpenCL.lib 的目录指定为....../ /lib/x64的话,很很可能还是不能正常编译。这是因为
A fresh install of Visual Studio (even 2010) uses 32-bit bydefault, so unless you've explicitly set your project to be 64-bit(in configuration manager -> platform -> x64) it will be32-bit.  
所以说如果编译不能正常通过的话试着把 OpenCL.lib 的目录指定为....../ /lib/x86 或者 ....../ /lib/Win32试试。
但是目录还是C:\Program Files   不是C:\ProgramFiles(x86)

比如如果用NVDIA 的CUDA可以这样设定目录
C:\Program Files\NVIDIA GPUComputing Toolkit\CUDA\v7.0\lib\Win32



然后添加源文件,源文件如下:

  #include
  #include //包含CL的头文件
  using namespace std;
 
  //根据参数,判断设备类别。是CPU、GPU、ACCELERATOR或其他设备
  const char* GetDeviceType(cl_device_typeit)
  {
      if(it== CL_DEVICE_TYPE_CPU)
          return "CPU";
      elseif(it== CL_DEVICE_TYPE_GPU)
          return "GPU";
      elseif(it==CL_DEVICE_TYPE_ACCELERATOR)
          return "ACCELERATOR";
      else
          return "DEFAULT";
   
  }
   
  int main()
  {
      chardname[512];
      cl_device_id devices[20];
      cl_platform_id* platform_id = NULL;
      cl_uint num_devices;
      cl_device_type int_type;
      cl_ulong long_entries;
      cl_uint num_platform;
      cl_interr;
   
      //查询系统上可用的计算平台,可以理解为初始化
      err =clGetPlatformIDs(0,NULL,&num_platform);
   
      if(err!=CL_SUCCESS)
      {
          cout<<"clGetPlatformIDserror"<<endl;
          return 0;
      }
   
      cout<<"PlatFormnum:"<<num_platform<<endl;
   
    unsigned int st=0;
   
      platform_id = newcl_platform_id[num_platform];
   
      err =clGetPlatformIDs(num_platform,platform_id,NULL);
   
      if(err!=CL_SUCCESS)
      {
          cout<<"clGetPlatformIDserror"<<endl;
          return 0;
      }
   
 
for(st=0;st
      {
          cout<<endl<<"----------------------------------"<<endl;
          cout<<"Platform"<<st+1<<endl;
   
          //获取可用计算平台的名称
          clGetPlatformInfo(platform_id[st],CL_PLATFORM_NAME,512,dname,NULL);
          cout<<"CL_PLATFORM_NAME:"<<dname<<endl;
   
          //获取可用计算平台的版本号,即OpenCL的版本号
          clGetPlatformInfo(platform_id[st],CL_PLATFORM_VENDOR,512,dname,NULL);
          cout<<"CL_PLATFORM_VERSION:"<<dname<<endl;
   
          //获取可用计算平台的设备数目
          clGetDeviceIDs(platform_id[st],CL_DEVICE_TYPE_ALL,20,devices,&num_devices);
          cout<<"Devicenum:"<<num_devices<<endl<<endl;
   
          unsigned int n=0;
   
          //循环两次,检测两个设备的属性
          for(n=0;n
          {
              cout<<endl<<"Device"<<n+1<<endl;
              //获取设备名称
              clGetDeviceInfo(devices[n],CL_DEVICE_NAME,512,dname,NULL);
              cout<<"Device:"<<dname<<endl;
   
              //获取设备类别
              clGetDeviceInfo(devices[n],CL_DEVICE_TYPE,sizeof(cl_device_type),&int_type,NULL);
              cout<<"DeviceType:"<<GetDeviceType(int_type)<<endl;
   
              //获取设备版本号
              clGetDeviceInfo(devices[n],CL_DRIVER_VERSION,512,dname,NULL);
              cout<<"Deviceversion:"<<dname<<endl;
   
              //获取设备全局内存大小
              clGetDeviceInfo(devices[n],CL_DEVICE_GLOBAL_MEM_SIZE,sizeof(cl_ulong),&long_entries,NULL);
              cout<<"Device globalmem(MB):"<<long_entries/1024/1024<<endl;
   
              //获取设备CACHE内存大小
              clGetDeviceInfo(devices[n],CL_DEVICE_GLOBAL_MEM_CACHE_SIZE,sizeof(cl_ulong),&long_entries,NULL);
              cout<<"Device global memcache(KB):"<<long_entries/1024<<endl;
   
              //获取本地内存大小
              clGetDeviceInfo(devices[n],CL_DEVICE_LOCAL_MEM_SIZE,sizeof(cl_ulong),&long_entries,NULL);
              cout<<"Device Locale mem(KB):"<<long_entries/1024<<endl;
   
              //获取设备频率
              clGetDeviceInfo(devices[n],CL_DEVICE_MAX_CLOCK_FREQUENCY,sizeof(cl_ulong),&long_entries,NULL);
              cout<<"Device Max clock(MHz):"<<long_entries<<endl;
   
              //获取最大工作组数
              clGetDeviceInfo(devices[n],CL_DEVICE_MAX_WORK_GROUP_SIZE,sizeof(cl_ulong),&long_entries,NULL);
              cout<<"Device Max Group size:"<<long_entries<<endl;
   
              //获取最大计算核心数
              clGetDeviceInfo(devices[n],CL_DEVICE_MAX_COMPUTE_UNITS,sizeof(cl_ulong),&long_entries,NULL);
              cout<<"Device Max parallelcores:"<<long_entries<<endl;
   
          }
      }
   
      return0;
  }

以上程序是检测当前计算机的可用计算平台的相关信息,运行结果如下。
Windows下opencl环境配置

提示复制本代码,编译后若发现提示:  检测到 Mac 文件格式: 请将源文件转换为 DOS 格式或UNIX 格式, 则 在VS中,点文件->高级保存选项,然后在行尾选项中选择windows(CRLF),重新编译,ok。
还有在查找替换时,在查找选项中启用 正则表达式选项 ,注意windows下的换行符是 /n而不是\n 


opencl编码流程

摘自opencl异构计算:

  (1)初始化opencl 平台(调用两次clGetPlatformIDs函数)

                  第一次获取可用的平台数量,第二次获取一个可用的平台。

(2) 选择设备(调用两次clGetDeviceIDs函数)

                 第一次获取可用的设备数量,第二次获取一个可用的设备。

(3)创建上下文(调用clCreateContext函数)

Context:环境上下文,一个Context包含几个device(单个Cpu或GPU),一个Context就是这些device的一个联系纽带,只有在一个Context上的那些Device才能彼此交流工作,你的机器上可以同时存在很多Context。你可以用一个CPu创建context,也可以用一个CPU和一个GPU创建一个。

(4)创建命令队列(调用clCreateCommandQueue函数)

(5)创建数据缓冲区(调用clCreateBuffer函数)

(6)将 host数据写进设备缓冲区(调用clEnqueueWriteBuffer函数)

(7)创建程序对象(调用clCreateProgramWithSource函数)并编译内核源码(调用clBuildProgram函数,如果编译成功,则把编译代码存储在程序对象中

(8)创建kernel(调用clCreateKernel函数)

(9)设置内核参数(调用clSetKernelArg函数)

(10)Configure the work-itemstructure(设置worksize)//只在分组的时候用到,只调用全局id的时候不要设置

(11)内核入队执行(调用clEnqueueNDRangeKernel函数)

(12)取回计算结果。Read  the output buffer back to thehost(调用clEnqueueReadBuffer函数)

(13)Release OpenCL resources(至此结束整个运行过程)

中间有很多地方需要结合实际情况进行设定。


  //step 1:初始化OpenCL

    err =clGetPlatformIDs(1,&platform_id,NULL);

 

   if(err!=CL_SUCCESS)

    {

       cout<<"clGetPlatformIDserror"<<endl;

       return 0;

    }

 

    step2:创建上下文。这次我们只用CPU来进行并行运算,当然你也可以该成GPU

   clGetDeviceIDs(platform_id,CL_DEVICE_TYPE_CPU,1,&device,NULL);

 

    //step3:创建上下文

    context =clCreateContext(NULL,1,&device,NULL,NULL,NULL);

 

    //step4:创建命令队列

    cmdQueue =clCreateCommandQueue(context,device,0,NULL);

 

    //step5:创建数据缓冲区,即创建内存对象,内存对象分配在设备内存中,可以有内核函数直接调用

    bufferA =clCreateBuffer(context,

                        CL_MEM_READ_ONLY,

                        datasize,NULL,NULL);

 

    bufferB =clCreateBuffer(context,

                        CL_MEM_READ_ONLY,

                        datasize,NULL,NULL);

 

    //step6:将数据上传到缓冲区,注意这里只传A,相当于赋值,B 是结果,不需要初始化了

   clEnqueueWriteBuffer(cmdQueue,

                     bufferA,CL_FALSE,

                     0,datasize,

                     buf_A,0,

                     NULL,NULL);

 

 

 

    //step7:由内核源代码创建程序对象.

 

    program =clCreateProgramWithSource(context,1,

                                  (constchar**)&buf_code,

                                  NULL,NULL);

 

   

//调用clBuildProgram函数,编译内核源代码。如果编译成功,则把编译代码存储在程序对象中

clBuildProgram(program,1,&device,NULL,NULL,NULL);

   

//step 8:创建内核对象

    kernel =clCreateKernel(program,"transposition",NULL);


    //step9:设置参数,执行内核

   clSetKernelArg(kernel,0,sizeof(cl_mem),&bufferA);

   clSetKernelArg(kernel,1,sizeof(cl_mem),&bufferB);

 

    //step10:内核入队执行。注意这里第三个参数已经改成2,表示二维数据。

 clEnqueueNDRangeKernel(cmdQueue,kernel,

                       2,NULL,

                       globalWorkSize,

                      NULL,0,NULL,NULL); 

   //step11:取回计算结果

   clEnqueueReadBuffer(cmdQueue,bufferB,CL_TRUE,0,

                    datasize,buf_B,0,NULL,NULL);

 

    //输出计算结果

   for(n=0;n

    {

       for(m=0;m

       {

          cout<< buf_A[m][n] <<",";

       }

       cout<<endl;

    }

 

   cout<<endl<<"====transposition===="<<endl<<endl;

 

   for(n=0;n

    {

       for(m=0;m

       {

          cout<< buf_B[m][n] <<",";

       }

       cout<<endl;

    }

 

    //step12:释放所有调用和内存

 

   clReleaseKernel(kernel);

   clReleaseProgram(program);

   clReleaseCommandQueue(cmdQueue);

   clReleaseMemObject(bufferA);

   clReleaseMemObject(bufferB);

   clReleaseContext(context);

 

    deletebuf_code;

   return 0;

  • 0
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值