Computer Vision2014. 3. 18. 10:46

Device에 대한 정보를 얻는 코드이다.


추가되는 함수는


displayDeviceDetails 

displayDeviceInfo


이다.


이들 함수는 loop내에서 호출된다.


    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");

          .........

       

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

        displayDeviceInfo( platforms[i], CL_DEVICE_TYPE_ALL );

  

   }


플랫폼에서 얻어진 디바이스의 정보를 프린트해주는 함수를 추가하고

그 함수의 내부에서 디바이스의 개수를 확인 한 뒤에 개수만큼 Loop를 돌려서 정보를 프린트한다.


즉 플랫폼 1개당 디바이스의 개수는 복수개가 검출 될 수 있는 것이다.


.....

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

    error = clGetDeviceIDs(id, dev_type, 0, NULL, &numOfDevices);  <= 디바이스의 개수를 확인

......

    

    error = clGetDeviceIDs(id, dev_type, numOfDevices, devices, NULL); <= 확인된 개수만큼 정보를 가지고 옴

....

   

 /* 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_WORK_GROUP_SIZE, "CL_DEVICE_MAX_WORK_GROUP_SIZE");

    }





//

//  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");

    }

}


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;

    }//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

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

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







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

OpenCL::Query OpenCL kernel (4)  (0) 2014.05.02
OpenCL Test Program (3)  (0) 2014.03.31
OpenCL test program (1)  (0) 2014.03.15
OpenCL Architecture  (0) 2014.03.15
Optical Flow에 의한 영상 정보 분석  (0) 2013.05.28
Posted by GUNDAM_IM