Computer Vision2014. 3. 31. 19:28

디바이스 별로 고유한 확장 기능을 부여할 수 있다.

이런 기능이 추가되어 있는지 확인을 한다.


추가되는 함수는 아래에 표시되어 있다.


void displayDeviceInfo( cl_platform_id id ,

                        cl_device_type dev_type)

......

        displayDeviceDetails( devices[i], CL_DEVICE_EXTENSIONS"CL_DEVICE_EXTENSIONS" );

.....



void displayDeviceDetails( cl_device_id id,

                            cl_device_info param_name,

                            const char * paramNameAsStr)

...

    

    switch(param_name)

    {

       ......

            break;

        case CL_DEVICE_EXTENSIONS : {

            // beware of buffer overflow; alternatively use the OpenCL C++ bindings

            char* extension_info[4096];

            error = clGetDeviceInfo( id, CL_DEVICE_EXTENSIONSsizeof(extension_info), 

extension_info, NULL);

            printf("\tSupported extensions: %s\n", extension_info);

        }break;

  }

....


확장에 대한 정보를 확인하기 위해서 CL_DEVICE_EXTENSONS를 확인하면 된다.

세부 정보에서 해당 정보를 프린트하도록 한다.


완성된 코드와 실행 결과는 아래와 같다.




//

//  main.cpp

//  TestOpenCL

//

//  Created by freegear on 2014. 2. 8..

//  Copyright (c) 2014 freegear. All rights reserved.

//


#include <iostream>


#include <stdio.h>

#include <stdlib.h>



#ifdef __APPLE__

#   include <OpenCL/opencl.h>

#else

#   include <CL/cl.h>

#endif


//Function proto type

void displayDeviceDetails(cl_device_id id ,

                          cl_device_info param_name,

                          const char * paramNameAsStr);


void displayDeviceInfo( cl_platform_id id ,

                        cl_device_type dev_type)

{

    /* OpenCL 1.1 device type */

    

    cl_int error = 0 ;

    cl_uint numOfDevices = 0 ;

    

    /* Determine how many devices are connected to your platform */

    error = clGetDeviceIDs(id, dev_type, 0, NULL, &numOfDevices);

    

    if( error != CL_SUCCESS){

        perror("Unable to obtain any OpenCL compliant device info");

        exit(1);

    }

    

    cl_device_id * devices = (cl_device_id*)alloca(sizeof(cl_device_id) * numOfDevices);

    

    /* Load the information about your devices into the variable 'devices' */

    

    error = clGetDeviceIDs(id, dev_type, numOfDevices, devices, NULL);

    

    if (error != CL_SUCCESS)

    {

        perror("Unable to obtain any OpenCL compliant device info");

        exit(1);

    }

    

    printf("Numnber of detected OpenCL devices %d\n", numOfDevices);

    

    /* we attempt to retrieve some information about the devices */

    for( int i = 0 ; i < numOfDevices ; ++i)

    {

        displayDeviceDetails(devices[i], CL_DEVICE_TYPE, "CL_DEVICE_TYPE");

        displayDeviceDetails(devices[i], CL_DEVICE_VENDOR_ID, "CL_DEVICE_VENDOR_ID");

        displayDeviceDetails(devices[i], CL_DEVICE_MAX_COMPUTE_UNITS, "CL_DEVICE_MAX_COMPUTE_UNITS");

        displayDeviceDetails(devices[i], CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, "CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS");

        displayDeviceDetails(devices[i], CL_DEVICE_MAX_WORK_ITEM_SIZES, "CL_DEVICE_MAX_WORK_ITEM_SIZES");

        displayDeviceDetails(devices[i], CL_DEVICE_MAX_WORK_GROUP_SIZE, "CL_DEVICE_MAX_WORK_GROUP_SIZE");

        displayDeviceDetails( devices[i], CL_DEVICE_EXTENSIONS, "CL_DEVICE_EXTENSIONS" );

    }

}


void displayDeviceDetails( cl_device_id id,

                            cl_device_info param_name,

                            const char * paramNameAsStr)

