首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Windows下opencl环境配置

Windows下opencl环境配置

首先要下载安装opencl库。我这里下载的是英特尔的。英伟达和AMD的也都差不多。


首先下载INTEL版的opencl驱动:

https://software.intel.com/en-us/articles/opencl-drivers


直接安装即可。


然后下载intel版本的opencl开发工具包
https://software.intel.com/en-us/vcsource/tools/opencl-sdk
我这里默认安装到  G:\Program Files\Intel\OpenCL SDK  目录下。
安装完成后  G:\Program Files\Intel\OpenCL SDK\3.0  目录下出现以下文档 (include和lib等)



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


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





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



在输入选项只用,右边“附加依赖项”,编辑,添加lib文件:OpenCL.lib



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

#include
#include //包含CL的头文件
using namespace std;

//根据参数,判断设备类别。是CPU、GPU、ACCELERATOR或其他设备
const char* GetDeviceType(cl_device_type it)
{


if(it == CL_DEVICE_TYPE_CPU)




return "CPU";


else if(it== CL_DEVICE_TYPE_GPU)




return "GPU";


else if(it==CL_DEVICE_TYPE_ACCELERATOR)




return "ACCELERATOR";


else




return "DEFAULT";
  
}
  
int main()
{


char dname[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_int err;
  


//查询系统上可用的计算平台,可以理解为初始化


err = clGetPlatformIDs(0,NULL,&num_platform);
  


if(err!=CL_SUCCESS)


{




cout<<"clGetPlatformIDs error"<<endl;




return 0;


}
  


cout<<"PlatForm num:"<<num_platform<<endl;
  


unsigned int st=0;
  


platform_id = new cl_platform_id[num_platform];
  


err = clGetPlatformIDs(num_platform,platform_id,NULL);
  


if(err!=CL_SUCCESS)


{




cout<<"clGetPlatformIDs error"<<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<<"Device num:"<<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<<"Device Type:"<<GetDeviceType(int_type)<<endl;
  






//获取设备版本号






clGetDeviceInfo(devices[n],CL_DRIVER_VERSION,512,dname,NULL);






cout<<"Device version:"<<dname<<endl;
  






//获取设备全局内存大小






clGetDeviceInfo(devices[n],CL_DEVICE_GLOBAL_MEM_SIZE,sizeof(cl_ulong),&long_entries,NULL);






cout<<"Device global mem(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 mem cache(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 parallel cores:"<<long_entries<<endl;
  




}


}
  


return 0;
}




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




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


opencl编码流程
摘自opencl异构计算:

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

(2) 选择设备(调用两次clGetDeviceIDs函数)
(3)创建上下文(调用clCreateContext函数)
(4)创建命令队列(调用clCreateCommandQueue函数)
(5)创建数据缓冲区(调用clCreateBuffer函数)
(6)将 host数据写进设备缓冲区(调用clEnqueueWriteBuffer函数)
(7)创建程序对象(调用clCreateProgramWithSource函数)并编译内核源码(调用clBuildProgram函数,如果编译成功,则把编译代码存储在程序对象中
(8)创建kernel(调用clCreateKernel函数)
(9)设置内核参数(调用clSetKernelArg函数)
(10)Configure the work-item structure(设置worksize)//只在分组的时候用到,只调用全局id的时候不要设置
(11)内核入队执行(调用clEnqueueNDRangeKernel函数)
(12)取回计算结果。Read  the output buffer back to the host(调用clEnqueueReadBuffer函数)
(13)Release OpenCL resources(至此结束整个运行过程)
中间有很多地方需要结合实际情况进行设定。


//step 1:初始化OpenCL



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




if(err!=CL_SUCCESS)



{





cout<<"clGetPlatformIDs error"<<endl;





return 0;



}




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



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




//step 3:创建上下文



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




//step 4:创建命令队列



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




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



bufferA = clCreateBuffer(context,















CL_MEM_READ_ONLY,















datasize,NULL,NULL);




bufferB = clCreateBuffer(context,















CL_MEM_READ_ONLY,















datasize,NULL,NULL);




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



clEnqueueWriteBuffer(cmdQueue,













bufferA,CL_FALSE,













0,datasize,













buf_A,0,













NULL,NULL);






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




program = clCreateProgramWithSource(context,1,





















(const char**)&buf_code,





















NULL,NULL);




//调用clBuildProgram函数,编译内核源代码。如果编译成功,则把编译代码存储在程序对象中
clBuildProgram(program,1,&device,NULL,NULL,NULL);

  

//step 8:创建内核对象


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





//step 9:设置参数,执行内核



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



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




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


clEnqueueNDRangeKernel(cmdQueue,kernel,














2,NULL,














globalWorkSize,














NULL,0,NULL,NULL);


//step 11:取回计算结果



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;



}




//step 12:释放所有调用和内存




clReleaseKernel(kernel);



clReleaseProgram(program);



clReleaseCommandQueue(cmdQueue);



clReleaseMemObject(bufferA);



clReleaseMemObject(bufferB);



clReleaseContext(context);




delete buf_code;


  
return 0;

返回列表