生活随笔
收集整理的這篇文章主要介紹了
详细程序注解学OpenCL一 环境配置和入门程序
小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
本專欄是通過注解程序的方法學(xué)習(xí)OpenCL,我覺得一個(gè)一個(gè)地去摳原理也不是辦法,干脆直接學(xué)習(xí)程序,然后把相關(guān)原理都直接注解到程序語句當(dāng)中。
原創(chuàng)地址:http://blog.csdn.net/kenden23/article/details/14101657
一開始要配置好環(huán)境,我的是nvidia,所以就按照我的電腦舉例,AMD應(yīng)該也差不多。
1. 首先要到nvidia網(wǎng)站下載適合你顯卡的最新驅(qū)動(dòng),安裝好
2. 還是在nvidia網(wǎng)站下載好CUDA開發(fā)包,安裝好
3. 如果默認(rèn)安裝路徑的話,路徑應(yīng)該是在:C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.0
4. 打開這個(gè)目錄會(huì)發(fā)現(xiàn)里面有include和lib文件夾,這就是我們需要配置在visual studio中的文件
5. 打開visual studio(版本基本都無關(guān)系,我用的是vs2012),新建一個(gè)win32空項(xiàng)目。按下alt+F7打開項(xiàng)目屬性,也可以點(diǎn)擊項(xiàng)目文件右鍵,選擇屬性。
6. 在屬性頁里面找到“C/C++”的“常規(guī)”項(xiàng),點(diǎn)擊,右邊有“附加包含目錄”,然后編輯,添加目錄:C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.0\include
7.在屬性頁里面找到“連接器”,點(diǎn)擊其“常規(guī)”項(xiàng),右邊有“附加庫目錄”,然后也是編輯,添加目錄:C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.0\lib\Win32,如果是64位系統(tǒng)可以是:C:\Program Files\NVIDIA GPU Computing Toolkit\CUDA\v5.0\lib\x64。
8. 在屬性頁里找到“常規(guī)”項(xiàng), 右邊“附加依賴項(xiàng)”,編輯,添加lib文件:OpenCL.lib
9. 然后就可以新建源文件,在源文件里面添加相關(guān)的OpenCl程序,就可以調(diào)試OpenCL程序了。
下面就可以開始學(xué)習(xí)程序了。
下面是個(gè)入門程序,已經(jīng)注釋好了,注釋包括了基本原理的解析,可以通過直接閱讀和調(diào)試程序?qū)W習(xí)OpenCL了。
本程序是讀取電腦中的支持OpenCL的硬件nvidia和intel和AMD等信息,然后顯示在屏幕上。
[cpp] view plaincopyprint?
#include?<stdio.h>??#include?<stdlib.h>??#include?<string.h>??#include?<iostream>????#ifdef?MAC??#include?<OpenCL/cl.h>??#else??#include?<CL/cl.h>??#endif????int?main()?{??????????????cl_platform_id?*platforms;????????????cl_uint?num_platforms;??????cl_int?i,?err,?platform_index?=?-1;??????????????char*?ext_data;???????????????????????????????size_t?ext_size;?????????const?char?icd_ext[]?=?"cl_khr_icd";????????????????????????????????????????err?=?clGetPlatformIDs(5,?NULL,?&num_platforms);??????????????if(err?<?0)?{??????????????????perror("Couldn't?find?any?platforms.");???????????????????exit(1);??????????????????????????????????}???????????????????????????????????????????printf("I?have?platforms:?%d\n",?num_platforms);?????????????????????platforms?=?(cl_platform_id*)?????????????????????????????malloc(sizeof(cl_platform_id)?*?num_platforms);?????????????clGetPlatformIDs(num_platforms,?platforms,?NULL);?????????????????????????????????for(i=0;?i<num_platforms;?i++)???????{??????????????????????????????err?=?clGetPlatformInfo(platforms[i],?????????????????????????CL_PLATFORM_EXTENSIONS,?0,?NULL,?&ext_size);??????????????if(err?<?0)???????????{??????????????perror("Couldn't?read?extension?data.");??????????????????????????exit(1);??????????}???????????????printf("The?size?of?extension?data?is:?%d\n",?ext_size);??????????????????????????????????ext_data?=?(char*)malloc(ext_size);?????????????????????clGetPlatformInfo(platforms[i],?CL_PLATFORM_EXTENSIONS,???????????????????ext_size,?ext_data,?NULL);????????????????????????printf("Platform?%d?supports?extensions:?%s\n",?i,?ext_data);??????????????????????char?*name?=?(char*)malloc(ext_size);??????????clGetPlatformInfo(platforms[i],?CL_PLATFORM_NAME,?????????????????ext_size,?name,?NULL);????????????????????????printf("Platform?%d?name:?%s\n",?i,?name);??????????????????????char?*vendor?=?(char*)malloc(ext_size);??????????clGetPlatformInfo(platforms[i],?CL_PLATFORM_VENDOR,???????????????????ext_size,?vendor,?NULL);??????????????????????????printf("Platform?%d?vendor:?%s\n",?i,?vendor);??????????????????????char?*version?=?(char*)malloc(ext_size);??????????clGetPlatformInfo(platforms[i],?CL_PLATFORM_VERSION,??????????????????ext_size,?version,?NULL);?????????????????????????printf("Platform?%d?version:?%s\n",?i,?version);??????????????????????char?*profile?=?(char*)malloc(ext_size);??????????clGetPlatformInfo(platforms[i],?CL_PLATFORM_PROFILE,??????????????????ext_size,?profile,?NULL);?????????????????????????printf("Platform?%d?full?profile?or?embeded?profile?:?%s\n",?i,?profile);???????????????????????????????????if(strstr(ext_data,?icd_ext)?!=?NULL)???????????????platform_index?=?i;??????????std::cout<<"Platform_index?=?"<<platform_index<<std::endl;????????????????????if(platform_index?>?-1)??????????????printf("Platform?%d?supports?the?%s?extension.\n",???????????????platform_index,?icd_ext);????????????std::cout<<std::endl;??????????????????????free(ext_data);??????????free(name);??????????free(vendor);??????????free(version);??????????free(profile);??????}????????????????if(platform_index?<=?-1)??????????printf("No?platforms?support?the?%s?extension.\n",?icd_ext);??????????????free(platforms);??????return?0;??}???
每個(gè)電腦的輸出結(jié)果不一樣的,我電腦的輸出結(jié)果是:
OpenCL 查看設(shè)備信息
下面是注釋程序,目的就是查看自己計(jì)算機(jī)上所有支持OpenCL的設(shè)備,并打印信息。
主函數(shù)調(diào)用run()就可以運(yùn)行了。要設(shè)置請(qǐng)看我另一篇OpenCl設(shè)置文章。
[cpp] view plaincopyprint?
#include?<stdio.h>??#include?<stdlib.h>??#include?<string.h>????#ifdef?MAC??#include?<OpenCL/cl.h>??#else??#include?<CL/cl.h>??#endif????namespace?device_ext_test??{????int?run()?{????????????cl_platform_id?*platforms;??????cl_device_id?*devices;??????cl_uint?num_platforms;??????cl_uint?num_devices,?addr_data;??????cl_int?i,?err;??????????????char?name_data[48],?ext_data[4096];????????err?=?clGetPlatformIDs(5,?NULL,?&num_platforms);??????????????if(err?<?0)?{??????????????????perror("Couldn't?find?any?platforms.");???????????????????exit(1);??????????????????????????????????}??????????????platforms?=?(cl_platform_id*)?????????????????????????????malloc(sizeof(cl_platform_id)?*?num_platforms);??????err?=?clGetPlatformIDs(num_platforms,?platforms,?NULL);???????????????if(err?<?0)?{??????????????????????perror("Couldn't?find?any?platforms");??????????exit(1);??????}????????????????????????for?(int?j?=?0;?j?<?(int)num_platforms;?j++)??????{??????????printf("\nplatform?%d\n",?j+1);????????????????????err?=?clGetDeviceIDs(platforms[j],?CL_DEVICE_TYPE_ALL,?1,?NULL,?&num_devices);??????????if(err?<?0)?{??????????????????????????????perror("Couldn't?find?any?devices");??????????????exit(1);??????????}??????????????????????devices?=?(cl_device_id*)?????????????????????????????????malloc(sizeof(cl_device_id)?*?num_devices);???????????????clGetDeviceIDs(platforms[j],?CL_DEVICE_TYPE_ALL,??????????????????????????num_devices,?devices,?NULL);??????????????????????????????????????for(i=0;?i<(int)num_devices;?i++)?{????????????????err?=?clGetDeviceInfo(devices[i],?CL_DEVICE_NAME,?????????????????????????sizeof(name_data),?name_data,?NULL);??????????????????????????if(err?<?0)?{??????????????????????????perror("Couldn't?read?extension?data");??????????????????exit(1);??????????????}??????????????clGetDeviceInfo(devices[i],?CL_DEVICE_ADDRESS_BITS,???????????????????????sizeof(ext_data),?&addr_data,?NULL);????????????????????????????clGetDeviceInfo(devices[i],?CL_DEVICE_EXTENSIONS,?????????????????????????sizeof(ext_data),?ext_data,?NULL);??????????????????????????printf("NAME:?%s\nADDRESS_WIDTH:?%u\nEXTENSIONS:?%s\n\n",???????????????????name_data,?addr_data,?ext_data);??????????}??????}????????free(platforms);??????free(devices);??????printf("\n");??????system("pause");??????return?0;??}??????}??
OpenCL 操作context
本程序主要測(cè)試:
context = clCreateContext(NULL, 1, &device, NULL, NULL, &err);
創(chuàng)建一個(gè)context
clRetainContext(context);//Context的reference +1
clReleaseContext(context);//Context的reference -1
[cpp] view plaincopyprint?
#include?<stdio.h>??#include?<stdlib.h>??#include?<string.h>????#ifdef?MAC??#include?<OpenCL/cl.h>??#else??#include?<CL/cl.h>??#endif????namespace?context_count??{????int?run()???{??????cl_platform_id?platform;??????cl_device_id?device;??????cl_context?context;??????cl_int?err;??????cl_uint?ref_count;????????err?=?clGetPlatformIDs(1,?&platform,?NULL);??????if(err?<?0)?{??????????perror("Couldn't?find?any?platforms");??????????exit(1);??????}????????err?=?clGetDeviceIDs(platform,?CL_DEVICE_TYPE_GPU,?1,?&device,?NULL);??????if(err?==?CL_DEVICE_NOT_FOUND)?{??????????err?=?clGetDeviceIDs(platform,?CL_DEVICE_TYPE_CPU,?1,?&device,?NULL);??????}??????if(err?<?0)?{??????????perror("Couldn't?find?any?devices");??????????exit(1);??????}??????????????context?=?clCreateContext(NULL,?1,?&device,?NULL,?NULL,?&err);??????if(err?<?0)?{??????????perror("Couldn't?create?a?context");??????????exit(1);?????????}??????????????err?=?clGetContextInfo(context,?CL_CONTEXT_REFERENCE_COUNT,???????????????sizeof(ref_count),?&ref_count,?NULL);?????????????????if(err?<?0)?{??????????????????perror("Couldn't?read?the?reference?count.");??????????exit(1);??????}??????printf("Initial?reference?count:?%u\n",?ref_count);??????????????clRetainContext(context);clRetainContext(context);????????????????????????????clGetContextInfo(context,?CL_CONTEXT_REFERENCE_COUNT,?????????????????sizeof(ref_count),?&ref_count,?NULL);?????????????????printf("Reference?count:?%u\n",?ref_count);?????????????????clReleaseContext(context);????????????????????????????clGetContextInfo(context,?CL_CONTEXT_REFERENCE_COUNT,?????????????????sizeof(ref_count),?&ref_count,?NULL);?????????????????printf("Reference?count:?%u\n",?ref_count);?????????????????clReleaseContext(context);clReleaseContext(context);??????????system("pause");??????return?0;??}????}??
OpenCL 獲取Program信息
本程序生成一個(gè)OpenCL Program,然后獲取Program的source,其實(shí)它的source就是一個(gè)char[],可以打印出來。
然后我們把這些內(nèi)容和原來文本的內(nèi)容對(duì)比,看看是否是我們想要讀入的內(nèi)容。
還可以測(cè)試是否編譯正確,如果不正確會(huì)有輸出提示的。
下面程序運(yùn)行如下:
前面都是讀入的函數(shù)代碼。然后后面檢查這些函數(shù)是否正確,可以看到第二個(gè)函數(shù)不正確,因?yàn)?r沒有定義。
下面是完整代碼:
[cpp] view plaincopyprint?
#define?_CRT_SECURE_NO_WARNINGS????#include?<stdio.h>??#include?<stdlib.h>??#include?<sys/types.h>????#ifdef?MAC??#include?<OpenCL/cl.h>??#else??#include?<CL/cl.h>??#endif????namespace?program_build??{????const?static?int?NUM_FILES?=?2;??const?char?PROGRAM_FILE_1[]?=?"good.cl";??const?char?*PROGRAM_FILE_2?=?"bad.cl";????int?run()??{???????????????cl_platform_id?platform;??????cl_device_id?device;??????cl_context?context;??????cl_int?i,?err;??????????????cl_program?program;??????FILE?*program_handle;??????char?*program_buffer[NUM_FILES];??????char?*program_log;??????const?char?*file_name[]?=?{PROGRAM_FILE_1,?PROGRAM_FILE_2};??????const?char?options[]?=?"-cl-finite-math-only?-cl-no-signed-zeros";????????size_t?program_size[NUM_FILES];??????size_t?log_size;??????????????err?=?clGetPlatformIDs(1,?&platform,?NULL);??????if(err?<?0)?{??????????perror("Couldn't?find?any?platforms");??????????exit(1);??????}??????????????err?=?clGetDeviceIDs(platform,?CL_DEVICE_TYPE_GPU,?1,?&device,?NULL);??????if(err?==?CL_DEVICE_NOT_FOUND)?{??????????err?=?clGetDeviceIDs(platform,?CL_DEVICE_TYPE_CPU,?1,?&device,?NULL);??????}??????if(err?<?0)?{??????????perror("Couldn't?find?any?devices");??????????exit(1);??????}??????????????context?=?clCreateContext(NULL,?1,?&device,?NULL,?NULL,?&err);??????if(err?<?0)?{??????????perror("Couldn't?create?a?context");??????????exit(1);?????????}??????????????for(i=0;?i<NUM_FILES;?i++)?{????????????program_handle?=?fopen(file_name[i],?"r");??????????if(program_handle?==?NULL)?{??????????????perror("Couldn't?find?the?program?file");??????????????exit(1);?????????????}??????????fseek(program_handle,?0,?SEEK_END);??????????program_size[i]?=?ftell(program_handle);??????????rewind(program_handle);??????????program_buffer[i]?=?(char*)malloc(program_size[i]+1);??????????program_buffer[i][program_size[i]]?=?'\0';??????????fread(program_buffer[i],?sizeof(char),?program_size[i],???????????????program_handle);??????????fclose(program_handle);??????}??????????????program?=?clCreateProgramWithSource(context,?NUM_FILES,???????????????????????(const?char**)program_buffer,?program_size,?&err);????????????????????if(err?<?0)?{??????????perror("Couldn't?create?the?program");??????????exit(1);?????????}??????????????????err?=?clBuildProgram(program,?1,?&device,?options,?NULL,?NULL);?????????int?bufSize?=?program_size[0]?+?program_size[1]?+?1;??????char?*programBuffer?=?(char?*)?malloc(bufSize);??????clGetProgramInfo(program,?CL_PROGRAM_SOURCE,?bufSize,?programBuffer,?NULL);??????printf("Print?Program?Source:\n");??????printf("\n?%s?\n",?programBuffer);?????????printf("Check?if?it?is?correct:\n");??????for?(int?i?=?0;?i?<?NUM_FILES;?i++)??????{??????????printf("\n?%s?\n",?program_buffer[i]);??????}????????if(err?<?0)???????{??????????clGetProgramBuildInfo(program,?device,?CL_PROGRAM_BUILD_LOG,???????????????0,?NULL,?&log_size);??????????program_log?=?(char*)?malloc(log_size+1);??????????program_log[log_size]?=?'\0';??????????clGetProgramBuildInfo(program,?device,?CL_PROGRAM_BUILD_LOG,???????????????log_size+1,?program_log,?NULL);??????????printf("%s\n",?program_log);??????????free(program_log);??????????system("pause");??????????exit(1);??????}??????????????for(i=0;?i<NUM_FILES;?i++)?{??????????free(program_buffer[i]);??????}??????clReleaseProgram(program);??????clReleaseContext(context);??????system("pause");????????return?0;??}????}?
總結(jié)
以上是生活随笔為你收集整理的详细程序注解学OpenCL一 环境配置和入门程序的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。