{

    cl_int error = 0 ;

    size_t paramSize = 0 ;

    

    error = clGetDeviceInfo( id ,param_name, 0 , NULL, &paramSize);

    if(error != CL_SUCCESS)

    {

        perror("Unable to obtain device info for param");

        return;

    }

    

    /* 

     The cl_device_info are preporcessor directives define in cl.h

     */

    

    switch(param_name)

    {

        case CL_DEVICE_TYPE :

        {

            cl_device_type * devType  = (cl_device_type*)alloca(sizeof(cl_device_type)*paramSize);

            error = clGetDeviceInfo(id, param_name, paramSize, devType, NULL);

            

            if(error != CL_SUCCESS)

            {

                perror("Unable to optain device info for param\n");

                return;

            }

            

            switch( *devType)

            {

                case CL_DEVICE_TYPE_CPU : printf("CPU Detected \n"); break;

                case CL_DEVICE_TYPE_GPU : printf("GPU Detected \n"); break;

                case CL_DEVICE_TYPE_ACCELERATOR : printf("Accelerator detected\n");break;

                case CL_DEVICE_TYPE_DEFAULT : printf("default detected \n"); break;

            }

            break;

        }

        case CL_DEVICE_VENDOR_ID :

        case CL_DEVICE_MAX_COMPUTE_UNITS :

        case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS : {

            

                cl_uint* ret = (cl_uint*) alloca(sizeof(cl_uint) * paramSize);

                error = clGetDeviceInfo( id, param_name, paramSize, ret, NULL );

            

                if (error != CL_SUCCESS ) {

                    perror("Unable to obtain device info for param\n");

                    return;

                }

            

                switch (param_name) {

                    case CL_DEVICE_VENDOR_ID: printf("\tVENDOR ID: 0x%x\n", *ret); break;

                    case CL_DEVICE_MAX_COMPUTE_UNITS: printf("\tMaximum number of parallel compute units: %d\n", *ret); break;

                    case CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS: printf("\tMaximum dimensions for global/local work-item IDs: %d\n", *ret); break;

                }

            }

            break;

      

        case CL_DEVICE_MAX_WORK_ITEM_SIZES :

            {

                cl_uint maxWIDimensions;

                size_t* ret = (size_t*) alloca(sizeof(size_t) * paramSize);

                error = clGetDeviceInfo( id, param_name, paramSize, ret, NULL );

            

                error = clGetDeviceInfo( id, CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS, sizeof(cl_uint), &maxWIDimensions, NULL );

                if (error != CL_SUCCESS ) {

                    perror("Unable to obtain device info for param\n");

                    return;

                }

                printf("\tMaximum number of work-items in each dimension: ( ");

                for(cl_int i =0; i < maxWIDimensions; ++i ) {

                    printf("%d ", (int)ret[i]);

                }

                printf(" )\n");

            }break;

        

        case CL_DEVICE_MAX_WORK_GROUP_SIZE :

            {

                size_t* ret = (size_t*) alloca(sizeof(size_t) * paramSize);

                error = clGetDeviceInfo( id, param_name, paramSize, ret, NULL );

                if (error != CL_SUCCESS ) {

                    perror("Unable to obtain device info for param\n");

                    return;

                }

                printf("\tMaximum number of work-items in a work-group: %d\n", (int)*ret);

            }

            break;

        case CL_DEVICE_NAME :

        case CL_DEVICE_VENDOR :

            {

                char data[48];

                error = clGetDeviceInfo( id, param_name, paramSize, data, NULL );

                if (error != CL_SUCCESS ) {

                    perror("Unable to obtain device name/vendor info for param\n");

                    return;

                }

                switch (param_name) {

                    case CL_DEVICE_NAME : printf("\tDevice name is %s\n", data);break;

                    case CL_DEVICE_VENDOR : printf("\tDevice vendor is %s\n", data);break;

                }

            }

            break;

        case CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE: {

            cl_uint* size = (cl_uint*) alloca(sizeof(cl_uint) * paramSize);

            error = clGetDeviceInfo( id, param_name, paramSize, size, NULL );

            if (error != CL_SUCCESS ) {

                perror("Unable to obtain device name/vendor info for param\n");

                return;

            }

            printf("\tDevice global cacheline size: %d bytes\n", (*size)); break;

        } break;

            

        case CL_DEVICE_GLOBAL_MEM_SIZE:

        case CL_DEVICE_MAX_MEM_ALLOC_SIZE:

            {

                cl_ulong* size = (cl_ulong*) alloca(sizeof(cl_ulong) * paramSize);

                error = clGetDeviceInfo( id, param_name, paramSize, size, NULL );

                if (error != CL_SUCCESS ) {

                    perror("Unable to obtain device name/vendor info for param\n");

                    return;

                }

                switch (param_name) {

                    case CL_DEVICE_GLOBAL_MEM_SIZE: printf("\tDevice global mem: %ld mega-bytes\n", (*size)>>20); break;

                    case CL_DEVICE_MAX_MEM_ALLOC_SIZE: printf("\tDevice max memory allocation: %ld mega-bytes\n", (*size)>>20); break;

                }

            }

            break;

        case CL_DEVICE_EXTENSIONS : {

            // beware of buffer overflow; alternatively use the OpenCL C++ bindings

            char* extension_info[4096];

            error = clGetDeviceInfo( id, CL_DEVICE_EXTENSIONS, sizeof(extension_info), extension_info, NULL);

            printf("\tSupported extensions: %s\n", extension_info);

        }break;

    }//end of switch(param_name

    

    

}// end of displayDeviceDetailes


