2014年5月8日 星期四

OpenCL: Query Device Info

since: 2014/05/08
update: 2014/05/08

reference:
1. Amazon.com: OpenCL Programming by Example
2. I touchs: OpenCL: Query Platforms Info

A. 說明
     本篇文章以 OpenCL: Query Platforms Info 所建的專案為主, 來進行功能的修改.

---------------------------------------------------------------------------------------------

B. 幫專案新增檔案
     1. 在專案的 Utility 群組裡, 新增檔案:
          QueryDeviceInfo.h
QueryDeviceInfo.cpph

     2. 專案結構如下:


---------------------------------------------------------------------------------------------

C. 撰寫程式碼
     1. 開啓 QueryDeviceInfo.h 檔案, 修改如下
/*
#ifndef __HelloOpenCL__QueryDeviceInfo__
#define __HelloOpenCL__QueryDeviceInfo__

#include <iostream>

#endif

*/

//@add
#include "OpenCLHeader.h"

void PrintDeviceInfo(cl_device_id device);


**********************************************************************

     2. 開啓 QueryDeviceInfo.cpp 檔案, 修改如下
#include "QueryDeviceInfo.h"

void PrintDeviceInfo(cl_device_id device)
{
    char queryBuffer[1024];
    int queryInt;
    cl_int clError;
    cl_device_type dev_type;
    size_t ret_size;
    cl_uint entries;
    cl_bool bool_entries;
   
    // Get DEVICE_TYPE
    clError = clGetDeviceInfo(device, CL_DEVICE_TYPE, sizeof(dev_type), &dev_type, &ret_size);
    printf("Device Type: ");
    if(dev_type & CL_DEVICE_TYPE_GPU) printf("CL_DEVICE_TYPE_GPU ");
    if(dev_type & CL_DEVICE_TYPE_CPU) printf("CL_DEVICE_TYPE_CPU ");
    if(dev_type & CL_DEVICE_TYPE_ACCELERATOR) printf("CL_DEVICE_TYPE_ACCELERATOR ");
    if(dev_type & CL_DEVICE_TYPE_DEFAULT) printf("CL_DEVICE_TYPE_DEFAULT ");
    printf("\n");
   
    // Get DEVICE_NAME
    clError = clGetDeviceInfo(device, CL_DEVICE_NAME, sizeof(queryBuffer), &queryBuffer, NULL);
    printf("CL_DEVICE_NAME: %s\n", queryBuffer);
    queryBuffer[0] = '\0';
   
    // Get DEVICE_VENDOR
    clError = clGetDeviceInfo(device, CL_DEVICE_VENDOR, sizeof(queryBuffer), &queryBuffer, NULL);
    printf("CL_DEVICE_VENDOR: %s\n", queryBuffer);
    queryBuffer[0] = '\0';
   
    // Get DRIVER_VERSION
    clError = clGetDeviceInfo(device, CL_DRIVER_VERSION, sizeof(queryBuffer), &queryBuffer, NULL);
    printf("CL_DRIVER_VERSION: %s\n", queryBuffer);
    queryBuffer[0] = '\0';
   
    // Get DEVICE_VERSION
    clError = clGetDeviceInfo(device, CL_DEVICE_VERSION, sizeof(queryBuffer), &queryBuffer, NULL);
    printf("CL_DEVICE_VERSION: %s\n", queryBuffer);
    queryBuffer[0] = '\0';
   
    // Get DEVICE_MAX_COMPUTE_UNITS
    clError = clGetDeviceInfo(device, CL_DEVICE_MAX_COMPUTE_UNITS, sizeof(int), &queryInt, NULL);
    printf("CL_DEVICE_MAX_COMPUTE_UNITS: %d\n", queryInt);
   
    // Get DEVICE_MAX_CLOCK_FREQUENCY
    clError = clGetDeviceInfo(device, CL_DEVICE_MAX_CLOCK_FREQUENCY, sizeof(cl_uint), &entries, &ret_size);
    printf("CL_DEVICE_MAX_CLOCK_FREQUENCY(Mhz): %d\n", entries);
   
    // Get DEVICE_IMAGE_SUPPORT
    clError = clGetDeviceInfo(device, CL_DEVICE_IMAGE_SUPPORT, sizeof(cl_bool), &bool_entries, &ret_size);
    printf("Image Support: ");
    if(bool_entries == true) printf("True");
    if(bool_entries == false) printf("False");
    printf("\n");
}


**********************************************************************

     3. 開啓 main.cpp 檔案, 修改如下
#include "QueryDeviceInfo.h"

int main(int argc, const char * argv[])
{
    cl_int           clError;
    cl_platform_id *platforms = NULL;
    cl_uint          num_platforms = 0;
   
    // 第一次呼叫 clGetPlatformIDs, 得到 num_platforms 的值
    clError = clGetPlatformIDs(0, NULL, &num_platforms);
    if(clError != CL_SUCCESS)
    {
        printf("Error in call to clGetPlatformIDs (first) ....\n Exiting");
        exit(0);
    }
   
    printf("Number of OpenCL platforms available in the system: %d\n", num_platforms);
   
    // 再次呼叫 clGetPlatformIDs, 得到 platforms 的值
    platforms = (cl_platform_id *)malloc(sizeof(cl_platform_id)*num_platforms);
    clError = clGetPlatformIDs(num_platforms, platforms, NULL);
    if(clError != CL_SUCCESS)
    {
        free(platforms);
        printf("Error in call to clGetPlatformIDs (second) ....\n Exiting");
        exit(0);
    }

    if (num_platforms == 0)
    {
        free(platforms);
        printf("No OpenCL Platforms Found ....\n Exiting");
        exit(0);
    }
   
    // We have obtained platforms here.
    // Lets enumerate the devices available in this Platform.

    for (cl_uint idx = 0; idx < num_platforms; idx++)
    {
        cl_device_id    *devices;
        cl_uint          num_devices;
        printf("\nPrinting OpenCL Device Info For Platform ID : %d\n\n", idx);
       
        // 第一次呼叫 clGetDeviceIDs, 得到 num_devices 的值
        clError = clGetDeviceIDs (platforms[idx], CL_DEVICE_TYPE_ALL, 0, NULL, &num_devices);
        if (clError != CL_SUCCESS)
        {
            printf("Error Getting number of devices (first) ... Exiting\n ");
            exit(0);
        }

        // If successfull the num_devices contains the number of devices available in the platform
        // Now lets get all the device list. Before that we need to malloc devices
        // 再次呼叫 clGetPlatformIDs, 得到 devices 的值

        devices = (cl_device_id *)malloc(sizeof(cl_device_id) * num_devices);
        clError = clGetDeviceIDs (platforms[idx], CL_DEVICE_TYPE_ALL, num_devices, devices, &num_devices);
        if (clError != CL_SUCCESS)
        {
            free(devices);
            printf("Error Getting number of devices (second) ... Exiting\n ");
            exit(0);
        }
       
        for (cl_uint dIndex = 0; dIndex < num_devices; dIndex++)
        {
            printf("==================Device No %d======================\n",dIndex);
            PrintDeviceInfo(devices[dIndex]);
            printf("====================================================\n\n");
        }
       
        free(devices);
    }
   
    return 0;
}


---------------------------------------------------------------------------------------------

D. 執行結果