# include "clutil.h"
# include <assert.h>
# include <inttypes.h>
# include <string.h>
# include <sys/stat.h>
# include <memory>
# include <vector>
# include "util.h"
# include "utilpp.h"
namespace { // helper functions
std : : string get_platform_info ( cl_platform_id platform , cl_platform_info param_name ) {
size_t size = 0 ;
CL_CHECK ( clGetPlatformInfo ( platform , param_name , 0 , NULL , & size ) ) ;
std : : string ret ;
ret . resize ( size , ' \0 ' ) ;
CL_CHECK ( clGetPlatformInfo ( platform , param_name , size , & ret [ 0 ] , NULL ) ) ;
return ret ;
}
void cl_print_info ( cl_platform_id platform , cl_device_id device ) {
std : : string info = get_platform_info ( platform , CL_PLATFORM_VENDOR ) ;
printf ( " vendor: '%s' \n " , info . c_str ( ) ) ;
info = get_platform_info ( platform , CL_PLATFORM_VERSION ) ;
printf ( " platform version: '%s' \n " , info . c_str ( ) ) ;
info = get_platform_info ( platform , CL_PLATFORM_PROFILE ) ;
printf ( " profile: '%s' \n " , info . c_str ( ) ) ;
info = get_platform_info ( platform , CL_PLATFORM_EXTENSIONS ) ;
printf ( " extensions: '%s' \n " , info . c_str ( ) ) ;
char str [ 4096 ] = { } ;
clGetDeviceInfo ( device , CL_DEVICE_NAME , sizeof ( str ) , str , NULL ) ;
printf ( " name: '%s' \n " , str ) ;
clGetDeviceInfo ( device , CL_DEVICE_VERSION , sizeof ( str ) , str , NULL ) ;
printf ( " device version: '%s' \n " , str ) ;
size_t sz = 0 ;
clGetDeviceInfo ( device , CL_DEVICE_MAX_WORK_GROUP_SIZE , sizeof ( sz ) , & sz , NULL ) ;
printf ( " max work group size: %zu \n " , sz ) ;
cl_device_type type = 0 ;
clGetDeviceInfo ( device , CL_DEVICE_TYPE , sizeof ( type ) , & type , NULL ) ;
printf ( " type = 0x%04x = " , ( unsigned int ) type ) ;
switch ( type ) {
case CL_DEVICE_TYPE_CPU :
printf ( " CL_DEVICE_TYPE_CPU \n " ) ;
break ;
case CL_DEVICE_TYPE_GPU :
printf ( " CL_DEVICE_TYPE_GPU \n " ) ;
break ;
case CL_DEVICE_TYPE_ACCELERATOR :
printf ( " CL_DEVICE_TYPE_ACCELERATOR \n " ) ;
break ;
default :
printf ( " Other... \n " ) ;
break ;
}
}
void cl_print_build_errors ( cl_program program , cl_device_id device ) {
cl_build_status status ;
clGetProgramBuildInfo ( program , device , CL_PROGRAM_BUILD_STATUS ,
sizeof ( cl_build_status ) , & status , NULL ) ;
size_t log_size ;
clGetProgramBuildInfo ( program , device , CL_PROGRAM_BUILD_LOG , 0 , NULL , & log_size ) ;
std : : unique_ptr < char [ ] > log = std : : make_unique < char [ ] > ( log_size + 1 ) ;
clGetProgramBuildInfo ( program , device , CL_PROGRAM_BUILD_LOG , log_size + 1 , & log [ 0 ] , NULL ) ;
printf ( " build failed; status=%d, log: \n %s \n " , status , & log [ 0 ] ) ;
}
} // namespace
cl_device_id cl_get_device_id ( cl_device_type device_type ) {
cl_uint num_platforms = 0 ;
CL_CHECK ( clGetPlatformIDs ( 0 , NULL , & num_platforms ) ) ;
std : : unique_ptr < cl_platform_id [ ] > platform_ids = std : : make_unique < cl_platform_id [ ] > ( num_platforms ) ;
CL_CHECK ( clGetPlatformIDs ( num_platforms , & platform_ids [ 0 ] , NULL ) ) ;
for ( size_t i = 0 ; i < num_platforms ; i + + ) {
std : : string platform_name = get_platform_info ( platform_ids [ i ] , CL_PLATFORM_NAME ) ;
printf ( " platform[%zu] CL_PLATFORM_NAME: %s \n " , i , platform_name . c_str ( ) ) ;
cl_uint num_devices ;
int err = clGetDeviceIDs ( platform_ids [ i ] , device_type , 0 , NULL , & num_devices ) ;
if ( err ! = 0 | | ! num_devices ) {
continue ;
}
// Get first device
cl_device_id device_id = NULL ;
CL_CHECK ( clGetDeviceIDs ( platform_ids [ i ] , device_type , 1 , & device_id , NULL ) ) ;
cl_print_info ( platform_ids [ i ] , device_id ) ;
return device_id ;
}
printf ( " No valid openCL platform found \n " ) ;
assert ( 0 ) ;
return nullptr ;
}
CLContext cl_init_context ( cl_device_type device_type ) {
cl_device_id device_id = cl_get_device_id ( device_type ) ;
cl_context ctx = CL_CHECK_ERR ( clCreateContext ( NULL , 1 , & device_id , NULL , NULL , & err ) ) ;
return CLContext { . device_id = device_id , . context = ctx } ;
}
void cl_free_context ( CLContext * ctx ) {
clReleaseContext ( ctx - > context ) ;
ctx - > context = nullptr ;
ctx - > device_id = nullptr ;
}
cl_program cl_program_from_file ( CLContext * ctx , const char * path , const char * args ) {
char * src = ( char * ) read_file ( path , nullptr ) ;
assert ( src ! = nullptr ) ;
cl_program prg = CL_CHECK_ERR ( clCreateProgramWithSource ( ctx - > context , 1 , ( const char * * ) & src , NULL , & err ) ) ;
free ( src ) ;
if ( int err = clBuildProgram ( prg , 1 , & ctx - > device_id , args , NULL , NULL ) ; err ! = 0 ) {
cl_print_build_errors ( prg , ctx - > device_id ) ;
assert ( 0 ) ;
}
return prg ;
}
// Given a cl code and return a string represenation
const char * cl_get_error_string ( int err ) {
switch ( err ) {
case 0 : return " CL_SUCCESS " ;
case - 1 : return " CL_DEVICE_NOT_FOUND " ;
case - 2 : return " CL_DEVICE_NOT_AVAILABLE " ;
case - 3 : return " CL_COMPILER_NOT_AVAILABLE " ;
case - 4 : return " CL_MEM_OBJECT_ALLOCATION_FAILURE " ;
case - 5 : return " CL_OUT_OF_RESOURCES " ;
case - 6 : return " CL_OUT_OF_HOST_MEMORY " ;
case - 7 : return " CL_PROFILING_INFO_NOT_AVAILABLE " ;
case - 8 : return " CL_MEM_COPY_OVERLAP " ;
case - 9 : return " CL_IMAGE_FORMAT_MISMATCH " ;
case - 10 : return " CL_IMAGE_FORMAT_NOT_SUPPORTED " ;
case - 12 : return " CL_MAP_FAILURE " ;
case - 13 : return " CL_MISALIGNED_SUB_BUFFER_OFFSET " ;
case - 14 : return " CL_EXEC_STATUS_ERROR_FOR_EVENTS_IN_WAIT_LIST " ;
case - 15 : return " CL_COMPILE_PROGRAM_FAILURE " ;
case - 16 : return " CL_LINKER_NOT_AVAILABLE " ;
case - 17 : return " CL_LINK_PROGRAM_FAILURE " ;
case - 18 : return " CL_DEVICE_PARTITION_FAILED " ;
case - 19 : return " CL_KERNEL_ARG_INFO_NOT_AVAILABLE " ;
case - 30 : return " CL_INVALID_VALUE " ;
case - 31 : return " CL_INVALID_DEVICE_TYPE " ;
case - 32 : return " CL_INVALID_PLATFORM " ;
case - 33 : return " CL_INVALID_DEVICE " ;
case - 34 : return " CL_INVALID_CONTEXT " ;
case - 35 : return " CL_INVALID_QUEUE_PROPERTIES " ;
case - 36 : return " CL_INVALID_COMMAND_QUEUE " ;
case - 37 : return " CL_INVALID_HOST_PTR " ;
case - 38 : return " CL_INVALID_MEM_OBJECT " ;
case - 39 : return " CL_INVALID_IMAGE_FORMAT_DESCRIPTOR " ;
case - 40 : return " CL_INVALID_IMAGE_SIZE " ;
case - 41 : return " CL_INVALID_SAMPLER " ;
case - 42 : return " CL_INVALID_BINARY " ;
case - 43 : return " CL_INVALID_BUILD_OPTIONS " ;
case - 44 : return " CL_INVALID_PROGRAM " ;
case - 45 : return " CL_INVALID_PROGRAM_EXECUTABLE " ;
case - 46 : return " CL_INVALID_KERNEL_NAME " ;
case - 47 : return " CL_INVALID_KERNEL_DEFINITION " ;
case - 48 : return " CL_INVALID_KERNEL " ;
case - 49 : return " CL_INVALID_ARG_INDEX " ;
case - 50 : return " CL_INVALID_ARG_VALUE " ;
case - 51 : return " CL_INVALID_ARG_SIZE " ;
case - 52 : return " CL_INVALID_KERNEL_ARGS " ;
case - 53 : return " CL_INVALID_WORK_DIMENSION " ;
case - 54 : return " CL_INVALID_WORK_GROUP_SIZE " ;
case - 55 : return " CL_INVALID_WORK_ITEM_SIZE " ;
case - 56 : return " CL_INVALID_GLOBAL_OFFSET " ;
case - 57 : return " CL_INVALID_EVENT_WAIT_LIST " ;
case - 58 : return " CL_INVALID_EVENT " ;
case - 59 : return " CL_INVALID_OPERATION " ;
case - 60 : return " CL_INVALID_GL_OBJECT " ;
case - 61 : return " CL_INVALID_BUFFER_SIZE " ;
case - 62 : return " CL_INVALID_MIP_LEVEL " ;
case - 63 : return " CL_INVALID_GLOBAL_WORK_SIZE " ;
case - 64 : return " CL_INVALID_PROPERTY " ;
case - 65 : return " CL_INVALID_IMAGE_DESCRIPTOR " ;
case - 66 : return " CL_INVALID_COMPILER_OPTIONS " ;
case - 67 : return " CL_INVALID_LINKER_OPTIONS " ;
case - 68 : return " CL_INVALID_DEVICE_PARTITION_COUNT " ;
case - 69 : return " CL_INVALID_PIPE_SIZE " ;
case - 70 : return " CL_INVALID_DEVICE_QUEUE " ;
case - 71 : return " CL_INVALID_SPEC_ID " ;
case - 72 : return " CL_MAX_SIZE_RESTRICTION_EXCEEDED " ;
case - 1002 : return " CL_INVALID_D3D10_DEVICE_KHR " ;
case - 1003 : return " CL_INVALID_D3D10_RESOURCE_KHR " ;
case - 1004 : return " CL_D3D10_RESOURCE_ALREADY_ACQUIRED_KHR " ;
case - 1005 : return " CL_D3D10_RESOURCE_NOT_ACQUIRED_KHR " ;
case - 1006 : return " CL_INVALID_D3D11_DEVICE_KHR " ;
case - 1007 : return " CL_INVALID_D3D11_RESOURCE_KHR " ;
case - 1008 : return " CL_D3D11_RESOURCE_ALREADY_ACQUIRED_KHR " ;
case - 1009 : return " CL_D3D11_RESOURCE_NOT_ACQUIRED_KHR " ;
case - 1010 : return " CL_INVALID_DX9_MEDIA_ADAPTER_KHR " ;
case - 1011 : return " CL_INVALID_DX9_MEDIA_SURFACE_KHR " ;
case - 1012 : return " CL_DX9_MEDIA_SURFACE_ALREADY_ACQUIRED_KHR " ;
case - 1013 : return " CL_DX9_MEDIA_SURFACE_NOT_ACQUIRED_KHR " ;
case - 1093 : return " CL_INVALID_EGL_OBJECT_KHR " ;
case - 1092 : return " CL_EGL_RESOURCE_NOT_ACQUIRED_KHR " ;
case - 1001 : return " CL_PLATFORM_NOT_FOUND_KHR " ;
case - 1057 : return " CL_DEVICE_PARTITION_FAILED_EXT " ;
case - 1058 : return " CL_INVALID_PARTITION_COUNT_EXT " ;
case - 1059 : return " CL_INVALID_PARTITION_NAME_EXT " ;
case - 1094 : return " CL_INVALID_ACCELERATOR_INTEL " ;
case - 1095 : return " CL_INVALID_ACCELERATOR_TYPE_INTEL " ;
case - 1096 : return " CL_INVALID_ACCELERATOR_DESCRIPTOR_INTEL " ;
case - 1097 : return " CL_ACCELERATOR_TYPE_NOT_SUPPORTED_INTEL " ;
case - 1000 : return " CL_INVALID_GL_SHAREGROUP_REFERENCE_KHR " ;
case - 1098 : return " CL_INVALID_VA_API_MEDIA_ADAPTER_INTEL " ;
case - 1099 : return " CL_INVALID_VA_API_MEDIA_SURFACE_INTEL " ;
case - 1100 : return " CL_VA_API_MEDIA_SURFACE_ALREADY_ACQUIRED_INTEL " ;
case - 1101 : return " CL_VA_API_MEDIA_SURFACE_NOT_ACQUIRED_INTEL " ;
default : return " CL_UNKNOWN_ERROR " ;
}
}