void displayPlatformInfo(

                         cl_platform_id id ,

                         cl_platform_info param_name,

                         const char * paramNameAsStr

                         )

{

    

    cl_int error = 0 ;

    size_t paramSize = 0 ;

    

    

    error = clGetPlatformInfo(

                              id,

                              param_name,

                              0,

                              NULL,

                              &paramSize

                              );

    

    char * moreInfo = (char *) alloca(sizeof(char)*paramSize);

    

    error = clGetPlatformInfo(

                              id, /* The platform ID returned by clGetPlatformIDs or can be NULL. 

                                     If platform is NULL, the behavior is implementation-defined.*/

                              param_name, /* An enumeration constant that identifies the platform 

                                             information being queried. It can be one of the following values 

                                             as specified in the table below. */

                              paramSize,  /* Specifies the size in bytes of memory pointed to by param_value. 

                                             This size in bytes must be greater than or equal to size of return type

                                             specified in the table below. */

                              moreInfo,   /* A pointer to memory location where appropriate values for a given 

                                             param_value will be returned. Acceptable param_value values are listed in 

                                             the table below. If param_value is NULL, it is ignored.*/

                              NULL        /* Returns the actual size in bytes of data being queried by param_value. 

                                             If param_value_size_ret is NULL, it is ignored */

                              );

    

    if( error != CL_SUCCESS)

    {

        if ( error == CL_INVALID_PLATFORM)

            perror("Error CL_INVALID_PLATFORM");

        else if (error == CL_INVALID_VALUE)

            perror("Error CL_INVALID_VALUE");

        else

            perror("Unable to find any OpenCL platform information");

        return ;

    }

    

    printf("%s : %s\n" , paramNameAsStr, moreInfo);

    

} // end of displayPlatformInfo




int main(int argc, const char * argv[])

{


    

    // OpenCL 1.2 Data struction

    cl_platform_id * platforms ;

    

    /* OpenCL 1.1 scalar data types */

    cl_uint numOfPlatforms ;

    cl_int  error ;

    

    /* 

        Get the number of platforms

        Remember that for each vendor's SDK installed on the computer,

        the number of available platform also increased.

    */

    

    

    error = clGetPlatformIDs(0, /*

                                 The number of cl_platform_id entries that can be added to platforms.

                                 If platforms is not NULL, the num_entries must be greater than zero. 

                                 */

                             NULL, /* Returns a list of OpenCL platforms found. 

                                      The cl_platform_id values returned in platforms can be used to identify 

                                      a specific OpenCL platform. If platforms argument is NULL, 

                                      this argument is ignored. 

                                      The number of OpenCL platforms returned is the mininum of the value 

                                      specified by num_entries or the number of OpenCL platforms available. */

                             &numOfPlatforms

                                    /* Returns the number of OpenCL platforms available. 

                                       If num_platforms is NULL, this argument is ignored. */

                             );

    if ( error < 0)

    {

        perror("Unable to find any OpenCL platforms");

        exit(1);

    }

    

    // allocate memory for the number of installed platforms

    // alloca(....) occupies some stack space but is

    // automatically freed on return

    

    platforms = (cl_platform_id*) alloca(sizeof(cl_platform_id)*numOfPlatforms);

    

    printf("Number of OpenCL platforms found : %d\n", numOfPlatforms);

    

    

    error = clGetPlatformIDs(numOfPlatforms, /*

                                 The number of cl_platform_id entries that can be added to platforms.

                                 If platforms is not NULL, the num_entries must be greater than zero.

                                 */

                             platforms, /* Returns a list of OpenCL platforms found.

                                    The cl_platform_id values returned in platforms can be used to identify

                                    a specific OpenCL platform. If platforms argument is NULL,

                                    this argument is ignored.

                                    The number of OpenCL platforms returned is the mininum of the value

                                    specified by num_entries or the number of OpenCL platforms available. */

                             NULL

                             /* Returns the number of OpenCL platforms available.

                              If num_platforms is NULL, this argument is ignored. */

                             );

    if ( error < 0)

    {

        perror("Unable to find any OpenCL platforms");

        exit(1);

    }

    // We invoke the API 'clPlatformInfo' twice for each

    // parameter we are trying to extract

    // and we use the return value to create temporary data

    // structure (on the stack) to store

    // the returned information ot the second invocation.

    

    for( cl_uint i = 0 ; i < numOfPlatforms ; ++i)

    {

        displayPlatformInfo( platforms[i],  CL_PLATFORM_PROFILE     , "CL_PLATFORM_PROFILE");

        displayPlatformInfo( platforms[i],  CL_PLATFORM_VERSION     , "CL_PLATFORM_VERSION");

        displayPlatformInfo( platforms[i],  CL_PLATFORM_NAME        , "CL_PLATFORM_NAME");

        displayPlatformInfo( platforms[i],  CL_PLATFORM_VENDOR      , "CL_PLATFORM_VENDOR");

        displayPlatformInfo( platforms[i],  CL_PLATFORM_EXTENSIONS  , "CL_PLATFORM_EXTENSIONS");

        

        // Assume that we don't know how many devices are OpenCL compliant, we locate everything !

        displayDeviceInfo( platforms[i], CL_DEVICE_TYPE_ALL );

    }

    

    return 0;

}




