ViennaCL - The Vienna Computing Library  1.5.0
viennacl/ocl/infos.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_OCL_INFOS_HPP_
00002 #define VIENNACL_OCL_INFOS_HPP_
00003 
00004 /* =========================================================================
00005    Copyright (c) 2010-2012, Institute for Microelectronics,
00006                             Institute for Analysis and Scientific Computing,
00007                             TU Wien.
00008 
00009                             -----------------
00010                   ViennaCL - The Vienna Computing Library
00011                             -----------------
00012 
00013    Project Head:    Karl Rupp                   rupp@iue.tuwien.ac.at
00014 
00015    (A list of authors and contributors can be found in the PDF manual)
00016 
00017    License:         MIT (X11), see file LICENSE in the base directory
00018 ============================================================================= */
00019 
00024 #ifdef __APPLE__
00025 #include <OpenCL/cl.h>
00026 #else
00027 #include <CL/cl.h>
00028 #endif
00029 #include <vector>
00030 #include "viennacl/ocl/forwards.h"
00031 #include "viennacl/ocl/error.hpp"
00032 
00033 namespace viennacl{
00034 
00035     namespace ocl{
00036 
00038     namespace detail{
00039 
00041     template<typename T>
00042     struct info;
00043 
00045     template<>
00046     struct info<cl_mem>{
00047       typedef cl_mem_info type;
00048       static void get(cl_mem mem, cl_mem_info param_name,size_t param_value_size,void *param_value,size_t *param_value_size_ret){
00049           cl_int err = clGetMemObjectInfo(mem,param_name,param_value_size,param_value,param_value_size_ret);
00050           VIENNACL_ERR_CHECK(err);
00051       }
00052     };
00053 
00054     template<>
00055     struct info<cl_device_id>{
00056       typedef cl_device_info type;
00057       static void get(cl_device_id device, cl_device_info param_name,size_t param_value_size,void *param_value,size_t *param_value_size_ret){
00058           cl_int err = clGetDeviceInfo(device,param_name,param_value_size,param_value,param_value_size_ret);
00059           VIENNACL_ERR_CHECK(err);
00060       }
00061     };
00062 
00063     template<>
00064     struct info<cl_kernel>{
00065       typedef cl_kernel_info type;
00066       static void get(cl_kernel kernel, cl_kernel_info param_name,size_t param_value_size,void *param_value,size_t *param_value_size_ret){
00067           cl_int err = clGetKernelInfo(kernel,param_name,param_value_size,param_value,param_value_size_ret);
00068           VIENNACL_ERR_CHECK(err);
00069       }
00070 
00071       static void get(cl_kernel kernel, cl_device_id dev_id, cl_kernel_work_group_info param_name,size_t param_value_size,void *param_value,size_t *param_value_size_ret){
00072           cl_int err = clGetKernelWorkGroupInfo(kernel, dev_id, param_name,param_value_size,param_value,param_value_size_ret);
00073           VIENNACL_ERR_CHECK(err);
00074       }
00075     };
00076 
00077     template<>
00078     struct info<cl_context>{
00079       typedef cl_context_info type;
00080       static void get(cl_context context, cl_context_info param_name,size_t param_value_size,void *param_value,size_t *param_value_size_ret){
00081           cl_int err = clGetContextInfo(context,param_name,param_value_size,param_value,param_value_size_ret);
00082           VIENNACL_ERR_CHECK(err);
00083       }
00084     };
00085 
00086     template<>
00087     struct info<cl_program>{
00088       typedef cl_program_info type;
00089       static void get(cl_program context, cl_program_info param_name,size_t param_value_size,void *param_value,size_t *param_value_size_ret){
00090           cl_int err = clGetProgramInfo(context,param_name,param_value_size,param_value,param_value_size_ret);
00091           VIENNACL_ERR_CHECK(err);
00092       }
00093     };
00094 
00095     template<class RES_T>
00096     struct get_info_impl{
00097 
00098         template<class MEM_T, class INFO_T>
00099         RES_T operator()(MEM_T const & mem, INFO_T const & info){
00100             RES_T res;
00101             detail::info<MEM_T>::get(mem,info,sizeof(RES_T),&res,NULL);
00102             return res;
00103         }
00104 
00105         template<class MEM_T, class MEM2_T, class INFO_T>
00106         RES_T operator()(MEM_T const & mem, MEM2_T const & mem2, INFO_T const & info){
00107             RES_T res;
00108             detail::info<MEM_T>::get(mem,mem2, info,sizeof(RES_T),&res,NULL);
00109             return res;
00110         }
00111     };
00112 
00113     template<>
00114     struct get_info_impl<std::string>{
00115 
00116         template<class MEM_T, class INFO_T>
00117         std::string operator()(const MEM_T &mem, const INFO_T &info){
00118             char buff[1024];
00119             detail::info<MEM_T>::get(mem,info,1024,buff,NULL);
00120             return std::string(buff);
00121         }
00122     };
00123 
00124     template<class T>
00125     struct get_info_impl<std::vector<T> >{
00126         template<class MEM_T, class INFO_T>
00127         std::vector<T> operator()(const MEM_T &mem, const INFO_T &info){
00128             size_t vec_size;
00129             detail::info<MEM_T>::get(mem,info,0,NULL,&vec_size);
00130             std::vector<T> res(vec_size/sizeof(T));
00131             detail::info<MEM_T>::get(mem,info,vec_size,res.data(),NULL);
00132             return res;
00133         }
00134     };
00135 
00136     template<typename T, typename info<T>::type param>
00137     struct return_type;
00141      #define SET_INFO_RETURN_TYPE(DATA_TYPE,NAME,RETURN_TYPE) template<> struct return_type<DATA_TYPE, NAME> { typedef RETURN_TYPE Result; }
00142 
00143      SET_INFO_RETURN_TYPE(cl_mem,CL_MEM_TYPE, cl_mem_object_type);
00144      SET_INFO_RETURN_TYPE(cl_mem,CL_MEM_FLAGS, cl_mem_flags);
00145      SET_INFO_RETURN_TYPE(cl_mem,CL_MEM_SIZE, size_t);
00146      SET_INFO_RETURN_TYPE(cl_mem,CL_MEM_HOST_PTR, void*);
00147      SET_INFO_RETURN_TYPE(cl_mem,CL_MEM_MAP_COUNT, cl_uint);
00148      SET_INFO_RETURN_TYPE(cl_mem,CL_MEM_REFERENCE_COUNT, cl_uint);
00149      SET_INFO_RETURN_TYPE(cl_mem,CL_MEM_CONTEXT, cl_context);
00150 
00151      SET_INFO_RETURN_TYPE(cl_program,CL_PROGRAM_REFERENCE_COUNT,cl_uint);
00152 
00153       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_ADDRESS_BITS, cl_uint);
00154       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_AVAILABLE, cl_bool);
00155       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_COMPILER_AVAILABLE, cl_bool);
00156 //      SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_DOUBLE_FP_CONFIG, cl_device_fp_config);
00157       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_ENDIAN_LITTLE, cl_bool);
00158       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_ERROR_CORRECTION_SUPPORT, cl_bool);
00159       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_EXECUTION_CAPABILITIES, cl_device_exec_capabilities);
00160       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_EXTENSIONS, std::string);
00161       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_GLOBAL_MEM_CACHE_SIZE, cl_ulong);
00162       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_GLOBAL_MEM_CACHELINE_SIZE, cl_uint);
00163       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_GLOBAL_MEM_SIZE, cl_ulong);
00164 //      SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_HALF_FP_CONFIG, cl_device_fp_config);
00165       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_IMAGE_SUPPORT, cl_bool);
00166       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_IMAGE2D_MAX_HEIGHT , size_t);
00167       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_IMAGE2D_MAX_WIDTH , size_t);
00168       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_IMAGE3D_MAX_DEPTH , size_t);
00169       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_IMAGE3D_MAX_HEIGHT , size_t);
00170       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_IMAGE3D_MAX_WIDTH , size_t);
00171       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_LOCAL_MEM_SIZE, cl_ulong);
00172       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_LOCAL_MEM_TYPE, cl_device_local_mem_type);
00173       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_MAX_CLOCK_FREQUENCY , cl_uint);
00174       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_MAX_COMPUTE_UNITS , cl_uint); //The minimum value is 1
00175       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_MAX_CONSTANT_ARGS  , cl_uint); //The minimum value is 8
00176       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_MAX_CONSTANT_BUFFER_SIZE   , cl_ulong); //The minimum value is 64 KB
00177       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_MAX_MEM_ALLOC_SIZE , cl_ulong); //The minimum value is max (1/4th of CL_DEVICE_GLOBAL_MEM_SIZE, 128*1024*1024)
00178       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_MAX_PARAMETER_SIZE  , size_t);
00179       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_MAX_READ_IMAGE_ARGS  , cl_uint);
00180       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_MAX_SAMPLERS , cl_uint);
00181       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_MAX_WORK_GROUP_SIZE , size_t);
00182       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_MAX_WORK_ITEM_DIMENSIONS  , cl_uint);
00183       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_MAX_WORK_ITEM_SIZES , std::vector<size_t>);
00184       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_MAX_WRITE_IMAGE_ARGS , cl_uint);
00185       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_MEM_BASE_ADDR_ALIGN  , cl_uint);
00186       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_MIN_DATA_TYPE_ALIGN_SIZE , cl_uint);
00187       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_NAME , std::string);
00188       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_PLATFORM , cl_platform_id);
00189       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR  , cl_uint);
00190       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT  , cl_uint);
00191       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_PREFERRED_VECTOR_WIDTH_INT  , cl_uint);
00192       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_PREFERRED_VECTOR_WIDTH_FLOAT  , cl_uint);
00193       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_PREFERRED_VECTOR_WIDTH_DOUBLE  , cl_uint);
00194       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_PROFILE , std::string);
00195       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_PROFILING_TIMER_RESOLUTION , size_t);
00196       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_QUEUE_PROPERTIES , cl_command_queue_properties);
00197       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_SINGLE_FP_CONFIG  , cl_device_fp_config);
00198       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_TYPE , cl_device_type);
00199       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_VENDOR , std::string);
00200       SET_INFO_RETURN_TYPE(cl_device_id,  CL_DEVICE_VENDOR_ID  , cl_uint);
00201       SET_INFO_RETURN_TYPE(cl_device_id,   CL_DEVICE_VERSION  , std::string);
00202       SET_INFO_RETURN_TYPE(cl_device_id,   CL_DRIVER_VERSION  , std::string);
00203 
00204 
00205       SET_INFO_RETURN_TYPE(cl_kernel,CL_KERNEL_FUNCTION_NAME, std::string);
00206       SET_INFO_RETURN_TYPE(cl_kernel,CL_KERNEL_NUM_ARGS, cl_uint);
00207       SET_INFO_RETURN_TYPE(cl_kernel,CL_KERNEL_REFERENCE_COUNT, cl_uint);
00208       SET_INFO_RETURN_TYPE(cl_kernel,CL_KERNEL_CONTEXT, cl_context);
00209       SET_INFO_RETURN_TYPE(cl_kernel,CL_KERNEL_PROGRAM, cl_program);
00210 
00211 
00212       SET_INFO_RETURN_TYPE(cl_kernel,CL_KERNEL_WORK_GROUP_SIZE, size_t);
00213 //      SET_INFO_RETURN_TYPE(cl_kernel,CL_KERNEL_COMPILE_WORK_GROUP_SIZE, size_t[3]);
00214       SET_INFO_RETURN_TYPE(cl_kernel,CL_KERNEL_LOCAL_MEM_SIZE, cl_ulong);
00215       SET_INFO_RETURN_TYPE(cl_kernel,CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE, size_t);
00216 
00217       SET_INFO_RETURN_TYPE(cl_context, CL_CONTEXT_NUM_DEVICES, cl_uint);
00218       SET_INFO_RETURN_TYPE(cl_context, CL_CONTEXT_REFERENCE_COUNT, cl_uint);
00219       SET_INFO_RETURN_TYPE(cl_context, CL_CONTEXT_PROPERTIES, cl_context_properties);
00220 
00221       #undef SET_INFO_RETURN_TYPE
00222 
00224     }
00225 
00226     template<cl_device_info param>
00227     typename detail::return_type<cl_device_id, param>::Result info(cl_device_id const & handle){
00228         typedef typename detail::return_type<cl_device_id, param>::Result res_t;
00229         return detail::get_info_impl<res_t>()(handle,param);
00230     }
00231 
00232     template<cl_mem_info param>
00233     typename detail::return_type<cl_mem, param>::Result info(cl_mem const & handle){
00234         typedef typename detail::return_type<cl_mem, param>::Result res_t;
00235         return detail::get_info_impl<res_t>()(handle,param);
00236     }
00237     template<cl_program_info param>
00238     typename detail::return_type<cl_program, param>::Result info(cl_program const & handle){
00239         typedef typename detail::return_type<cl_program, param>::Result res_t;
00240         return detail::get_info_impl<res_t>()(handle,param);
00241     }
00242 
00243 //    template<cl_kernel_info param>
00244 //    typename detail::return_type<cl_kernel, param>::Result info(cl_kernel const & handle){
00245 //        typedef typename detail::return_type<cl_kernel, param>::Result res_t;
00246 //        return detail::get_info_impl<res_t>()(handle,param);
00247 //    }
00248 
00249 //    template<cl_kernel_work_group_info param>
00250 //    typename detail::return_type<cl_kernel, param>::Result info(cl_kernel const & handle, cl_device_id const & handle2){
00251 //        typedef typename detail::return_type<cl_kernel, param>::Result res_t;
00252 //        return detail::get_info_impl<res_t>()(handle,handle2,param);
00253 //    }
00254 
00255     template<cl_context_info param>
00256     typename detail::return_type<cl_context, param>::Result info(cl_context const & handle){
00257         typedef typename detail::return_type<cl_context, param>::Result res_t;
00258         return detail::get_info_impl<res_t>()(handle,param);
00259     }
00260 
00261     template<class OCL_TYPE, typename detail::info<OCL_TYPE>::type param>
00262     typename detail::return_type<OCL_TYPE, param>::Result info(OCL_TYPE const & handle){
00263         return viennacl::ocl::info(handle.get());
00264     }
00265 
00266     }
00267 }
00268 #endif // INFOS_HPP