diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py index dc1adcf19682c2142e13c029d9f913203e736ac0..1198b1c10531b6f8395fc5bd2736881686628068 100644 --- a/pyopencl/cffi_cl.py +++ b/pyopencl/cffi_cl.py @@ -332,6 +332,13 @@ class _Program(object): _handle_error(_lib.program__build(self.ptr, _ffi.new('char[]', options), len(ptr_devices), _ffi.cast('void**', ptr_devices))) + + def get_build_info(self, device, param): + info = _ffi.new('generic_info *') + _handle_error(_lib.program__get_build_info(self.ptr, device.ptr, param, info)) + return _generic_info_to_python(info) + + def get_info(self, param): if param == program_info.DEVICES: # todo: refactor, same code as in get_devices @@ -347,8 +354,12 @@ class _Program(object): ptr_binaries = _CArrays(_ffi.new('char***')) _handle_error(_lib.program__get_info__binaries(self.ptr, ptr_binaries.ptr, ptr_binaries.size)) return map(_ffi.string, ptr_binaries) - print param - raise NotImplementedError() + + info = _ffi.new('generic_info *') + _handle_error(_lib.program__get_info(self.ptr, param, info)) + + return _generic_info_to_python(info) + class Platform(EQUALITY_TESTS): def __init__(self): @@ -385,8 +396,15 @@ def _create_platform(ptr): def _generic_info_to_python(info): if info.type == _lib.generic_info_type_chars: return _ffi.string(info.value._chars) + if info.type == _lib.generic_info_type_array: + ar = _ffi.cast('%s[%s]' % (_ffi.string(info.array_element_type), info.value._array.size), info.value._array.array) + return list(ar) + for type_ in ('cl_uint', 'cl_mem_object_type', + 'cl_build_status', + 'cl_program_binary_type', + 'size_t', ): if info.type == getattr(_lib, 'generic_info_type_%s' % type_): return getattr(info.value, '_%s' % type_) diff --git a/src/c_wrapper/wrap_cl.cpp b/src/c_wrapper/wrap_cl.cpp index d2f1f148dffdc61653835b2e0adff4f3952a5e8b..eb0dea0ac3d06ecfade28910d1851c9ce3edfa5a 100644 --- a/src/c_wrapper/wrap_cl.cpp +++ b/src/c_wrapper/wrap_cl.cpp @@ -96,16 +96,29 @@ return info; \ } - -#define PYOPENCL_RETURN_NEW_EVENT(evt) \ - try \ - { \ - return new event(evt, false); \ - } \ - catch (...) \ - { \ - clReleaseEvent(evt); \ - throw; \ +#define PYOPENCL_GET_ARRAY_INFO(TYPE, VEC) \ + { \ + MALLOC(TYPE, ar, VEC.size()); \ + for(uint32_t i = 0; i < VEC.size(); ++i) { \ + ar[i] = VEC[i]; \ + } \ + generic_info info; \ + info.type = generic_info_type_array; \ + info.value._array.array = ar; \ + info.value._array.size = VEC.size(); \ + info.array_element_type = #TYPE; \ + return info; \ + } + +#define PYOPENCL_RETURN_NEW_EVENT(evt) \ + try \ + { \ + return new event(evt, false); \ + } \ + catch (...) \ + { \ + clReleaseEvent(evt); \ + throw; \ } @@ -1376,19 +1389,19 @@ class buffer : public memory_object } - //py::object get_info(cl_program_info param_name) const -// { -// switch (param_name) -// { -// case CL_PROGRAM_REFERENCE_COUNT: -// PYOPENCL_GET_INTEGRAL_INFO(Program, m_program, param_name, -// cl_uint); -// case CL_PROGRAM_CONTEXT: -// PYOPENCL_GET_OPAQUE_INFO(Program, m_program, param_name, -// cl_context, context); -// case CL_PROGRAM_NUM_DEVICES: -// PYOPENCL_GET_INTEGRAL_INFO(Program, m_program, param_name, -// cl_uint); + generic_info get_info(cl_program_info param_name) const + { + switch (param_name) + { + case CL_PROGRAM_REFERENCE_COUNT: + PYOPENCL_GET_INTEGRAL_INFO(Program, m_program, param_name, + cl_uint); + // case CL_PROGRAM_CONTEXT: + // PYOPENCL_GET_OPAQUE_INFO(Program, m_program, param_name, + // cl_context, context); + case CL_PROGRAM_NUM_DEVICES: + PYOPENCL_GET_INTEGRAL_INFO(Program, m_program, param_name, + cl_uint); // case CL_PROGRAM_DEVICES: // { // std::vector<cl_device_id> result; @@ -1400,14 +1413,14 @@ class buffer : public memory_object // new pyopencl::device(did))); // return py_result; // } -// case CL_PROGRAM_SOURCE: -// PYOPENCL_GET_STR_INFO(Program, m_program, param_name); -// case CL_PROGRAM_BINARY_SIZES: -// { -// std::vector<size_t> result; -// PYOPENCL_GET_VEC_INFO(Program, m_program, param_name, result); -// PYOPENCL_RETURN_VECTOR(size_t, result); -// } + case CL_PROGRAM_SOURCE: + PYOPENCL_GET_STR_INFO(Program, m_program, param_name); + case CL_PROGRAM_BINARY_SIZES: + { + std::vector<size_t> result; + PYOPENCL_GET_VEC_INFO(Program, m_program, param_name, result); + PYOPENCL_GET_ARRAY_INFO(size_t, result); + } // case CL_PROGRAM_BINARIES: // // {{{ // { @@ -1450,46 +1463,45 @@ class buffer : public memory_object // return py_result; // } // // }}} -// #if PYOPENCL_CL_VERSION >= 0x1020 -// case CL_PROGRAM_NUM_KERNELS: -// PYOPENCL_GET_INTEGRAL_INFO(Program, m_program, param_name, -// size_t); -// case CL_PROGRAM_KERNEL_NAMES: -// PYOPENCL_GET_STR_INFO(Program, m_program, param_name); -// #endif +#if PYOPENCL_CL_VERSION >= 0x1020 + case CL_PROGRAM_NUM_KERNELS: + PYOPENCL_GET_INTEGRAL_INFO(Program, m_program, param_name, + size_t); + case CL_PROGRAM_KERNEL_NAMES: + PYOPENCL_GET_STR_INFO(Program, m_program, param_name); +#endif -// default: -// throw error("Program.get_info", CL_INVALID_VALUE); -// } -// } + default: + throw error("Program.get_info", CL_INVALID_VALUE); + } + } -// py::object get_build_info( -// device const &dev, -// cl_program_build_info param_name) const -// { -// switch (param_name) -// { -// #define PYOPENCL_FIRST_ARG m_program, dev.data() // hackety hack -// case CL_PROGRAM_BUILD_STATUS: -// PYOPENCL_GET_INTEGRAL_INFO(ProgramBuild, -// PYOPENCL_FIRST_ARG, param_name, -// cl_build_status); -// case CL_PROGRAM_BUILD_OPTIONS: -// case CL_PROGRAM_BUILD_LOG: -// PYOPENCL_GET_STR_INFO(ProgramBuild, -// PYOPENCL_FIRST_ARG, param_name); -// #if PYOPENCL_CL_VERSION >= 0x1020 -// case CL_PROGRAM_BINARY_TYPE: -// PYOPENCL_GET_INTEGRAL_INFO(ProgramBuild, -// PYOPENCL_FIRST_ARG, param_name, -// cl_program_binary_type); -// #endif -// #undef PYOPENCL_FIRST_ARG + generic_info get_build_info(device const &dev, + cl_program_build_info param_name) const + { + switch (param_name) + { +#define PYOPENCL_FIRST_ARG m_program, dev.data() // hackety hack + case CL_PROGRAM_BUILD_STATUS: + PYOPENCL_GET_INTEGRAL_INFO(ProgramBuild, + PYOPENCL_FIRST_ARG, param_name, + cl_build_status); + case CL_PROGRAM_BUILD_OPTIONS: + case CL_PROGRAM_BUILD_LOG: + PYOPENCL_GET_STR_INFO(ProgramBuild, + PYOPENCL_FIRST_ARG, param_name); +#if PYOPENCL_CL_VERSION >= 0x1020 + case CL_PROGRAM_BINARY_TYPE: + PYOPENCL_GET_INTEGRAL_INFO(ProgramBuild, + PYOPENCL_FIRST_ARG, param_name, + cl_program_binary_type); +#endif +#undef PYOPENCL_FIRST_ARG -// default: -// throw error("Program.get_build_info", CL_INVALID_VALUE); -// } -// } + default: + throw error("Program.get_build_info", CL_INVALID_VALUE); + } + } void build(char *options, cl_uint num_devices, void **ptr_devices) { @@ -2084,6 +2096,15 @@ inline event *enqueue_nd_range_kernel( return 0; } + + ::error *program__get_build_info(void *ptr_program, void *ptr_device, cl_program_build_info param, generic_info *out) { + C_HANDLE_ERROR( + *out = static_cast<program*>(ptr_program)->get_build_info(*static_cast<device*>(ptr_device), + param); + ) + return 0; + } + ::error *program__get_info__devices(void *ptr_program, void **ptr_devices, uint32_t *num_devices) { typedef std::vector<cl_device_id> vec; @@ -2109,6 +2130,15 @@ inline event *enqueue_nd_range_kernel( ) return 0; } + + + ::error *program__get_info(void *ptr_program, cl_program_info param, generic_info *out) { + C_HANDLE_ERROR( + *out = static_cast<program*>(ptr_program)->get_info(param); + ) + return 0; + } + long device__hash(void *ptr_device) { diff --git a/src/c_wrapper/wrap_cl_core.h b/src/c_wrapper/wrap_cl_core.h index 0a35b58479c6121bc444f97820c91656458e2465..fd68f5ea70e55a3e66beb0646e8bdcfe39591c8d 100644 --- a/src/c_wrapper/wrap_cl_core.h +++ b/src/c_wrapper/wrap_cl_core.h @@ -3,15 +3,25 @@ typedef enum { KND_UNKNOWN, KND_SOURCE, KND_BINARY } program_kind_type; typedef enum { generic_info_type_cl_uint, generic_info_type_cl_mem_object_type, + generic_info_type_cl_build_status, + generic_info_type_cl_program_binary_type, + generic_info_type_size_t, generic_info_type_chars, + generic_info_type_array, } generic_info_type_t; typedef struct { generic_info_type_t type; + const char *array_element_type; union value_t { cl_uint _cl_uint; cl_mem_object_type _cl_mem_object_type; + cl_build_status _cl_build_status; + cl_program_binary_type _cl_program_binary_type; + size_t _size_t; char *_chars; + + struct { void *array; uint32_t size; } _array; } value; } generic_info; @@ -38,6 +48,8 @@ error *_create_program_with_source(void **ptr_program, void *ptr_context, char * error *_create_program_with_binary(void **ptr_program, void *ptr_context, cl_uint num_devices, void **ptr_devices, cl_uint num_binaries, char **binaries); error *program__build(void *ptr_program, char *options, cl_uint num_devices, void **ptr_devices); error *program__kind(void *ptr_program, int *kind); +error *program__get_build_info(void *ptr_program, void *ptr_device, cl_program_build_info param, generic_info *out); +error *program__get_info(void *ptr_program, cl_program_info param, generic_info *out); error *program__get_info__devices(void *ptr_program, void **ptr_devices, uint32_t *num_devices); error *program__get_info__binaries(void *ptr_program, char ***ptr_binaries, uint32_t *num_binaries); long program__hash(void *ptr_program);