실행 결과


Number of OpenCL platforms found : 1

CL_PLATFORM_PROFILE : FULL_PROFILE

CL_PLATFORM_VERSION : OpenCL 1.2 (Aug 24 2013 21:03:27)

CL_PLATFORM_NAME : Apple

CL_PLATFORM_VENDOR : Apple

CL_PLATFORM_EXTENSIONS : cl_APPLE_SetMemObjectDestructor cl_APPLE_ContextLoggingFunctions cl_APPLE_clut cl_APPLE_query_kernel_names cl_APPLE_gl_sharing cl_khr_gl_event


Numnber of detected OpenCL devices 3


CPU Detected 

VENDOR ID: 0xffffffff

Maximum number of parallel compute units: 8

Maximum dimensions for global/local work-item IDs: 3

Maximum number of work-items in each dimension: ( 1024 1 1  )

Maximum number of work-items in a work-group: 1024

Supported extensions: cl_APPLE_SetMemObjectDestructor cl_APPLE_ContextLoggingFunctions cl_APPLE_clut cl_APPLE_query_kernel_names cl_APPLE_gl_sharing cl_khr_gl_event cl_khr_fp64 cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_byte_addressable_store cl_khr_int64_base_atomics cl_khr_int64_extended_atomics cl_khr_3d_image_writes cl_khr_image2d_from_buffer cl_APPLE_fp64_basic_ops cl_APPLE_fixed_alpha_channel_orders cl_APPLE_biased_fixed_point_image_formats cl_APPLE_command_queue_priority


GPU Detected 

VENDOR ID: 0x1022700

Maximum number of parallel compute units: 2

Maximum dimensions for global/local work-item IDs: 3

Maximum number of work-items in each dimension: ( 1024 1024 64  )

Maximum number of work-items in a work-group: 1024

Supported extensions: cl_APPLE_SetMemObjectDestructor cl_APPLE_ContextLoggingFunctions cl_APPLE_clut cl_APPLE_query_kernel_names cl_APPLE_gl_sharing cl_khr_gl_event cl_khr_byte_addressable_store cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_APPLE_fp64_basic_ops cl_khr_fp64 cl_khr_3d_image_writes cl_khr_depth_images cl_khr_gl_depth_images cl_khr_gl_msaa_sharing cl_khr_image2d_from_buffer 


GPU Detected 

VENDOR ID: 0x1024400

Maximum number of parallel compute units: 16

Maximum dimensions for global/local work-item IDs: 3

Maximum number of work-items in each dimension: ( 512 512 512  )

Maximum number of work-items in a work-group: 512

Supported extensions: cl_APPLE_SetMemObjectDestructor cl_APPLE_ContextLoggingFunctions cl_APPLE_clut cl_APPLE_query_kernel_names cl_APPLE_gl_sharing cl_khr_gl_event cl_khr_global_int32_base_atomics cl_khr_global_int32_extended_atomics cl_khr_local_int32_base_atomics cl_khr_local_int32_extended_atomics cl_khr_byte_addressable_store cl_khr_image2d_from_buffer cl_khr_gl_depth_images cl_khr_depth_images 

Program ended with exit code: 0


위에서 나온 용어에 대해서 다음페이지에서 설명한다.

'Computer Vision' 카테고리의 다른 글

OpenCL : Using work item to partition data (5)  (1) 2014.06.01
OpenCL::Query OpenCL kernel (4)  (0) 2014.05.02
OpenCL Test Program (2)  (0) 2014.03.18
OpenCL test program (1)  (0) 2014.03.15
OpenCL Architecture  (0) 2014.03.15
Posted by GUNDAM_IM