//創建平臺對象
status = clGetPlatformIDs( 1, &platform, NULL );
注意:上式是選擇默許的第1個平臺。如果我們系統中安裝不止1個opencl平臺,如何選擇自己需要的平臺? 比如我現在安裝了intel和NVIDIA平臺。那末我們就需要進行1個選擇判斷。第1次調用是獲得平臺的數量,numPlatforms里面存的就是平臺的數量。第2個是獲得可用的平臺。另外,我也沒有增加毛病檢測之類的代碼,但是我增加了1個 status 的變量,通常如果函數履行正確,返回的值是 0。
/*Step1: Getting platforms and choose an available one.*/
cl_uint numPlatforms; //the NO. of platforms
cl_platform_id platform = NULL; //the chosen platform
cl_int status = clGetPlatformIDs(0, NULL, &numPlatforms);
if (status != CL_SUCCESS)
{
cout << "Error: Getting platforms!" << endl;
return FAILURE;
}
/*For clarity, choose the first available platform. */
if(numPlatforms > 0)
{
cl_platform_id* platforms = (cl_platform_id* )malloc(numPlatforms* sizeof(cl_platform_id));
status = clGetPlatformIDs(numPlatforms, platforms, NULL);
platform = platforms[0];
free(platforms);
}
詢問裝備名稱,并選擇1個。
/*Step 2:Query the platform and choose the first GPU device if has one.Otherwise use the CPU as device.*/
cl_uint numDevices = 0;
cl_device_id *devices;
status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, 0, NULL, &numDevices);
if (numDevices == 0) //no GPU available.
{
cout << "No GPU device available." << endl;
cout << "Choose CPU as default device." << endl;
status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, 0, NULL, &numDevices);
devices = (cl_device_id*)malloc(numDevices * sizeof(cl_device_id));
status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_CPU, numDevices, devices, NULL);
}
else
{
devices = (cl_device_id*)malloc(numDevices * sizeof(cl_device_id));
status = clGetDeviceIDs(platform, CL_DEVICE_TYPE_GPU, numDevices, devices, NULL);
}
下面我們來看下 OpenCL 中 Context 的概念。通常,Context 是指管理 OpenCL 對象和資源的上下文環境。為了管理 OpenCL 程序,下面的1些對象都要和 Context 關聯起來:
? 裝備(Devices): 履行 Kernel 程序對象。
? 程序對象(Program objects): kernel 程序源代碼
? Kernels: 運行在 OpenCL 裝備上的函數
? 內存對象(Memory objects): 裝備上寄存數據
? 命令隊列(Command queues): 裝備的交互機制
? 內存命令(Memory commands)(用于在主機內存和裝備內存之間拷貝數據)
? Kernel 履行(Kernel execution)
? 同步(Synchronization)
注意:創建1個 Context 的時候,我們必須把1個或多個裝備和它關聯起來。對其它的 OpenCL 資源,它們創建時候,也要和 Context 關聯起來,1般創建這些資源的 OpenCL 函數的輸入參數中,都會有 context。
/*Step 3: Create context.*/
cl_context context = clCreateContext(NULL,1, devices,NULL,NULL,NULL);
接下來,我們要看下命令隊列。在 OpenCL 中,命令隊列就是主機的要求,在裝備上履行的1種機制。
在 Kernel 履行前,我們1般要進行1些內存拷貝的工作,比如把主機內存中的數據傳輸到裝備內存中。
另外要注意的幾點就是:對不同的裝備,它們都有自己的獨立的命令隊列;命令隊列中的命令 (kernel 函數)多是同步的,也多是異步的,它們的履行順序可以是有序的,也能夠是亂序的。
命令隊列在 device 和 context 之間建立了1個連接。
命令隊列 properties 指定1下內容:
? 是不是亂序履行(在 AMD GPU 中,好像現在還不支持亂序履行)
? 是不是啟動 profiling。 Profiling 通過事件機制來得到 kernel 履行時間等有用的信息,但它本身也會有1些開消。
/*Step 4: Creating command queue associate with the context.*/
cl_command_queue commandQueue = clCreateCommandQueue(context, devices[0], 0, NULL);
clCreateProgramWithSource()這個函數通過源代碼 (strings),創建1個程序對象,其中 counts 指定源代碼串的數量,lengths 指定源代碼串的長度(為 NULL 結束的串時,可以省略)。固然,我們還必須自己編寫1個從文件中讀取源代碼串的函數。
/*Step 5: Create program object */
const char *filename = "Vadd.cl";
string sourceStr;
status = convertToString(filename, sourceStr);
const char *source = sourceStr.c_str();
size_t sourceSize[] = {strlen(source)};
cl_program program = clCreateProgramWithSource(context, 1, &source, sourceSize, NULL);
//從文件中讀取源代碼串的函數
/* convert the kernel file into a string */
int convertToString(const char *filename, std::string& s)
{
size_t size;
char* str;
std::fstream f(filename, (std::fstream::in | std::fstream::binary));
if(f.is_open())
{
size_t fileSize;
f.seekg(0, std::fstream::end);
size = fileSize = (size_t)f.tellg();
f.seekg(0, std::fstream::beg);
str = new char[size+1];
if(!str)
{
f.close();
return 0;
}
f.read(str, fileSize);
f.close();
str[size] = '
主站蜘蛛池模板:
中国一级片在线观看
|
国产精品91一区二区三区
|
欧美国产另类
|
蜜臀av网站
|
国产一区免费在线观看
|
国产区一区|
一区二区三区在线免费视频
|
夜夜摸夜夜操
|
国产91精品久久久久久久网曝门
|
久久久午夜精品
|
久久精品不卡
|
97人人超碰
|
亚洲高清网站
|
www日韩|
日产av在线免费观看
|
久久久久99精品国产片
|
av大全在线免费观看
|
色乱码一区二区三区网站
|
麻豆国产在线
|
在线免费观看污
|
国产一级黄色影片
|
91网站在线看
|
国产精品国产三级国产aⅴ浪潮
|
加勒比在线免费视频
|
亚洲www啪成人一区二区麻豆
|
色网站免费
|
日本色一区
|
亚洲精品视频二区
|
国产精品99久久久久久动医院
|
黄色片一级免费看
|
亚洲高清成人
|
久久免费视频1
|
国产精品综合网
|
亚洲国产不卡
|
久久久久亚洲精品
|
中文字幕一区二区三区在线观看
|
在线欧美一区
|
亚洲h片|
亚洲91视频
|
日韩精品在线观看视频
|
国产日韩欧美在线
|