diff --git a/pyopencl/_cffi.py b/pyopencl/_cffi.py index 596be5c286f3ac15ef9d6ad59244411fa705fa2a..8c12c497c9c5631b52ad90c97338e75835f48295 100644 --- a/pyopencl/_cffi.py +++ b/pyopencl/_cffi.py @@ -89,6 +89,8 @@ typedef struct _cl_buffer_region { size_t size; } cl_buffer_region; +/* c++ class pointer */ +typedef struct clbase *clobj_t; """ diff --git a/pyopencl/c_wrapper/wrap_cl_core.h b/pyopencl/c_wrapper/wrap_cl_core.h index 097b0ac2061f7fc9e687a91c9cdb5d1b84e28567..45c9a3fd3a644ab68ed89912a2025909710d80ea 100644 --- a/pyopencl/c_wrapper/wrap_cl_core.h +++ b/pyopencl/c_wrapper/wrap_cl_core.h @@ -35,64 +35,104 @@ typedef struct { } generic_info; -int pyopencl_get_cl_version(void); - -error *get_platforms(void **ptr_platforms, uint32_t *num_platforms); -error *platform__get_devices(void *ptr_platform, void **ptr_devices, uint32_t *num_devices, cl_device_type devtype); -error *_create_context(void **ptr_ctx, cl_context_properties *properties, cl_uint num_devices, void **ptr_devices); -error *_create_command_queue(void **ptr_command_queue, void *ptr_context, void *ptr_device, cl_command_queue_properties properties); -error *_create_buffer(void **ptr_buffer, void *ptr_context, cl_mem_flags flags, size_t size, void *hostbuf); -error *_create_program_with_source(void **ptr_program, void *ptr_context, const char *src); -error *_create_program_with_binary(void **ptr_program, void *ptr_context, cl_uint num_devices, void **ptr_devices, cl_uint num_binaries, char **binaries, size_t *binary_sizes); -error *program__build(void *ptr_program, const 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 *_create_sampler(void **ptr_sampler, void *ptr_context, int normalized_coordinates, cl_addressing_mode am, cl_filter_mode fm); - -error *event__get_profiling_info(void *ptr_event, cl_profiling_info param, generic_info *out); -error *event__wait(void *ptr_event); - -error *_create_kernel(void **ptr_kernel, void *ptr_program, const char *name); -error *kernel__set_arg_null(void *ptr_kernel, cl_uint arg_index); -error *kernel__set_arg_mem(void *ptr_kernel, cl_uint arg_index, void *ptr_mem); -error *kernel__set_arg_sampler(void *ptr_kernel, cl_uint arg_index, void *ptr_sampler); -error *kernel__set_arg_buf(void *ptr_kernel, cl_uint arg_index, +int pyopencl_get_cl_version(); + +error *get_platforms(clobj_t **ptr_platforms, uint32_t *num_platforms); +error *platform__get_devices(clobj_t platform, clobj_t **ptr_devices, + uint32_t *num_devices, cl_device_type devtype); +error *_create_context(clobj_t *ctx, const cl_context_properties *properties, + cl_uint num_devices, const clobj_t *ptr_devices); +error *_create_command_queue(clobj_t *queue, clobj_t context, clobj_t device, + cl_command_queue_properties properties); +error *_create_buffer(clobj_t *buffer, clobj_t context, cl_mem_flags flags, + size_t size, void *hostbuf); +error *_create_program_with_source(clobj_t *program, clobj_t context, + const char *src); +error *_create_program_with_binary(clobj_t *program, clobj_t context, + cl_uint num_devices, const clobj_t *devices, + cl_uint num_binaries, char **binaries, + size_t *binary_sizes); +error *program__build(clobj_t program, const char *options, + cl_uint num_devices, const clobj_t *devices); +error *program__kind(clobj_t program, int *kind); +error *program__get_build_info(clobj_t program, clobj_t device, + cl_program_build_info param, generic_info *out); + +error *_create_sampler(clobj_t *sampler, clobj_t context, + int normalized_coordinates, cl_addressing_mode am, + cl_filter_mode fm); + +error *event__get_profiling_info(clobj_t event, cl_profiling_info param, + generic_info *out); +error *event__wait(clobj_t event); + +error *_create_kernel(clobj_t *kernel, clobj_t program, const char *name); +error *kernel__set_arg_null(clobj_t kernel, cl_uint arg_index); +error *kernel__set_arg_mem(clobj_t kernel, cl_uint arg_index, clobj_t mem); +error *kernel__set_arg_sampler(clobj_t kernel, cl_uint arg_index, + clobj_t sampler); +error *kernel__set_arg_buf(clobj_t kernel, cl_uint arg_index, const void *buffer, size_t size); -error *kernel__get_work_group_info(void *ptr_kernel, cl_kernel_work_group_info param, void *ptr_device, generic_info *out); - -error *_get_supported_image_formats(void *ptr_context, cl_mem_flags flags, cl_mem_object_type image_type, generic_info *out); - -error *_create_image_2d(void **ptr_image, void *ptr_context, cl_mem_flags flags, cl_image_format *fmt, size_t width, size_t height, size_t pitch, void *ptr_buffer, size_t size); -error *_create_image_3d(void **ptr_image, void *ptr_context, cl_mem_flags flags, cl_image_format *fmt, size_t width, size_t height, size_t depth, size_t pitch_x, size_t pitch_y, void *ptr_buffer, size_t size); -error *image__get_image_info(void *ptr_image, cl_image_info param, generic_info *out); - -long _hash(void *ptr_platform, class_t); - -error *_enqueue_nd_range_kernel(void **ptr_event, void *ptr_command_queue, void *ptr_kernel, cl_uint work_dim, const size_t *global_work_offset, const size_t *global_work_size, const size_t *local_work_size, void **wait_for, uint32_t num_wait_for); - -error *_enqueue_marker_with_wait_list(void **ptr_event, void *ptr_command_queue, - void **wait_for, uint32_t num_wait_for); -error *_enqueue_barrier_with_wait_list(void **ptr_event, - void *ptr_command_queue, - void **wait_for, uint32_t num_wait_for); -error *_enqueue_marker(void **ptr_event, void *ptr_command_queue); -error *_enqueue_barrier(void *ptr_command_queue); -error *_enqueue_read_buffer(void **ptr_event, void *ptr_command_queue, void *ptr_mem, void *buffer, size_t size, size_t device_offset, void **wait_for, uint32_t num_wait_for, int is_blocking); -error *_enqueue_copy_buffer(void **ptr_event, void *ptr_command_queue, void *ptr_src, void *ptr_dst, ptrdiff_t byte_count, size_t src_offset, size_t dst_offset, void **wait_for, uint32_t num_wait_for); -error *_enqueue_write_buffer(void **ptr_event, void *ptr_command_queue, void *ptr_memory_object_holder, const void *buffer, size_t size, size_t device_offset, void **wait_for, uint32_t num_wait_for, int is_blocking); -error *_enqueue_read_image(void **ptr_event, void *ptr_command_queue, void *ptr_mem, size_t *origin, size_t *region, void *buffer, size_t size, size_t row_pitch, size_t slice_pitch, void **wait_for, uint32_t num_wait_for, int is_blocking); -void populate_constants(void(*add)(const char*, const char*, long value)); - -error *_command_queue_finish(void *ptr_command_queue); -error *_command_queue_flush(void *ptr_command_queue); - -intptr_t _int_ptr(void*, class_t); -void* _from_int_ptr(void **ptr_out, intptr_t int_ptr_value, class_t); -error *_get_info(void *ptr, class_t class_, cl_uint param, generic_info *out); -void _delete(void *ptr, class_t class_); -error *_release_memobj(void* ptr); +error *kernel__get_work_group_info(clobj_t kernel, + cl_kernel_work_group_info param, + clobj_t device, generic_info *out); + +error *_get_supported_image_formats(clobj_t context, cl_mem_flags flags, + cl_mem_object_type image_type, + generic_info *out); + +error *_create_image_2d(clobj_t *image, clobj_t context, cl_mem_flags flags, + cl_image_format *fmt, size_t width, size_t height, + size_t pitch, void *buffer, size_t size); +error *_create_image_3d(clobj_t *image, clobj_t context, cl_mem_flags flags, + cl_image_format *fmt, size_t width, size_t height, + size_t depth, size_t pitch_x, size_t pitch_y, + void *buffer, size_t size); +error *image__get_image_info(clobj_t image, cl_image_info param, + generic_info *out); + +error *_enqueue_nd_range_kernel(clobj_t *ptr_event, clobj_t queue, + clobj_t kernel, cl_uint work_dim, + const size_t *global_work_offset, + const size_t *global_work_size, + const size_t *local_work_size, + const clobj_t *wait_for, uint32_t num_wait_for); + +error *_enqueue_marker_with_wait_list(clobj_t *ptr_event, clobj_t queue, + const clobj_t *wait_for, + uint32_t num_wait_for); +error *_enqueue_barrier_with_wait_list(clobj_t *event, clobj_t queue, + const clobj_t *wait_for, + uint32_t num_wait_for); +error *_enqueue_marker(clobj_t *event, clobj_t queue); +error *_enqueue_barrier(clobj_t queue); +error *_enqueue_read_buffer(clobj_t *event, clobj_t queue, clobj_t mem, + void *buffer, size_t size, size_t device_offset, + const clobj_t *wait_for, uint32_t num_wait_for, + int is_blocking); +error *_enqueue_copy_buffer(clobj_t *event, clobj_t queue, clobj_t src, + clobj_t dst, ptrdiff_t byte_count, + size_t src_offset, size_t dst_offset, + const clobj_t *wait_for, uint32_t num_wait_for); +error *_enqueue_write_buffer(clobj_t *event, clobj_t queue, clobj_t mem, + const void *buffer, size_t size, + size_t device_offset, const clobj_t *wait_for, + uint32_t num_wait_for, int is_blocking); +error *_enqueue_read_image(clobj_t *event, clobj_t queue, clobj_t mem, + size_t *origin, size_t *region, void *buffer, + size_t size, size_t row_pitch, size_t slice_pitch, + const clobj_t *wait_for, uint32_t num_wait_for, + int is_blocking); + +error *_command_queue_finish(clobj_t queue); +error *_command_queue_flush(clobj_t queue); + +intptr_t _int_ptr(clobj_t obj); +error *_from_int_ptr(clobj_t *ptr_out, intptr_t int_ptr_value, class_t); +error *_get_info(clobj_t obj, cl_uint param, generic_info *out); +void _delete(clobj_t obj); +error *_release_memobj(clobj_t obj); void pyopencl_free_pointer(void*); void pyopencl_free_pointer_array(void**, uint32_t size); @@ -101,3 +141,4 @@ int pyopencl_have_gl(); unsigned pyopencl_bitlog2(unsigned long v); void pyopencl_set_gc(int (*func)()); +void populate_constants(void(*add)(const char*, const char*, long value)); diff --git a/pyopencl/c_wrapper/wrap_cl_gl_core.h b/pyopencl/c_wrapper/wrap_cl_gl_core.h index c362cca1233c2775a088b2022ca2cc869c60e8e4..2d34d9e2bec657896e76a24036591393193a841b 100644 --- a/pyopencl/c_wrapper/wrap_cl_gl_core.h +++ b/pyopencl/c_wrapper/wrap_cl_gl_core.h @@ -1,7 +1,13 @@ // Everything in here should have a 'pyopencl_' prefix to avoid clashing with // other libraries imported via CFFI. -error *_create_from_gl_buffer(void **ptr, void *ptr_context, cl_mem_flags flags, GLuint bufobj); -error *_create_from_gl_renderbuffer(void **ptr, void *ptr_context, cl_mem_flags flags, GLuint bufobj); -error *_enqueue_acquire_gl_objects(void **ptr_event, void *ptr_command_queue, void **ptr_mem_objects, uint32_t num_mem_objects, void **wait_for, uint32_t num_wait_for); -error *_enqueue_release_gl_objects(void **ptr_event, void *ptr_command_queue, void **ptr_mem_objects, uint32_t num_mem_objects, void **wait_for, uint32_t num_wait_for); +error *_create_from_gl_buffer(clobj_t *ptr, clobj_t context, + cl_mem_flags flags, GLuint bufobj); +error *_create_from_gl_renderbuffer(clobj_t *ptr, clobj_t context, + cl_mem_flags flags, GLuint bufobj); +error *_enqueue_acquire_gl_objects( + clobj_t *ptr_event, clobj_t queue, const clobj_t *mem_objects, + uint32_t num_mem_objects, const clobj_t *wait_for, uint32_t num_wait_for); +error *_enqueue_release_gl_objects( + clobj_t *ptr_event, clobj_t queue, const clobj_t *mem_objects, + uint32_t num_mem_objects, const clobj_t *wait_for, uint32_t num_wait_for); diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py index b3a77f3c5e7018f34a9a9c0a0d06081c67c67de9..3a048c70d6d7ddac0e5f86893b7bc6220652cb3b 100644 --- a/pyopencl/cffi_cl.py +++ b/pyopencl/cffi_cl.py @@ -183,34 +183,29 @@ def _create_instance(cls, ptr): class _Common(object): ptr = _ffi.NULL - @classmethod - def _c_class_type(cls): - return getattr(_lib, 'CLASS_%s' % cls._id.upper()) - def __del__(self): - _lib._delete(self.ptr, self._c_class_type()) + _lib._delete(self.ptr) def __eq__(self, other): - return hash(self) == hash(other) + return other == self.int_ptr def __hash__(self): - return _lib._hash(self.ptr, self._c_class_type()) + return _lib._int_ptr(self.ptr) def get_info(self, param): - info = _ffi.new('generic_info *') - _handle_error(_lib._get_info(self.ptr, self._c_class_type(), param, info)) + info = _ffi.new('generic_info*') + _handle_error(_lib._get_info(self.ptr, param, info)) return _generic_info_to_python(info) @property def int_ptr(self): - return _lib._int_ptr(self.ptr, self._c_class_type()) + return _lib._int_ptr(self.ptr) @classmethod def from_int_ptr(cls, int_ptr_value): ptr = _ffi.new('void **') - _lib._from_int_ptr(ptr, int_ptr_value, - getattr(_lib, 'CLASS_%s' % cls._id.upper())) - #getattr(_lib, '%s__from_int_ptr' % cls._id)(ptr, int_ptr_value) + _handle_error(_lib._from_int_ptr( + ptr, int_ptr_value, getattr(_lib, 'CLASS_%s' % cls._id.upper()))) return _create_instance(cls, ptr[0]) # }}} @@ -499,25 +494,21 @@ def _c_buffer_from_obj(obj, writable=False): if isinstance(obj, np.ndarray): # numpy array - return ( - _ffi.cast('void *', - obj.__array_interface__['data'][0]), - obj.nbytes, - None) + return (_ffi.cast('void *', + obj.__array_interface__['data'][0]), + obj.nbytes, None) elif isinstance(obj, np.generic): # numpy scalar # - # * obj.__array_interface__ exists in CPython, but the address does - # not seem to point to the actual scalar (not supported/bug?). + # * obj.__array_interface__ exists in CPython although requires + # holding a reference to the dynamically created + # __array_interface__ object # # * does not exist (yet?) in numpypy. - - s_array = np.array([obj]) # obj[()] not supported yet by numpypy - return ( - _ffi.cast('void *', - s_array.__array_interface__['data'][0]), - s_array.nbytes, - s_array) + s_array = obj[()] + return (_ffi.cast('void *', + s_array.__array_interface__['data'][0]), + s_array.nbytes, s_array) elif isinstance(obj, bytes): if writable: # There sould be better ways to pass arguments diff --git a/src/c_wrapper/utils.h b/src/c_wrapper/utils.h index a7f8ca387a7791a9de7a5e10a6b941ec155a2455..8b687b65a9c4595ee075e50a84857ff74f8f6c60 100644 --- a/src/c_wrapper/utils.h +++ b/src/c_wrapper/utils.h @@ -43,7 +43,7 @@ public: { } inline size_t - len() + len() const { return m_len; } @@ -65,59 +65,6 @@ public: m_len = len; this->reset((T*)realloc((void*)this->release(), len * sizeof(T))); } - template<typename T2> - static pyopencl_buf<T> - from_class(const T2 *buf2, size_t len) - { - pyopencl_buf<T> buf(len); - for (size_t i = 0;i < len;i++) { - buf[i] = buf2[i]->data(); - } - return buf; - } - template<typename T2> - static pyopencl_buf<T> - from_class(const void **buf2, size_t len) - { - return from_class<const T2*>( - reinterpret_cast<const T2 *const*>(buf2), len); - } - template<typename T2> - static pyopencl_buf<T> - from_class(const void *const *buf2, size_t len) - { - return from_class<const T2*>( - reinterpret_cast<const T2 *const*>(buf2), len); - } - template<typename T2> - static pyopencl_buf<T> - from_class(const pyopencl_buf<T2> buf2) - { - return from_class(buf2.get(), buf2.len()); - } - template<typename T2, typename... ArgTypes> - static pyopencl_buf<T2*> - _to_class(const T *buf2, size_t len, ArgTypes&&... args) - { - pyopencl_buf<T2*> buf(len); - for (size_t i = 0;i < len;i++) { - buf[i] = new T2(buf2[i], std::forward<ArgTypes>(args)...); - } - return buf; - } - template<typename T2, typename... ArgTypes> - static pyopencl_buf<T2*> - to_class(const T *buf2, size_t len, ArgTypes&&... args) - { - return _to_class<T2>(buf2, len, std::forward<ArgTypes>(args)...); - } - template<typename T2, typename... ArgTypes> - pyopencl_buf<T2*> - to_class(ArgTypes... args) - { - return _to_class<T2>(this->get(), m_len, - std::forward<ArgTypes>(args)...); - } }; template<> @@ -130,7 +77,7 @@ public: { } inline size_t - len() + len() const { return m_len; } @@ -162,6 +109,96 @@ public: noncopyable() = default; }; +struct clbase : public noncopyable { + virtual ~clbase() = default; + virtual intptr_t intptr() const = 0; + virtual generic_info get_info(cl_uint) const = 0; + bool operator==(clbase const &other) const = delete; + bool operator!=(clbase const &other) const = delete; +}; + +template<typename CLType> +class clobj : public clbase { +private: + CLType m_obj; +public: + typedef CLType cl_type; + clobj(CLType obj, bool=false) : m_obj(obj) + {} + inline const CLType& + data() const + { + return m_obj; + } + intptr_t + intptr() const + { + return (intptr_t)m_obj; + } +}; + +template<typename T, typename T2> +static inline pyopencl_buf<typename T::cl_type> +buf_from_class(const T2 *buf2, size_t len) +{ + pyopencl_buf<typename T::cl_type> buf(len); + for (size_t i = 0;i < len;i++) { + buf[i] = static_cast<const T*>(buf2[i])->data(); + } + return buf; +} + +template<typename T, typename T2> +static inline pyopencl_buf<typename T::cl_type> +buf_from_class(const pyopencl_buf<T2> &&buf) +{ + return buf_from_class(buf.get(), buf.len()); +} + +template<typename T, typename T2> +static inline pyopencl_buf<typename T::cl_type> +buf_from_class(const pyopencl_buf<T2> &buf) +{ + return buf_from_class(buf.get(), buf.len()); +} + +template<typename T, typename T2, typename... ArgTypes> +static inline pyopencl_buf<clbase*> +buf_to_base(const T2 *buf2, size_t len, ArgTypes&&... args) +{ + pyopencl_buf<clbase*> buf(len); + size_t i = 0; + try { + for (;i < len;i++) { + buf[i] = static_cast<clbase*>( + new T((typename T::cl_type)buf2[i], + std::forward<ArgTypes>(args)...)); + } + } catch (...) { + for (size_t j = 0;j < i;j++) { + delete buf[i]; + } + throw; + } + return buf; +} + +template<typename T, typename T2, typename... ArgTypes> +static inline pyopencl_buf<clbase*> +buf_to_base(const pyopencl_buf<T2> &&buf2, ArgTypes&&... args) +{ + return buf_to_base<T>(buf2.get(), buf2.len(), + std::forward<ArgTypes>(args)...); +} + +template<typename T, typename T2, typename... ArgTypes> +static inline pyopencl_buf<clbase*> +buf_to_base(const pyopencl_buf<T2> &buf2, ArgTypes&&... args) +{ + return buf_to_base<T>(buf2.get(), buf2.len(), + std::forward<ArgTypes>(args)...); +} + // FIXME static inline char* _copy_str(const std::string& str) @@ -219,7 +256,7 @@ convert_opaque_array_info(pyopencl_buf<T> &buf) info.dontfree = 0; info.opaque_class = Cls::get_class_t(); info.type = _copy_str(std::string("void*[") + tostring(buf.len()) + "]"); - info.value = buf.template to_class<Cls>().release(); + info.value = buf_to_base<Cls>(buf).release(); return info; } diff --git a/src/c_wrapper/wrap_cl.cpp b/src/c_wrapper/wrap_cl.cpp index a3ab00f218fbf27f28194ee47205bd83523318ae..5021f5a13edbae729e6e2cba780541dc2b3d4df2 100644 --- a/src/c_wrapper/wrap_cl.cpp +++ b/src/c_wrapper/wrap_cl.cpp @@ -27,15 +27,6 @@ // }}} - -// {{{ equality testing - -#define PYOPENCL_EQUALITY_TESTS(cls) \ - bool operator==(cls const &other) const = delete; \ - bool operator!=(cls const &other) const = delete; - -// }}} - // {{{ more odds and ends #ifdef HAVE_GL @@ -89,33 +80,16 @@ dummy_python_gc() int (*python_gc)() = dummy_python_gc; - // {{{ platform - - class platform : public noncopyable - { - private: - cl_platform_id m_platform; - - public: - PYOPENCL_DEF_GET_CLASS_T(PLATFORM); - platform(cl_platform_id pid) - : m_platform(pid) - { } - - platform(cl_platform_id pid, bool /*retain (ignored)*/) - : m_platform(pid) - { } - - cl_platform_id data() const - { - return m_platform; - } - - PYOPENCL_EQUALITY_TESTS(platform); +// {{{ platform - generic_info get_info(cl_platform_info param_name) const - { - switch (param_name) { +class platform : public clobj<cl_platform_id> { +public: + using clobj::clobj; + PYOPENCL_DEF_GET_CLASS_T(PLATFORM); + generic_info + get_info(cl_uint param_name) const + { + switch ((cl_platform_info)param_name) { case CL_PLATFORM_PROFILE: case CL_PLATFORM_VERSION: case CL_PLATFORM_NAME: @@ -123,15 +97,15 @@ int (*python_gc)() = dummy_python_gc; #if !(defined(CL_PLATFORM_NVIDIA) && CL_PLATFORM_NVIDIA == 0x3001) case CL_PLATFORM_EXTENSIONS: #endif - return pyopencl_get_str_info(Platform, m_platform, param_name); + return pyopencl_get_str_info(Platform, data(), param_name); default: throw error("Platform.get_info", CL_INVALID_VALUE); } - } + } - pyopencl_buf<cl_device_id> get_devices(cl_device_type devtype); - }; + pyopencl_buf<cl_device_id> get_devices(cl_device_type devtype); +}; inline pyopencl_buf<cl_device_id> @@ -140,7 +114,7 @@ platform::get_devices(cl_device_type devtype) cl_uint num_devices = 0; print_call_trace("clGetDeviceIDs"); cl_int status_code; - status_code = clGetDeviceIDs(m_platform, devtype, 0, 0, &num_devices); + status_code = clGetDeviceIDs(data(), devtype, 0, 0, &num_devices); if (status_code == CL_DEVICE_NOT_FOUND) { num_devices = 0; } else if (status_code != CL_SUCCESS) { @@ -150,7 +124,7 @@ platform::get_devices(cl_device_type devtype) pyopencl_buf<cl_device_id> devices(num_devices); if (num_devices == 0) return devices; - pyopencl_call_guarded(clGetDeviceIDs, m_platform, devtype, num_devices, + pyopencl_call_guarded(clGetDeviceIDs, data(), devtype, num_devices, devices.get(), &num_devices); return devices; } @@ -158,103 +132,88 @@ platform::get_devices(cl_device_type devtype) // }}} - // {{{ device +// {{{ device - class device : public noncopyable - { - public: - PYOPENCL_DEF_GET_CLASS_T(DEVICE); - enum reference_type_t { +class device : public clobj<cl_device_id> { +public: + PYOPENCL_DEF_GET_CLASS_T(DEVICE); + enum reference_type_t { REF_NOT_OWNABLE, REF_FISSION_EXT, #if PYOPENCL_CL_VERSION >= 0x1020 REF_CL_1_2, #endif - }; + }; - private: - cl_device_id m_device; - reference_type_t m_ref_type; +private: + reference_type_t m_ref_type; - public: - device(cl_device_id did) - : m_device(did), m_ref_type(REF_NOT_OWNABLE) - { } +public: + device(cl_device_id did) + : clobj(did), m_ref_type(REF_NOT_OWNABLE) + {} - device(cl_device_id did, bool retain, reference_type_t ref_type=REF_NOT_OWNABLE) - : m_device(did), m_ref_type(ref_type) - { - if (retain && ref_type != REF_NOT_OWNABLE) - { - if (false) - { } + device(cl_device_id did, bool retain, + reference_type_t ref_type=REF_NOT_OWNABLE) + : clobj(did), m_ref_type(ref_type) + { + if (retain && ref_type != REF_NOT_OWNABLE) { + if (false) { + } #if (defined(cl_ext_device_fission) && defined(PYOPENCL_USE_DEVICE_FISSION)) - else if (ref_type == REF_FISSION_EXT) - { + else if (ref_type == REF_FISSION_EXT) { #if PYOPENCL_CL_VERSION >= 0x1020 - cl_platform_id plat; - pyopencl_call_guarded(clGetDeviceInfo, m_device, CL_DEVICE_PLATFORM, - sizeof(plat), &plat, NULL); + cl_platform_id plat; + pyopencl_call_guarded(clGetDeviceInfo, data(), + CL_DEVICE_PLATFORM, sizeof(plat), + &plat, NULL); #endif - - PYOPENCL_GET_EXT_FUN(plat, - clRetainDeviceEXT, retain_func); - - pyopencl_call_guarded(retain_func, did); - } + PYOPENCL_GET_EXT_FUN(plat, clRetainDeviceEXT, retain_func); + pyopencl_call_guarded(retain_func, did); + } #endif - #if PYOPENCL_CL_VERSION >= 0x1020 - else if (ref_type == REF_CL_1_2) - { - pyopencl_call_guarded(clRetainDevice, did); + else if (ref_type == REF_CL_1_2) { + pyopencl_call_guarded(clRetainDevice, did); } #endif - else - throw error("Device", CL_INVALID_VALUE, - "cannot own references to devices when device fission or CL 1.2 is not available"); + else { + throw error("Device", CL_INVALID_VALUE, + "cannot own references to devices when device " + "fission or CL 1.2 is not available"); + } } - } + } - ~device() - { - if (false) - { } + ~device() + { + if (false) { + } #if defined(cl_ext_device_fission) && defined(PYOPENCL_USE_DEVICE_FISSION) - else if (m_ref_type == REF_FISSION_EXT) - { + else if (m_ref_type == REF_FISSION_EXT) { #if PYOPENCL_CL_VERSION >= 0x1020 - cl_platform_id plat; - pyopencl_call_guarded(clGetDeviceInfo, m_device, CL_DEVICE_PLATFORM, - sizeof(plat), &plat, NULL); + cl_platform_id plat; + pyopencl_call_guarded(clGetDeviceInfo, data(), CL_DEVICE_PLATFORM, + sizeof(plat), &plat, NULL); #endif - - PYOPENCL_GET_EXT_FUN(plat, - clReleaseDeviceEXT, release_func); - - pyopencl_call_guarded_cleanup(release_func, m_device); + PYOPENCL_GET_EXT_FUN(plat, clReleaseDeviceEXT, release_func); + pyopencl_call_guarded_cleanup(release_func, data()); } #endif - #if PYOPENCL_CL_VERSION >= 0x1020 - else if (m_ref_type == REF_CL_1_2) - pyopencl_call_guarded(clReleaseDevice, m_device); + else if (m_ref_type == REF_CL_1_2) { + pyopencl_call_guarded(clReleaseDevice, data()); + } #endif - } - - cl_device_id data() const - { - return m_device; - } - - PYOPENCL_EQUALITY_TESTS(device); + } - generic_info get_info(cl_device_info param_name) const - { + generic_info get_info(cl_uint param_name) const + { #define DEV_GET_INT_INF(TYPE) \ - pyopencl_get_int_info(TYPE, Device, m_device, param_name) - switch (param_name) { + pyopencl_get_int_info(TYPE, Device, data(), param_name) + + switch ((cl_device_info)param_name) { case CL_DEVICE_TYPE: return DEV_GET_INT_INF(cl_device_type); case CL_DEVICE_MAX_WORK_GROUP_SIZE: @@ -265,7 +224,7 @@ platform::get_devices(cl_device_type devtype) return DEV_GET_INT_INF(cl_uint); case CL_DEVICE_MAX_WORK_ITEM_SIZES: - return pyopencl_get_array_info(size_t, Device, m_device, param_name); + return pyopencl_get_array_info(size_t, Device, data(), param_name); case CL_DEVICE_PREFERRED_VECTOR_WIDTH_CHAR: case CL_DEVICE_PREFERRED_VECTOR_WIDTH_SHORT: @@ -337,11 +296,11 @@ platform::get_devices(cl_device_type devtype) case CL_DEVICE_PROFILE: case CL_DEVICE_VERSION: case CL_DEVICE_EXTENSIONS: - return pyopencl_get_str_info(Device, m_device, param_name); + return pyopencl_get_str_info(Device, data(), param_name); case CL_DEVICE_PLATFORM: return pyopencl_get_opaque_info(cl_platform_id, platform, - Device, m_device, param_name); + Device, data(), param_name); #if PYOPENCL_CL_VERSION >= 0x1010 case CL_DEVICE_PREFERRED_VECTOR_WIDTH_HALF: case CL_DEVICE_NATIVE_VECTOR_WIDTH_CHAR: @@ -356,7 +315,7 @@ platform::get_devices(cl_device_type devtype) case CL_DEVICE_HOST_UNIFIED_MEMORY: return DEV_GET_INT_INF(cl_bool); case CL_DEVICE_OPENCL_C_VERSION: - return pyopencl_get_str_info(Device, m_device, param_name); + return pyopencl_get_str_info(Device, data(), param_name); #endif #ifdef CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV case CL_DEVICE_COMPUTE_CAPABILITY_MAJOR_NV: @@ -372,34 +331,34 @@ platform::get_devices(cl_device_type devtype) #if defined(cl_ext_device_fission) && defined(PYOPENCL_USE_DEVICE_FISSION) case CL_DEVICE_PARENT_DEVICE_EXT: return pyopencl_get_opaque_info(cl_device_id, device, - Device, m_device, param_name); + Device, data(), param_name); case CL_DEVICE_PARTITION_TYPES_EXT: case CL_DEVICE_AFFINITY_DOMAINS_EXT: case CL_DEVICE_PARTITION_STYLE_EXT: return pyopencl_get_array_info(cl_device_partition_property_ext, - Device, m_device, param_name); + Device, data(), param_name); case CL_DEVICE_REFERENCE_COUNT_EXT: return DEV_GET_INT_INF(cl_uint); #endif #if PYOPENCL_CL_VERSION >= 0x1020 case CL_DEVICE_LINKER_AVAILABLE: return DEV_GET_INT_INF(cl_bool); case CL_DEVICE_BUILT_IN_KERNELS: - return pyopencl_get_str_info(Device, m_device, param_name); + return pyopencl_get_str_info(Device, data(), param_name); case CL_DEVICE_IMAGE_MAX_BUFFER_SIZE: case CL_DEVICE_IMAGE_MAX_ARRAY_SIZE: DEV_GET_INT_INF(size_t); case CL_DEVICE_PARENT_DEVICE: return pyopencl_get_opaque_info(cl_device_id, device, - Device, m_device, param_name); + Device, data(), param_name); case CL_DEVICE_PARTITION_MAX_SUB_DEVICES: return DEV_GET_INT_INF(cl_uint); case CL_DEVICE_PARTITION_TYPE: case CL_DEVICE_PARTITION_PROPERTIES: return pyopencl_get_array_info(cl_device_partition_property, - Device, m_device, param_name); + Device, data(), param_name); case CL_DEVICE_PARTITION_AFFINITY_DOMAIN: return pyopencl_get_array_info(cl_device_affinity_domain, - Device, m_device, param_name); + Device, data(), param_name); case CL_DEVICE_REFERENCE_COUNT: DEV_GET_INT_INF(cl_uint); case CL_DEVICE_PREFERRED_INTEROP_USER_SYNC: case CL_DEVICE_PRINTF_BUFFER_SIZE: @@ -419,12 +378,12 @@ platform::get_devices(cl_device_type devtype) */ #ifdef CL_DEVICE_BOARD_NAME_AMD case CL_DEVICE_BOARD_NAME_AMD: ; - return pyopencl_get_str_info(Device, m_device, param_name); + return pyopencl_get_str_info(Device, data(), param_name); #endif #ifdef CL_DEVICE_GLOBAL_FREE_MEMORY_AMD case CL_DEVICE_GLOBAL_FREE_MEMORY_AMD: return pyopencl_get_array_info(size_t, Device, - m_device, param_name); + data(), param_name); #endif #ifdef CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD case CL_DEVICE_SIMD_PER_COMPUTE_UNIT_AMD: @@ -463,7 +422,7 @@ platform::get_devices(cl_device_type devtype) default: throw error("Device.get_info", CL_INVALID_VALUE); } - } + } // TODO: sub-devices // #if PYOPENCL_CL_VERSION >= 0x1020 @@ -533,52 +492,39 @@ platform::get_devices(cl_device_type devtype) // return py_result; // } // #endif - }; - - // }}} - - - // {{{ context - - class context : public noncopyable - { - private: - cl_context m_context; - - public: - PYOPENCL_DEF_GET_CLASS_T(CONTEXT); - context(cl_context ctx, bool retain) - : m_context(ctx) - { - if (retain) - pyopencl_call_guarded(clRetainContext, ctx); - } - +}; - ~context() - { - pyopencl_call_guarded_cleanup(clReleaseContext, m_context); - } +// }}} - cl_context data() const - { - return m_context; - } - PYOPENCL_EQUALITY_TESTS(context); +// {{{ context - generic_info get_info(cl_context_info param_name) const - { - switch (param_name) { +class context : public clobj<cl_context> { +public: + PYOPENCL_DEF_GET_CLASS_T(CONTEXT); + context(cl_context ctx, bool retain) + : clobj(ctx) + { + if (retain) { + pyopencl_call_guarded(clRetainContext, ctx); + } + } + ~context() + { + pyopencl_call_guarded_cleanup(clReleaseContext, data()); + } + generic_info get_info(cl_uint param_name) const + { + switch ((cl_context_info)param_name) { case CL_CONTEXT_REFERENCE_COUNT: return pyopencl_get_int_info(cl_uint, Context, - m_context, param_name); + data(), param_name); case CL_CONTEXT_DEVICES: return pyopencl_get_opaque_array_info( - cl_device_id, device, Context, m_context, param_name); + cl_device_id, device, Context, data(), param_name); case CL_CONTEXT_PROPERTIES: { auto result = pyopencl_get_vec_info( - cl_context_properties, Context, m_context, param_name); + cl_context_properties, Context, data(), param_name); pyopencl_buf<generic_info> py_result(result.len() / 2); size_t i = 0; for (;i < py_result.len();i++) { @@ -626,249 +572,230 @@ platform::get_devices(cl_device_type devtype) #if PYOPENCL_CL_VERSION >= 0x1010 case CL_CONTEXT_NUM_DEVICES: return pyopencl_get_int_info(cl_uint, Context, - m_context, param_name); + data(), param_name); #endif default: throw error("Context.get_info", CL_INVALID_VALUE); } - } - }; - - // }}} - - - // {{{ command_queue + } +}; - class command_queue : public noncopyable - { - private: - cl_command_queue m_queue; +// }}} - public: - PYOPENCL_DEF_GET_CLASS_T(COMMAND_QUEUE); - command_queue(cl_command_queue q, bool retain) - : m_queue(q) - { - if (retain) - pyopencl_call_guarded(clRetainCommandQueue, q); - } - command_queue(command_queue const &src) - : m_queue(src.m_queue) - { - pyopencl_call_guarded(clRetainCommandQueue, m_queue); - } +// {{{ command_queue - command_queue( - const context &ctx, - const device *py_dev=0, - cl_command_queue_properties props=0) - { +class command_queue : public clobj<cl_command_queue> { +private: + static cl_command_queue + create_command_queue(const context *ctx, const device *py_dev, + cl_command_queue_properties props) + { cl_device_id dev; if (py_dev) { dev = py_dev->data(); } else { auto devs = pyopencl_get_vec_info(cl_device_id, Context, - ctx.data(), CL_CONTEXT_DEVICES); - if (devs.len() == 0) - throw pyopencl::error("CommandQueue", CL_INVALID_VALUE, - "context doesn't have any devices? -- " - "don't know which one to default to"); + ctx->data(), CL_CONTEXT_DEVICES); + if (devs.len() == 0) { + throw pyopencl::error("CommandQueue", CL_INVALID_VALUE, + "context doesn't have any devices? -- " + "don't know which one to default to"); + } dev = devs[0]; } - m_queue = pyopencl_call_guarded(clCreateCommandQueue, - ctx.data(), dev, props); - } - - ~command_queue() - { - pyopencl_call_guarded_cleanup(clReleaseCommandQueue, m_queue); - } - - const cl_command_queue data() const - { return m_queue; } - - PYOPENCL_EQUALITY_TESTS(command_queue); + return pyopencl_call_guarded(clCreateCommandQueue, + ctx->data(), dev, props); + } +public: + PYOPENCL_DEF_GET_CLASS_T(COMMAND_QUEUE); + command_queue(cl_command_queue q, bool retain) + : clobj(q) + { + if (retain) { + pyopencl_call_guarded(clRetainCommandQueue, q); + } + } + command_queue(command_queue const &src) + : clobj(src.data()) + { + pyopencl_call_guarded(clRetainCommandQueue, data()); + } + command_queue(const context *ctx, const device *py_dev=0, + cl_command_queue_properties props=0) + : clobj(create_command_queue(ctx, py_dev, props)) + {} + ~command_queue() + { + pyopencl_call_guarded_cleanup(clReleaseCommandQueue, data()); + } - generic_info get_info(cl_command_queue_info param_name) const - { - switch (param_name) { + generic_info + get_info(cl_uint param_name) const + { + switch ((cl_command_queue_info)param_name) { case CL_QUEUE_CONTEXT: return pyopencl_get_opaque_info(cl_context, context, - CommandQueue, m_queue, param_name); + CommandQueue, data(), param_name); case CL_QUEUE_DEVICE: return pyopencl_get_opaque_info(cl_device_id, device, - CommandQueue, m_queue, param_name); + CommandQueue, data(), param_name); case CL_QUEUE_REFERENCE_COUNT: return pyopencl_get_int_info(cl_uint, CommandQueue, - m_queue, param_name); + data(), param_name); case CL_QUEUE_PROPERTIES: return pyopencl_get_int_info(cl_command_queue_properties, - CommandQueue, m_queue, param_name); + CommandQueue, data(), param_name); default: throw error("CommandQueue.get_info", CL_INVALID_VALUE); } - } + } - std::unique_ptr<context> get_context() const - { + std::unique_ptr<context> + get_context() const + { cl_context param_value; - pyopencl_call_guarded(clGetCommandQueueInfo, m_queue, CL_QUEUE_CONTEXT, + pyopencl_call_guarded(clGetCommandQueueInfo, data(), CL_QUEUE_CONTEXT, sizeof(param_value), ¶m_value, NULL); return std::unique_ptr<context>( new context(param_value, /*retain*/ true)); - } + } #if PYOPENCL_CL_VERSION < 0x1010 - cl_command_queue_properties set_property( - cl_command_queue_properties prop, - bool enable) + cl_command_queue_properties + set_property(cl_command_queue_properties prop, bool enable) { - cl_command_queue_properties old_prop; - pyopencl_call_guarded(clSetCommandQueueProperty, m_queue, prop, - cast_bool(enable), &old_prop); - return old_prop; + cl_command_queue_properties old_prop; + pyopencl_call_guarded(clSetCommandQueueProperty, data(), prop, + cast_bool(enable), &old_prop); + return old_prop; } #endif - - void flush() - { pyopencl_call_guarded(clFlush, m_queue); } - - void finish() + void + flush() { - pyopencl_call_guarded(clFinish, m_queue); + pyopencl_call_guarded(clFlush, data()); } - }; - - // }}} - - - // {{{ event - - class event : public noncopyable - { - private: - cl_event m_event; - - public: - PYOPENCL_DEF_GET_CLASS_T(EVENT); - event(cl_event event, bool retain) - : m_event(event) - { - if (retain) - pyopencl_call_guarded(clRetainEvent, event); - } - - event(event const &src) : m_event(src.m_event) - { - pyopencl_call_guarded(clRetainEvent, m_event); - } - - virtual ~event() - { - pyopencl_call_guarded_cleanup(clReleaseEvent, m_event); - } + void + finish() + { + pyopencl_call_guarded(clFinish, data()); + } +}; +// }}} - const cl_event data() const - { return m_event; } - PYOPENCL_EQUALITY_TESTS(event); +// {{{ event - generic_info get_info(cl_event_info param_name) const - { - switch (param_name) { +class event : public clobj<cl_event> { +public: + PYOPENCL_DEF_GET_CLASS_T(EVENT); + event(cl_event event, bool retain) : clobj(event) + { + if (retain) { + pyopencl_call_guarded(clRetainEvent, event); + } + } + event(event const &src) : clobj(src.data()) + { + pyopencl_call_guarded(clRetainEvent, data()); + } + ~event() + { + pyopencl_call_guarded_cleanup(clReleaseEvent, data()); + } + generic_info + get_info(cl_uint param_name) const + { + switch ((cl_event_info)param_name) { case CL_EVENT_COMMAND_QUEUE: return pyopencl_get_opaque_info(cl_command_queue, command_queue, - Event, m_event, param_name); + Event, data(), param_name); case CL_EVENT_COMMAND_TYPE: return pyopencl_get_int_info(cl_command_type, Event, - m_event, param_name); + data(), param_name); case CL_EVENT_COMMAND_EXECUTION_STATUS: - return pyopencl_get_int_info(cl_int, Event, m_event, param_name); + return pyopencl_get_int_info(cl_int, Event, data(), param_name); case CL_EVENT_REFERENCE_COUNT: - return pyopencl_get_int_info(cl_uint, Event, m_event, param_name); + return pyopencl_get_int_info(cl_uint, Event, data(), param_name); #if PYOPENCL_CL_VERSION >= 0x1010 case CL_EVENT_CONTEXT: return pyopencl_get_opaque_info(cl_context, context, - Event, m_event, param_name); + Event, data(), param_name); #endif default: throw error("Event.get_info", CL_INVALID_VALUE); } - } - - generic_info get_profiling_info(cl_profiling_info param_name) const - { + } + generic_info + get_profiling_info(cl_profiling_info param_name) const + { switch (param_name) { case CL_PROFILING_COMMAND_QUEUED: case CL_PROFILING_COMMAND_SUBMIT: case CL_PROFILING_COMMAND_START: case CL_PROFILING_COMMAND_END: return pyopencl_get_int_info(cl_ulong, EventProfiling, - m_event, param_name); + data(), param_name); default: throw error("Event.get_profiling_info", CL_INVALID_VALUE); } - } + } + + virtual void + wait() + { + pyopencl_call_guarded(clWaitForEvents, 1, &data()); + } +}; - virtual void wait() - { - pyopencl_call_guarded(clWaitForEvents, 1, &m_event); - } - }; static inline event* new_event(cl_event evt) { return pyopencl_convert_obj(event, clReleaseEvent, evt); } - // }}} - - - // {{{ memory_object - - //py::object create_mem_object_wrapper(cl_mem mem); +// }}} - class memory_object_holder : public noncopyable - { - public: - virtual const cl_mem data() const = 0; +// {{{ memory_object - PYOPENCL_EQUALITY_TESTS(memory_object_holder); +//py::object create_mem_object_wrapper(cl_mem mem); - size_t size() const - { +class memory_object_holder : public clobj<cl_mem> { +public: + using clobj::clobj; + size_t size() const + { size_t param_value; pyopencl_call_guarded(clGetMemObjectInfo, data(), CL_MEM_SIZE, sizeof(param_value), ¶m_value, NULL); return param_value; - } - - generic_info get_info(cl_mem_info param_name) - { - switch (param_name){ - case CL_MEM_TYPE: - return pyopencl_get_int_info(cl_mem_object_type, MemObject, - data(), param_name); - case CL_MEM_FLAGS: - return pyopencl_get_int_info(cl_mem_flags, MemObject, - data(), param_name); - case CL_MEM_SIZE: - return pyopencl_get_int_info(size_t, MemObject, - data(), param_name); - case CL_MEM_HOST_PTR: - throw pyopencl::error("MemoryObject.get_info", CL_INVALID_VALUE, - "Use MemoryObject.get_host_array to get " - "host pointer."); - case CL_MEM_MAP_COUNT: - case CL_MEM_REFERENCE_COUNT: - return pyopencl_get_int_info(cl_uint, MemObject, - data(), param_name); - case CL_MEM_CONTEXT: - return pyopencl_get_opaque_info(cl_context, context, - MemObject, data(), param_name); + } + generic_info + get_info(cl_uint param_name) const + { + switch ((cl_mem_info)param_name){ + case CL_MEM_TYPE: + return pyopencl_get_int_info(cl_mem_object_type, MemObject, + data(), param_name); + case CL_MEM_FLAGS: + return pyopencl_get_int_info(cl_mem_flags, MemObject, + data(), param_name); + case CL_MEM_SIZE: + return pyopencl_get_int_info(size_t, MemObject, data(), param_name); + case CL_MEM_HOST_PTR: + throw pyopencl::error("MemoryObject.get_info", CL_INVALID_VALUE, + "Use MemoryObject.get_host_array to get " + "host pointer."); + case CL_MEM_MAP_COUNT: + case CL_MEM_REFERENCE_COUNT: + return pyopencl_get_int_info(cl_uint, MemObject, + data(), param_name); + case CL_MEM_CONTEXT: + return pyopencl_get_opaque_info(cl_context, context, + MemObject, data(), param_name); #if PYOPENCL_CL_VERSION >= 0x1010 // TODO @@ -884,69 +811,63 @@ new_event(cl_event evt) // return create_mem_object_wrapper(param_value); // } - case CL_MEM_OFFSET: - return pyopencl_get_int_info(size_t, MemObject, - data(), param_name); + case CL_MEM_OFFSET: + return pyopencl_get_int_info(size_t, MemObject, data(), param_name); #endif - default: - throw error("MemoryObjectHolder.get_info", CL_INVALID_VALUE); + default: + throw error("MemoryObjectHolder.get_info", CL_INVALID_VALUE); } - } - }; - - - class memory_object : public memory_object_holder - { - private: - bool m_valid; - cl_mem m_mem; - void *m_hostbuf; - - public: - memory_object(cl_mem mem, bool retain, void *hostbuf=0) - : m_valid(true), m_mem(mem) - { - if (retain) - pyopencl_call_guarded(clRetainMemObject, mem); - - if (hostbuf) - m_hostbuf = hostbuf; - } - - memory_object(memory_object const &src) - : m_valid(true), m_mem(src.m_mem), m_hostbuf(src.m_hostbuf) - { - pyopencl_call_guarded(clRetainMemObject, m_mem); - } - - memory_object(memory_object_holder const &src) - : m_valid(true), m_mem(src.data()) - { - pyopencl_call_guarded(clRetainMemObject, m_mem); - } - - void release() - { - if (!m_valid) - throw error("MemoryObject.free", CL_INVALID_VALUE, - "trying to double-unref mem object"); - pyopencl_call_guarded_cleanup(clReleaseMemObject, m_mem); - m_valid = false; - } - - virtual ~memory_object() - { - if (m_valid) - release(); - } - - void *hostbuf() - { return m_hostbuf; } + } +}; - const cl_mem data() const - { return m_mem; } - }; +class memory_object : public memory_object_holder { +private: + bool m_valid; + void *m_hostbuf; +public: + memory_object(cl_mem mem, bool retain, void *hostbuf=0) + : m_valid(true), memory_object_holder(mem) + { + if (retain) { + pyopencl_call_guarded(clRetainMemObject, mem); + } + if (hostbuf) { + m_hostbuf = hostbuf; + } + } + memory_object(memory_object const &src) + : m_valid(true), memory_object_holder(src.data()), + m_hostbuf(src.m_hostbuf) + { + pyopencl_call_guarded(clRetainMemObject, data()); + } + memory_object(memory_object_holder const &src) + : m_valid(true), memory_object_holder(src.data()) + { + pyopencl_call_guarded(clRetainMemObject, data()); + } + void + release() + { + if (!m_valid) + throw error("MemoryObject.free", CL_INVALID_VALUE, + "trying to double-unref mem object"); + pyopencl_call_guarded_cleanup(clReleaseMemObject, data()); + m_valid = false; + } + ~memory_object() + { + if (m_valid) { + release(); + } + } + void* + hostbuf() + { + return m_hostbuf; + } +}; // #if PYOPENCL_CL_VERSION >= 0x1020 // inline @@ -1067,7 +988,7 @@ new_event(cl_event evt) #endif default: - throw error("MemoryObject.get_image_info", CL_INVALID_VALUE); + throw error("Image.get_image_info", CL_INVALID_VALUE); } } }; @@ -1077,51 +998,50 @@ new_image(cl_mem mem, void *buff=0) return pyopencl_convert_obj(image, clReleaseMemObject, mem, buff); } +// {{{ image formats - // {{{ image formats - inline generic_info - get_supported_image_formats(context const &ctx, cl_mem_flags flags, - cl_mem_object_type image_type) - { +inline generic_info +get_supported_image_formats(const context *ctx, cl_mem_flags flags, + cl_mem_object_type image_type) +{ cl_uint num_image_formats; pyopencl_call_guarded(clGetSupportedImageFormats, - ctx.data(), flags, image_type, + ctx->data(), flags, image_type, 0, NULL, &num_image_formats); pyopencl_buf<cl_image_format> formats(num_image_formats); pyopencl_call_guarded(clGetSupportedImageFormats, - ctx.data(), flags, image_type, + ctx->data(), flags, image_type, formats.len(), formats.get(), NULL); return pyopencl_convert_array_info(cl_image_format, formats); - } - +} - // }}} +// }}} - // {{{ image creation +// {{{ image creation inline image* -create_image_2d(context const &ctx, cl_mem_flags flags, - cl_image_format const &fmt, size_t width, size_t height, +create_image_2d(const context *ctx, cl_mem_flags flags, + const cl_image_format *fmt, size_t width, size_t height, size_t pitch, void *buffer, size_t size) { auto mem = retry_mem_error<cl_mem>([&] { - return pyopencl_call_guarded(clCreateImage2D, ctx.data(), flags, - &fmt, width, height, pitch, buffer); + return pyopencl_call_guarded(clCreateImage2D, ctx->data(), flags, + fmt, width, height, pitch, buffer); }); return new_image(mem, flags & CL_MEM_USE_HOST_PTR ? buffer : NULL); } inline image* -create_image_3d(context const &ctx, cl_mem_flags flags, - cl_image_format const &fmt, size_t width, size_t height, +create_image_3d(const context *ctx, cl_mem_flags flags, + const cl_image_format *fmt, size_t width, size_t height, size_t depth, size_t pitch_x, size_t pitch_y, void *buffer, size_t size) { auto mem = retry_mem_error<cl_mem>([&] { - return pyopencl_call_guarded(clCreateImage3D, ctx.data(), flags, - &fmt, width, height, depth, pitch_x, + return pyopencl_call_guarded(clCreateImage3D, ctx->data(), flags, + fmt, width, height, depth, pitch_x, pitch_y, buffer); }); return new_image(mem, flags & CL_MEM_USE_HOST_PTR ? buffer : NULL); @@ -1189,16 +1109,15 @@ create_image_3d(context const &ctx, cl_mem_flags flags, // {{{ image transfers inline event* -enqueue_read_image(command_queue &cq, image &img, size_t *origin, +enqueue_read_image(command_queue *cq, image *img, size_t *origin, size_t *region, void *buffer, size_t size, size_t row_pitch, - size_t slice_pitch, void **wait_for, uint32_t num_wait_for, - bool is_blocking) + size_t slice_pitch, const clobj_t *wait_for, + uint32_t num_wait_for, bool is_blocking) { - auto _wait_for = - pyopencl_buf<cl_event>::from_class<event>(wait_for, num_wait_for); + auto _wait_for = buf_from_class<event>(wait_for, num_wait_for); cl_event evt; retry_mem_error<void>([&] { - pyopencl_call_guarded(clEnqueueReadImage, cq.data(), img.data(), + pyopencl_call_guarded(clEnqueueReadImage, cq->data(), img->data(), cast_bool(is_blocking), origin, region, row_pitch, slice_pitch, buffer, num_wait_for, _wait_for.get(), &evt); @@ -1385,34 +1304,23 @@ enqueue_read_image(command_queue &cq, image &img, size_t *origin, #endif /* __APPLE__ */ - - - class gl_buffer : public memory_object - { - public: +class gl_buffer : public memory_object { +public: PYOPENCL_DEF_GET_CLASS_T(GL_BUFFER); gl_buffer(cl_mem mem, bool retain, void *hostbuf=0) - : memory_object(mem, retain, hostbuf) - { } - }; - - - + : memory_object(mem, retain, hostbuf) + {} +}; - class gl_renderbuffer : public memory_object - { - public: +class gl_renderbuffer : public memory_object { +public: PYOPENCL_DEF_GET_CLASS_T(GL_RENDERBUFFER); gl_renderbuffer(cl_mem mem, bool retain, void *hostbuf=0) - : memory_object(mem, retain, hostbuf) + : memory_object(mem, retain, hostbuf) { } - }; - - - +}; - class gl_texture : public image - { +class gl_texture : public image { public: gl_texture(cl_mem mem, bool retain, void *hostbuf=0) : image(mem, retain, hostbuf) @@ -1466,16 +1374,15 @@ typedef cl_int (*clEnqueueGLObjectFunc)(cl_command_queue, cl_uint, static inline event* enqueue_gl_objects(clEnqueueGLObjectFunc func, const char *name, - command_queue &cq, void **mem_objects, - uint32_t num_mem_objects, void **wait_for, + command_queue *cq, const clobj_t *mem_objects, + uint32_t num_mem_objects, const clobj_t *wait_for, uint32_t num_wait_for) { - auto _wait_for = - pyopencl_buf<cl_event>::from_class<event>(wait_for, num_wait_for); - auto _mem_objs = pyopencl_buf<cl_mem>::from_class<memory_object_holder>( + auto _wait_for = buf_from_class<event>(wait_for, num_wait_for); + auto _mem_objs = buf_from_class<memory_object_holder>( mem_objects, num_mem_objects); cl_event evt; - call_guarded(func, name, cq.data(), num_mem_objects, _mem_objs.get(), + call_guarded(func, name, cq->data(), num_mem_objects, _mem_objs.get(), num_wait_for, _wait_for.get(), &evt); return new_event(evt); } @@ -1641,14 +1548,14 @@ new_buffer(cl_mem mem, void *buff) // {{{ buffer creation inline buffer* -create_buffer(context &ctx, cl_mem_flags flags, size_t size, void *py_hostbuf) +create_buffer(context *ctx, cl_mem_flags flags, size_t size, void *py_hostbuf) { void *retained_buf_obj = 0; if (py_hostbuf != NULL && flags & CL_MEM_USE_HOST_PTR) { retained_buf_obj = py_hostbuf; } auto mem = retry_mem_error<cl_mem>([&] { - return pyopencl_call_guarded(clCreateBuffer, ctx.data(), + return pyopencl_call_guarded(clCreateBuffer, ctx->data(), flags, size, py_hostbuf); }); return new_buffer(mem, retained_buf_obj); @@ -1659,235 +1566,205 @@ create_buffer(context &ctx, cl_mem_flags flags, size_t size, void *py_hostbuf) // {{{ sampler -class sampler : public noncopyable { -private: - cl_sampler m_sampler; - +class sampler : public clobj<cl_sampler> { public: PYOPENCL_DEF_GET_CLASS_T(SAMPLER); - sampler(context const &ctx, bool normalized_coordinates, + sampler(const context *ctx, bool normalized_coordinates, cl_addressing_mode am, cl_filter_mode fm) - : m_sampler(pyopencl_call_guarded(clCreateSampler, ctx.data(), - normalized_coordinates, am, fm)) {} - + : clobj(pyopencl_call_guarded(clCreateSampler, ctx->data(), + normalized_coordinates, am, fm)) + {} sampler(cl_sampler samp, bool retain) - : m_sampler(samp) + : clobj(samp) { if (retain) { pyopencl_call_guarded(clRetainSampler, samp); } } - ~sampler() { - pyopencl_call_guarded_cleanup(clReleaseSampler, m_sampler); + pyopencl_call_guarded_cleanup(clReleaseSampler, data()); } - - cl_sampler data() const + generic_info + get_info(cl_uint param_name) const { - return m_sampler; - } - - PYOPENCL_EQUALITY_TESTS(sampler); - - generic_info get_info(cl_sampler_info param_name) const - { - switch (param_name) { + switch ((cl_sampler_info)param_name) { case CL_SAMPLER_REFERENCE_COUNT: return pyopencl_get_int_info(cl_uint, Sampler, - m_sampler, param_name); + data(), param_name); case CL_SAMPLER_CONTEXT: return pyopencl_get_opaque_info(cl_context, context, - Sampler, m_sampler, param_name); + Sampler, data(), param_name); case CL_SAMPLER_ADDRESSING_MODE: return pyopencl_get_int_info(cl_addressing_mode, Sampler, - m_sampler, param_name); + data(), param_name); case CL_SAMPLER_FILTER_MODE: return pyopencl_get_int_info(cl_filter_mode, Sampler, - m_sampler, param_name); + data(), param_name); case CL_SAMPLER_NORMALIZED_COORDS: return pyopencl_get_int_info(cl_bool, Sampler, - m_sampler, param_name); + data(), param_name); default: throw error("Sampler.get_info", CL_INVALID_VALUE); } - } - }; - - // }}} - + } +}; - // {{{ program +// }}} - class program : public noncopyable - { - private: - cl_program m_program; - program_kind_type m_program_kind; - public: - PYOPENCL_DEF_GET_CLASS_T(PROGRAM); - program(cl_program prog, bool retain, program_kind_type progkind=KND_UNKNOWN) - : m_program(prog), m_program_kind(progkind) - { - if (retain) - pyopencl_call_guarded(clRetainProgram, prog); - } - - ~program() - { - pyopencl_call_guarded_cleanup(clReleaseProgram, m_program); - } +// {{{ program - cl_program data() const - { - return m_program; - } +class program : public clobj<cl_program> { +private: + program_kind_type m_program_kind; - program_kind_type kind() const - { +public: + PYOPENCL_DEF_GET_CLASS_T(PROGRAM); + program(cl_program prog, bool retain, + program_kind_type progkind=KND_UNKNOWN) + : clobj(prog), m_program_kind(progkind) + { + if (retain) { + pyopencl_call_guarded(clRetainProgram, prog); + } + } + ~program() + { + pyopencl_call_guarded_cleanup(clReleaseProgram, data()); + } + program_kind_type + kind() const + { return m_program_kind; - } - - PYOPENCL_EQUALITY_TESTS(program); - - pyopencl_buf<cl_device_id> get_info__devices() - { - return pyopencl_get_vec_info(cl_device_id, Program, m_program, - CL_PROGRAM_DEVICES); - } - - generic_info get_info(cl_program_info param_name) const - { - switch (param_name) { - case CL_PROGRAM_CONTEXT: - return pyopencl_get_opaque_info(cl_context, context, - Program, m_program, param_name); - case CL_PROGRAM_REFERENCE_COUNT: - case CL_PROGRAM_NUM_DEVICES: - return pyopencl_get_int_info(cl_uint, Program, - m_program, param_name); - case CL_PROGRAM_DEVICES: - return pyopencl_get_opaque_array_info( - cl_device_id, device, Program, m_program, param_name); - case CL_PROGRAM_SOURCE: - return pyopencl_get_str_info(Program, m_program, param_name); - case CL_PROGRAM_BINARY_SIZES: - return pyopencl_get_array_info(size_t, Program, m_program, - param_name); - case CL_PROGRAM_BINARIES: { - auto sizes = pyopencl_get_vec_info(size_t, Program, m_program, - CL_PROGRAM_BINARY_SIZES); - pyopencl_buf<char*> result_ptrs(sizes.len()); - for (size_t i = 0;i < sizes.len();i++) { - result_ptrs[i] = (char*)malloc(sizes[i]); - } - try { - pyopencl_call_guarded(clGetProgramInfo, m_program, - CL_PROGRAM_BINARIES, - sizes.len() * sizeof(char*), - result_ptrs.get(), NULL); - } catch (...) { - for (size_t i = 0;i < sizes.len();i++) { - free(result_ptrs[i]); - } - } - pyopencl_buf<generic_info> gis(sizes.len()); - for (size_t i = 0;i < sizes.len();i++) { - gis[i].value = result_ptrs[i]; - gis[i].dontfree = 0; - gis[i].opaque_class = CLASS_NONE; - gis[i].type = _copy_str(std::string("char[") + - tostring(sizes[i]) + "]"); - } - return pyopencl_convert_array_info(generic_info, gis); - } + } + pyopencl_buf<cl_device_id> + get_info__devices() + { + return pyopencl_get_vec_info(cl_device_id, Program, data(), + CL_PROGRAM_DEVICES); + } + generic_info get_info(cl_uint param_name) const + { + switch ((cl_program_info)param_name) { + case CL_PROGRAM_CONTEXT: + return pyopencl_get_opaque_info(cl_context, context, + Program, data(), param_name); + case CL_PROGRAM_REFERENCE_COUNT: + case CL_PROGRAM_NUM_DEVICES: + return pyopencl_get_int_info(cl_uint, Program, data(), param_name); + case CL_PROGRAM_DEVICES: + return pyopencl_get_opaque_array_info( + cl_device_id, device, Program, data(), param_name); + case CL_PROGRAM_SOURCE: + return pyopencl_get_str_info(Program, data(), param_name); + case CL_PROGRAM_BINARY_SIZES: + return pyopencl_get_array_info(size_t, Program, data(), param_name); + case CL_PROGRAM_BINARIES: { + auto sizes = pyopencl_get_vec_info(size_t, Program, data(), + CL_PROGRAM_BINARY_SIZES); + pyopencl_buf<char*> result_ptrs(sizes.len()); + for (size_t i = 0;i < sizes.len();i++) { + result_ptrs[i] = (char*)malloc(sizes[i]); + } + try { + pyopencl_call_guarded(clGetProgramInfo, data(), + CL_PROGRAM_BINARIES, + sizes.len() * sizeof(char*), + result_ptrs.get(), NULL); + } catch (...) { + for (size_t i = 0;i < sizes.len();i++) { + free(result_ptrs[i]); + } + } + pyopencl_buf<generic_info> gis(sizes.len()); + for (size_t i = 0;i < sizes.len();i++) { + gis[i].value = result_ptrs[i]; + gis[i].dontfree = 0; + gis[i].opaque_class = CLASS_NONE; + gis[i].type = _copy_str(std::string("char[") + + tostring(sizes[i]) + "]"); + } + return pyopencl_convert_array_info(generic_info, gis); + } #if PYOPENCL_CL_VERSION >= 0x1020 - case CL_PROGRAM_NUM_KERNELS: - return pyopencl_get_int_info(size_t, Program, - m_program, param_name); - case CL_PROGRAM_KERNEL_NAMES: - return pyopencl_get_str_info(Program, m_program, param_name); + case CL_PROGRAM_NUM_KERNELS: + return pyopencl_get_int_info(size_t, Program, data(), param_name); + case CL_PROGRAM_KERNEL_NAMES: + return pyopencl_get_str_info(Program, data(), param_name); #endif - - default: + default: throw error("Program.get_info", CL_INVALID_VALUE); } - } - - generic_info get_build_info(device const &dev, - cl_program_build_info param_name) const - { + } + generic_info + get_build_info(const device *dev, cl_program_build_info param_name) const + { switch (param_name) { case CL_PROGRAM_BUILD_STATUS: return pyopencl_get_int_info(cl_build_status, ProgramBuild, - m_program, dev.data(), param_name); + data(), dev->data(), param_name); case CL_PROGRAM_BUILD_OPTIONS: case CL_PROGRAM_BUILD_LOG: - return pyopencl_get_str_info(ProgramBuild, m_program, - dev.data(), param_name); + return pyopencl_get_str_info(ProgramBuild, data(), + dev->data(), param_name); #if PYOPENCL_CL_VERSION >= 0x1020 case CL_PROGRAM_BINARY_TYPE: return pyopencl_get_int_info(cl_program_binary_type, ProgramBuild, - m_program, dev.data(), param_name); + data(), dev->data(), param_name); #endif default: throw error("Program.get_build_info", CL_INVALID_VALUE); } - } + } + void + build(const char *options, cl_uint num_devices, const clobj_t *ptr_devices) + { + auto devices = buf_from_class<device>(ptr_devices, num_devices); + pyopencl_call_guarded(clBuildProgram, data(), num_devices, + devices.get(), options, NULL, NULL); + } - void - build(const char *options, cl_uint num_devices, void **ptr_devices) - { - // todo: this function should get a list of device instances, - // not raw pointers pointers are for the cffi interface and - // should not be here - auto devices = pyopencl_buf<cl_device_id>::from_class<device>( - ptr_devices, num_devices); - pyopencl_call_guarded(clBuildProgram, m_program, num_devices, - devices.get(), options, NULL, NULL); - } + // #if PYOPENCL_CL_VERSION >= 0x1020 + // void compile(std::string options, py::object py_devices, + // py::object py_headers) + // { + // PYOPENCL_PARSE_PY_DEVICES; - // #if PYOPENCL_CL_VERSION >= 0x1020 - // void compile(std::string options, py::object py_devices, - // py::object py_headers) - // { - // PYOPENCL_PARSE_PY_DEVICES; - - // // {{{ pick apart py_headers - // // py_headers is a list of tuples *(name, program)* - - // std::vector<std::string> header_names; - // std::vector<cl_program> programs; - // PYTHON_FOREACH(name_hdr_tup, py_headers) - // { - // if (py::len(name_hdr_tup) != 2) - // throw error("Program.compile", CL_INVALID_VALUE, - // "epxected (name, header) tuple in headers list"); - // std::string name = py::extract<std::string const &>(name_hdr_tup[0]); - // program &prg = py::extract<program &>(name_hdr_tup[1]); - - // header_names.push_back(name); - // programs.push_back(prg.data()); - // } - - // std::vector<const char *> header_name_ptrs; - // BOOST_FOREACH(std::string const &name, header_names) - // header_name_ptrs.push_back(name.c_str()); - - // // }}} - - // PYOPENCL_CALL_GUARDED(clCompileProgram, - // (m_program, num_devices, devices, - // options.c_str(), header_names.size(), - // programs.empty() ? NULL : &programs.front(), - // header_name_ptrs.empty() ? NULL : &header_name_ptrs.front(), - // 0, 0)); - // } - // #endif - }; + // // {{{ pick apart py_headers + // // py_headers is a list of tuples *(name, program)* + + // std::vector<std::string> header_names; + // std::vector<cl_program> programs; + // PYTHON_FOREACH(name_hdr_tup, py_headers) + // { + // if (py::len(name_hdr_tup) != 2) + // throw error("Program.compile", CL_INVALID_VALUE, + // "epxected (name, header) tuple in headers list"); + // std::string name = py::extract<std::string const &>(name_hdr_tup[0]); + // program &prg = py::extract<program &>(name_hdr_tup[1]); + + // header_names.push_back(name); + // programs.push_back(prg.data()); + // } + + // std::vector<const char *> header_name_ptrs; + // BOOST_FOREACH(std::string const &name, header_names) + // header_name_ptrs.push_back(name.c_str()); + + // // }}} + + // PYOPENCL_CALL_GUARDED(clCompileProgram, + // (data(), num_devices, devices, + // options.c_str(), header_names.size(), + // programs.empty() ? NULL : &programs.front(), + // header_name_ptrs.empty() ? NULL : &header_name_ptrs.front(), + // 0, 0)); + // } + // #endif +}; static inline program* new_program(cl_program prog, program_kind_type progkind=KND_UNKNOWN) { @@ -1895,41 +1772,28 @@ new_program(cl_program prog, program_kind_type progkind=KND_UNKNOWN) } inline program* -create_program_with_source(context &ctx, const char *string) +create_program_with_source(context *ctx, const char *string) { size_t length = strlen(string); cl_program result = pyopencl_call_guarded(clCreateProgramWithSource, - ctx.data(), 1, &string, &length); + ctx->data(), 1, &string, &length); return new_program(result, KND_SOURCE); } inline program* -create_program_with_binary(context &ctx, cl_uint num_devices, - void **ptr_devices, cl_uint num_binaries, +create_program_with_binary(context *ctx, cl_uint num_devices, + const clobj_t *ptr_devices, cl_uint num_binaries, char **binaries, size_t *binary_sizes) { - std::vector<cl_device_id> devices; - std::vector<cl_int> binary_statuses(num_devices); - for (cl_uint i = 0; i < num_devices; ++i) { - devices.push_back(static_cast<device*>(ptr_devices[i])->data()); - } - cl_int status_code; - print_call_trace("clCreateProgramWithBinary"); - cl_program result = clCreateProgramWithBinary( - ctx.data(), num_devices, - devices.empty( ) ? NULL : &devices.front(), - binary_sizes, - reinterpret_cast<const unsigned char**>(const_cast<const char**>(binaries)), - binary_statuses.empty() ? NULL : &binary_statuses.front(), - &status_code); - + auto devices = buf_from_class<device>(ptr_devices, num_devices); + pyopencl_buf<cl_int> binary_statuses(num_devices); + cl_program result = pyopencl_call_guarded( + clCreateProgramWithBinary, ctx->data(), num_devices, devices.get(), + binary_sizes, reinterpret_cast<const unsigned char**>( + const_cast<const char**>(binaries)), binary_statuses.get()); // for (cl_uint i = 0; i < num_devices; ++i) // std::cout << i << ":" << binary_statuses[i] << std::endl; - - if (status_code != CL_SUCCESS) - throw pyopencl::error("clCreateProgramWithBinary", status_code); - return new_program(result, KND_BINARY); } @@ -1951,145 +1815,103 @@ public: } }; - -class kernel : public noncopyable { +class kernel : public clobj<cl_kernel> { private: cl_kernel m_kernel; public: PYOPENCL_DEF_GET_CLASS_T(KERNEL); kernel(cl_kernel knl, bool retain) - : m_kernel(knl) + : clobj(knl) { - if (retain) + if (retain) { pyopencl_call_guarded(clRetainKernel, knl); + } } - - kernel(program const &prg, const char *kernel_name) - : m_kernel(pyopencl_call_guarded(clCreateKernel, prg.data(), - kernel_name)) {} - + kernel(const program *prg, const char *kernel_name) + : clobj(pyopencl_call_guarded(clCreateKernel, prg->data(), + kernel_name)) + {} ~kernel() { - pyopencl_call_guarded_cleanup(clReleaseKernel, m_kernel); - } - - cl_kernel data() const - { - return m_kernel; + pyopencl_call_guarded_cleanup(clReleaseKernel, data()); } - - PYOPENCL_EQUALITY_TESTS(kernel); - - void set_arg_null(cl_uint arg_index) + void + set_arg_null(cl_uint arg_index) { cl_mem m = 0; - pyopencl_call_guarded(clSetKernelArg, m_kernel, arg_index, + pyopencl_call_guarded(clSetKernelArg, data(), arg_index, sizeof(cl_mem), &m); } - - void set_arg_mem(cl_uint arg_index, memory_object_holder &moh) + void + set_arg_mem(cl_uint arg_index, const memory_object_holder *mem) { - cl_mem m = moh.data(); - pyopencl_call_guarded(clSetKernelArg, m_kernel, arg_index, - sizeof(cl_mem), &m); + pyopencl_call_guarded(clSetKernelArg, data(), arg_index, + sizeof(cl_mem), &mem->data()); } - - void set_arg_local(cl_uint arg_index, local_memory const &loc) + void + set_arg_local(cl_uint arg_index, const local_memory *loc) { - pyopencl_call_guarded(clSetKernelArg, m_kernel, arg_index, - loc.size(), NULL); + pyopencl_call_guarded(clSetKernelArg, data(), arg_index, + loc->size(), NULL); } - - void set_arg_sampler(cl_uint arg_index, sampler const &smp) + void + set_arg_sampler(cl_uint arg_index, const sampler *smp) { - cl_sampler s = smp.data(); - pyopencl_call_guarded(clSetKernelArg, m_kernel, arg_index, - sizeof(cl_sampler), &s); + pyopencl_call_guarded(clSetKernelArg, data(), arg_index, + sizeof(cl_sampler), &smp->data()); } - - void set_arg_buf(cl_uint arg_index, const void *buffer, size_t size) + void + set_arg_buf(cl_uint arg_index, const void *buffer, size_t size) { - pyopencl_call_guarded(clSetKernelArg, m_kernel, arg_index, size, buffer); + pyopencl_call_guarded(clSetKernelArg, data(), arg_index, size, buffer); } - - // void set_arg(cl_uint arg_index, py::object arg) - // { - // if (arg.ptr() == Py_None) - // { - // set_arg_null(arg_index); - // return; - // } - - // py::extract<memory_object_holder &> ex_mo(arg); - // if (ex_mo.check()) - // { - // set_arg_mem(arg_index, ex_mo()); - // return; - // } - - // py::extract<local_memory const &> ex_loc(arg); - // if (ex_loc.check()) - // { - // set_arg_local(arg_index, ex_loc()); - // return; - // } - - // py::extract<sampler const &> ex_smp(arg); - // if (ex_smp.check()) - // { - // set_arg_sampler(arg_index, ex_smp()); - // return; - // } - - // set_arg_buf(arg_index, arg); - // } - - generic_info get_info(cl_kernel_info param_name) const + generic_info + get_info(cl_uint param_name) const { - switch (param_name) { - case CL_KERNEL_FUNCTION_NAME: - return pyopencl_get_str_info(Kernel, m_kernel, param_name); - case CL_KERNEL_NUM_ARGS: - case CL_KERNEL_REFERENCE_COUNT: - return pyopencl_get_int_info(cl_uint, Kernel, m_kernel, param_name); - case CL_KERNEL_CONTEXT: - return pyopencl_get_opaque_info(cl_context, context, - Kernel, m_kernel, param_name); - case CL_KERNEL_PROGRAM: - return pyopencl_get_opaque_info(cl_program, program, - Kernel, m_kernel, param_name); + switch ((cl_kernel_info)param_name) { + case CL_KERNEL_FUNCTION_NAME: + return pyopencl_get_str_info(Kernel, data(), param_name); + case CL_KERNEL_NUM_ARGS: + case CL_KERNEL_REFERENCE_COUNT: + return pyopencl_get_int_info(cl_uint, Kernel, data(), param_name); + case CL_KERNEL_CONTEXT: + return pyopencl_get_opaque_info(cl_context, context, + Kernel, data(), param_name); + case CL_KERNEL_PROGRAM: + return pyopencl_get_opaque_info(cl_program, program, + Kernel, data(), param_name); #if PYOPENCL_CL_VERSION >= 0x1020 - case CL_KERNEL_ATTRIBUTES: - return pyopencl_get_str_info(Kernel, m_kernel, param_name); + case CL_KERNEL_ATTRIBUTES: + return pyopencl_get_str_info(Kernel, data(), param_name); #endif - default: - throw error("Kernel.get_info", CL_INVALID_VALUE); - } + default: + throw error("Kernel.get_info", CL_INVALID_VALUE); + } } - - generic_info get_work_group_info(cl_kernel_work_group_info param_name, device const &dev) const + generic_info + get_work_group_info(cl_kernel_work_group_info param_name, + const device *dev) const { - switch (param_name) { + switch (param_name) { #if PYOPENCL_CL_VERSION >= 0x1010 - case CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE: + case CL_KERNEL_PREFERRED_WORK_GROUP_SIZE_MULTIPLE: #endif - case CL_KERNEL_WORK_GROUP_SIZE: - return pyopencl_get_int_info(size_t, KernelWorkGroup, - m_kernel, dev.data(), param_name); - case CL_KERNEL_COMPILE_WORK_GROUP_SIZE: - return pyopencl_get_array_info(size_t, KernelWorkGroup, - m_kernel, dev.data(), param_name); - case CL_KERNEL_LOCAL_MEM_SIZE: + case CL_KERNEL_WORK_GROUP_SIZE: + return pyopencl_get_int_info(size_t, KernelWorkGroup, + data(), dev->data(), param_name); + case CL_KERNEL_COMPILE_WORK_GROUP_SIZE: + return pyopencl_get_array_info(size_t, KernelWorkGroup, + data(), dev->data(), param_name); + case CL_KERNEL_LOCAL_MEM_SIZE: #if PYOPENCL_CL_VERSION >= 0x1010 - case CL_KERNEL_PRIVATE_MEM_SIZE: + case CL_KERNEL_PRIVATE_MEM_SIZE: #endif - return pyopencl_get_int_info(cl_ulong, KernelWorkGroup, - m_kernel, dev.data(), param_name); - - default: - throw error("Kernel.get_work_group_info", CL_INVALID_VALUE); - } + return pyopencl_get_int_info(cl_ulong, KernelWorkGroup, + data(), dev->data(), param_name); + default: + throw error("Kernel.get_work_group_info", CL_INVALID_VALUE); + } } // #if PYOPENCL_CL_VERSION >= 0x1020 @@ -2100,7 +1922,7 @@ public: // { // switch (param_name) // { - // #define PYOPENCL_FIRST_ARG m_kernel, arg_index // hackety hack + // #define PYOPENCL_FIRST_ARG data(), arg_index // hackety hack // case CL_KERNEL_ARG_ADDRESS_QUALIFIER: // PYOPENCL_GET_INTEGRAL_INFO(KernelArg, // PYOPENCL_FIRST_ARG, param_name, @@ -2120,52 +1942,49 @@ public: // } // } // #endif - }; +}; - // }}} +// }}} - // {{{ buffer transfers +// {{{ buffer transfers inline event* -enqueue_read_buffer(command_queue &cq, memory_object_holder &mem, void *buffer, - size_t size, size_t device_offset, void **wait_for, - uint32_t num_wait_for, bool is_blocking) +enqueue_read_buffer(command_queue *cq, memory_object_holder *mem, + void *buffer, size_t size, size_t device_offset, + const clobj_t *wait_for, uint32_t num_wait_for, + bool is_blocking) { - auto _wait_for = - pyopencl_buf<cl_event>::from_class<event>(wait_for, num_wait_for); + auto _wait_for = buf_from_class<event>(wait_for, num_wait_for); cl_event evt; retry_mem_error<void>([&] { - pyopencl_call_guarded(clEnqueueReadBuffer, cq.data(), mem.data(), + pyopencl_call_guarded(clEnqueueReadBuffer, cq->data(), mem->data(), cast_bool(is_blocking), device_offset, size, buffer, num_wait_for, _wait_for.get(), &evt); }); return new_event(evt); } - - inline event* -enqueue_copy_buffer(command_queue &cq, memory_object_holder &src, - memory_object_holder &dst, ptrdiff_t byte_count, +enqueue_copy_buffer(command_queue *cq, memory_object_holder *src, + memory_object_holder *dst, ptrdiff_t byte_count, size_t src_offset, size_t dst_offset, - void **wait_for, uint32_t num_wait_for) + const clobj_t *wait_for, uint32_t num_wait_for) { if (byte_count < 0) { size_t byte_count_src = 0; size_t byte_count_dst = 0; - pyopencl_call_guarded(clGetMemObjectInfo, src.data(), CL_MEM_SIZE, + pyopencl_call_guarded(clGetMemObjectInfo, src->data(), CL_MEM_SIZE, sizeof(byte_count), &byte_count_src, NULL); - pyopencl_call_guarded(clGetMemObjectInfo, src.data(), CL_MEM_SIZE, + pyopencl_call_guarded(clGetMemObjectInfo, src->data(), CL_MEM_SIZE, sizeof(byte_count), &byte_count_dst, NULL); byte_count = std::min(byte_count_src, byte_count_dst); } - auto _wait_for = - pyopencl_buf<cl_event>::from_class<event>(wait_for, num_wait_for); + auto _wait_for = buf_from_class<event>(wait_for, num_wait_for); cl_event evt; retry_mem_error<void>([&] { - pyopencl_call_guarded(clEnqueueCopyBuffer, cq.data(), src.data(), - dst.data(), src_offset, dst_offset, + pyopencl_call_guarded(clEnqueueCopyBuffer, cq->data(), src->data(), + dst->data(), src_offset, dst_offset, byte_count, num_wait_for, _wait_for.get(), &evt); }); @@ -2173,15 +1992,15 @@ enqueue_copy_buffer(command_queue &cq, memory_object_holder &src, } inline event* -enqueue_write_buffer(command_queue &cq,memory_object_holder &mem, +enqueue_write_buffer(command_queue *cq, memory_object_holder *mem, const void *buffer, size_t size, size_t device_offset, - void **wait_for, uint32_t num_wait_for, bool is_blocking) + const clobj_t *wait_for, uint32_t num_wait_for, + bool is_blocking) { - auto _wait_for = - pyopencl_buf<cl_event>::from_class<event>(wait_for, num_wait_for); + auto _wait_for = buf_from_class<event>(wait_for, num_wait_for); cl_event evt; retry_mem_error<void>([&] { - pyopencl_call_guarded(clEnqueueWriteBuffer, cq.data(), mem.data(), + pyopencl_call_guarded(clEnqueueWriteBuffer, cq->data(), mem->data(), cast_bool(is_blocking), device_offset, size, buffer, num_wait_for, _wait_for.get(), &evt); @@ -2193,18 +2012,17 @@ enqueue_write_buffer(command_queue &cq,memory_object_holder &mem, // }}} inline event* -enqueue_nd_range_kernel(command_queue &cq, kernel &knl, cl_uint work_dim, +enqueue_nd_range_kernel(command_queue *cq, kernel *knl, cl_uint work_dim, const size_t *global_work_offset, const size_t *global_work_size, const size_t *local_work_size, - void **wait_for, uint32_t num_wait_for) + const clobj_t *wait_for, uint32_t num_wait_for) { - auto _wait_for = - pyopencl_buf<cl_event>::from_class<event>(wait_for, num_wait_for); + auto _wait_for = buf_from_class<event>(wait_for, num_wait_for); cl_event evt; retry_mem_error<void>([&] { - pyopencl_call_guarded(clEnqueueNDRangeKernel, cq.data(), - knl.data(), work_dim, global_work_offset, + pyopencl_call_guarded(clEnqueueNDRangeKernel, cq->data(), + knl->data(), work_dim, global_work_offset, global_work_size, local_work_size, num_wait_for, _wait_for.get(), &evt); }); @@ -2213,42 +2031,40 @@ enqueue_nd_range_kernel(command_queue &cq, kernel &knl, cl_uint work_dim, #if PYOPENCL_CL_VERSION >= 0x1020 inline event* -enqueue_marker_with_wait_list(command_queue &cq, void **wait_for, +enqueue_marker_with_wait_list(command_queue *cq, const clobj_t *wait_for, uint32_t num_wait_for) { - auto _wait_for = - pyopencl_buf<cl_event>::from_class<event>(wait_for, num_wait_for); + auto _wait_for = buf_from_class<event>(wait_for, num_wait_for); cl_event evt; - pyopencl_call_guarded(clEnqueueMarkerWithWaitList, cq.data(), + pyopencl_call_guarded(clEnqueueMarkerWithWaitList, cq->data(), num_wait_for, _wait_for.get(), &evt); return new_event(evt); } inline event* -enqueue_barrier_with_wait_list(command_queue &cq, void **wait_for, +enqueue_barrier_with_wait_list(command_queue *cq, const clobj_t *wait_for, uint32_t num_wait_for) { - auto _wait_for = - pyopencl_buf<cl_event>::from_class<event>(wait_for, num_wait_for); + auto _wait_for = buf_from_class<event>(wait_for, num_wait_for); cl_event evt; - pyopencl_call_guarded(clEnqueueBarrierWithWaitList, cq.data(), + pyopencl_call_guarded(clEnqueueBarrierWithWaitList, cq->data(), num_wait_for, _wait_for.get(), &evt); return new_event(evt); } #endif inline event* -enqueue_marker(command_queue &cq) +enqueue_marker(command_queue *cq) { cl_event evt; - pyopencl_call_guarded(clEnqueueMarker, cq.data(), &evt); + pyopencl_call_guarded(clEnqueueMarker, cq->data(), &evt); return new_event(evt); } inline void -enqueue_barrier(command_queue &cq) +enqueue_barrier(command_queue *cq) { - pyopencl_call_guarded(clEnqueueBarrier, cq.data()); + pyopencl_call_guarded(clEnqueueBarrier, cq->data()); } } @@ -2276,7 +2092,7 @@ pyopencl_set_gc(int (*func)()) } ::error* -get_platforms(void **ptr_platforms, uint32_t *num_platforms) +get_platforms(clobj_t **ptr_platforms, uint32_t *num_platforms) { return pyopencl::c_handle_error([&] { *num_platforms = 0; @@ -2285,128 +2101,126 @@ get_platforms(void **ptr_platforms, uint32_t *num_platforms) pyopencl_call_guarded(clGetPlatformIDs, *num_platforms, platforms.get(), num_platforms); *ptr_platforms = - platforms.template to_class<pyopencl::platform>().release(); + pyopencl::buf_to_base<pyopencl::platform>(platforms).release(); }); } ::error* -platform__get_devices(void *ptr_platform, void **ptr_devices, +platform__get_devices(clobj_t platform, clobj_t **ptr_devices, uint32_t *num_devices, cl_device_type devtype) { return pyopencl::c_handle_error([&] { - auto devices = static_cast<pyopencl::platform*>(ptr_platform) + auto devices = static_cast<pyopencl::platform*>(platform) ->get_devices(devtype); *num_devices = devices.len(); - auto _ptr_devices = devices.template to_class<pyopencl::device>(); - *ptr_devices = _ptr_devices.release(); + *ptr_devices = + pyopencl::buf_to_base<pyopencl::device>(devices).release(); }); } ::error* -_create_context(void **ptr_ctx, cl_context_properties *properties, - cl_uint num_devices, void **ptr_devices) +_create_context(clobj_t *ptr_ctx, const cl_context_properties *properties, + cl_uint num_devices, const clobj_t *ptr_devices) { return pyopencl::c_handle_error([&] { - auto devices = pyopencl_buf<cl_device_id> - ::from_class<pyopencl::device>(ptr_devices, num_devices); + auto devices = pyopencl::buf_from_class<pyopencl::device>( + ptr_devices, num_devices); *ptr_ctx = new pyopencl::context( - pyopencl_call_guarded(clCreateContext, properties, - num_devices, devices.get(), - nullptr, nullptr), false); + pyopencl_call_guarded( + clCreateContext, + const_cast<cl_context_properties*>(properties), + num_devices, devices.get(), nullptr, nullptr), false); }); } ::error* -_create_command_queue(void **ptr_command_queue, void *ptr_context, - void *ptr_device, cl_command_queue_properties properties) +_create_command_queue(clobj_t *queue, clobj_t context, + clobj_t device, cl_command_queue_properties properties) { - pyopencl::context *ctx = static_cast<pyopencl::context*>(ptr_context); - pyopencl::device *dev = static_cast<pyopencl::device*>(ptr_device); + auto ctx = static_cast<pyopencl::context*>(context); + auto dev = static_cast<pyopencl::device*>(device); return pyopencl::c_handle_error([&] { - *ptr_command_queue = new pyopencl::command_queue( - *ctx, dev, properties); + *queue = new pyopencl::command_queue(ctx, dev, properties); }); } ::error* -_create_buffer(void **ptr_buffer, void *ptr_context, cl_mem_flags flags, +_create_buffer(clobj_t *buffer, clobj_t context, cl_mem_flags flags, size_t size, void *hostbuf) { - pyopencl::context *ctx = static_cast<pyopencl::context*>(ptr_context); - return pyopencl::c_handle_error([&] { - *ptr_buffer = create_buffer(*ctx, flags, size, hostbuf); - }); + auto ctx = static_cast<pyopencl::context*>(context); + return pyopencl::c_handle_error([&] { + *buffer = create_buffer(ctx, flags, size, hostbuf); + }); } // {{{ program ::error* -_create_program_with_source(void **ptr_program, void *ptr_context, - const char *src) +_create_program_with_source(clobj_t *program, clobj_t context, const char *src) { - pyopencl::context *ctx = static_cast<pyopencl::context*>(ptr_context); + auto ctx = static_cast<pyopencl::context*>(context); return pyopencl::c_handle_error([&] { - *ptr_program = create_program_with_source(*ctx, src); + *program = create_program_with_source(ctx, src); }); } ::error* _create_program_with_binary( - void **ptr_program, void *ptr_context, cl_uint num_devices, - void **ptr_devices, cl_uint num_binaries, char **binaries, + clobj_t *program, clobj_t context, cl_uint num_devices, + const clobj_t *devices, cl_uint num_binaries, char **binaries, size_t *binary_sizes) { - pyopencl::context *ctx = static_cast<pyopencl::context*>(ptr_context); + auto ctx = static_cast<pyopencl::context*>(context); return pyopencl::c_handle_error([&] { - *ptr_program = create_program_with_binary( - *ctx, num_devices, ptr_devices, num_binaries, - reinterpret_cast<char**>(binaries), binary_sizes); + *program = create_program_with_binary( + ctx, num_devices, devices, + num_binaries, binaries, binary_sizes); }); } ::error* -program__build(void *ptr_program, const char *options, cl_uint num_devices, - void **ptr_devices) +program__build(clobj_t program, const char *options, + cl_uint num_devices, const clobj_t *devices) { return pyopencl::c_handle_error([&] { - static_cast<pyopencl::program*>(ptr_program)->build( - options, num_devices, ptr_devices); + static_cast<pyopencl::program*>(program)->build( + options, num_devices, devices); }); } ::error* -program__kind(void *ptr_program, int *kind) +program__kind(clobj_t program, int *kind) { return pyopencl::c_handle_error([&] { - *kind = static_cast<pyopencl::program*>(ptr_program)->kind(); + *kind = static_cast<pyopencl::program*>(program)->kind(); }); } ::error* -program__get_build_info(void *ptr_program, void *ptr_device, +program__get_build_info(clobj_t program, clobj_t device, cl_program_build_info param, generic_info *out) { return pyopencl::c_handle_error([&] { - *out = static_cast<pyopencl::program*>(ptr_program) + *out = static_cast<pyopencl::program*>(program) ->get_build_info( - *static_cast<pyopencl::device*>(ptr_device), param); + static_cast<pyopencl::device*>(device), param); }); } // }}} ::error* -_create_sampler(void **ptr_sampler, void *ptr_context, - int normalized_coordinates, cl_addressing_mode am, - cl_filter_mode fm) +_create_sampler(clobj_t *sampler, clobj_t context, int normalized_coordinates, + cl_addressing_mode am, cl_filter_mode fm) { return pyopencl::c_handle_error([&] { - *ptr_sampler = new pyopencl::sampler( - *static_cast<pyopencl::context*>(ptr_context), + *sampler = new pyopencl::sampler( + static_cast<pyopencl::context*>(context), (bool)normalized_coordinates, am, fm); }); } @@ -2414,19 +2228,20 @@ _create_sampler(void **ptr_sampler, void *ptr_context, // {{{ event ::error* -event__get_profiling_info(void *ptr, cl_profiling_info param, generic_info *out) +event__get_profiling_info(clobj_t event, cl_profiling_info param, + generic_info *out) { return pyopencl::c_handle_error([&] { - *out = static_cast<pyopencl::event*>(ptr) + *out = static_cast<pyopencl::event*>(event) ->get_profiling_info(param); }); } ::error* -event__wait(void *ptr) +event__wait(clobj_t event) { return pyopencl::c_handle_error([&] { - static_cast<pyopencl::event*>(ptr)->wait(); + static_cast<pyopencl::event*>(event)->wait(); }); } @@ -2436,62 +2251,61 @@ event__wait(void *ptr) // {{{ kernel ::error* -_create_kernel(void **ptr_kernel, void *ptr_program, const char *name) +_create_kernel(clobj_t *kernel, clobj_t program, const char *name) { - pyopencl::program *prg = static_cast<pyopencl::program*>(ptr_program); + auto prg = static_cast<pyopencl::program*>(program); return pyopencl::c_handle_error([&] { - *ptr_kernel = new pyopencl::kernel(*prg, name); + *kernel = new pyopencl::kernel(prg, name); }); } ::error* -kernel__set_arg_null(void *ptr_kernel, cl_uint arg_index) +kernel__set_arg_null(clobj_t kernel, cl_uint arg_index) { return pyopencl::c_handle_error([&] { - static_cast<pyopencl::kernel*>(ptr_kernel)->set_arg_null(arg_index); + static_cast<pyopencl::kernel*>(kernel)->set_arg_null(arg_index); }); } ::error* -kernel__set_arg_mem(void *ptr_kernel, cl_uint arg_index, void *ptr_mem) +kernel__set_arg_mem(clobj_t kernel, cl_uint arg_index, clobj_t _mem) { - pyopencl::memory_object_holder *mem = - static_cast<pyopencl::memory_object_holder*>(ptr_mem); + auto mem = static_cast<pyopencl::memory_object_holder*>(_mem); return pyopencl::c_handle_error([&] { - static_cast<pyopencl::kernel*>(ptr_kernel) - ->set_arg_mem(arg_index, *mem); + static_cast<pyopencl::kernel*>(kernel) + ->set_arg_mem(arg_index, mem); }); } ::error* -kernel__set_arg_sampler(void *ptr_kernel, cl_uint arg_index, void *ptr_sampler) +kernel__set_arg_sampler(clobj_t kernel, cl_uint arg_index, clobj_t sampler) { - pyopencl::sampler *sampler = static_cast<pyopencl::sampler*>(ptr_sampler); return pyopencl::c_handle_error([&] { - static_cast<pyopencl::kernel*>(ptr_kernel) - ->set_arg_sampler(arg_index, *sampler); + static_cast<pyopencl::kernel*>(kernel) + ->set_arg_sampler(arg_index, + static_cast<pyopencl::sampler*>(sampler)); }); } ::error* -kernel__set_arg_buf(void *ptr_kernel, cl_uint arg_index, +kernel__set_arg_buf(clobj_t kernel, cl_uint arg_index, const void *buffer, size_t size) { return pyopencl::c_handle_error([&] { - static_cast<pyopencl::kernel*>(ptr_kernel) + static_cast<pyopencl::kernel*>(kernel) ->set_arg_buf(arg_index, buffer, size); }); } ::error* -kernel__get_work_group_info(void *ptr, cl_kernel_work_group_info param, - void *ptr_device, generic_info *out) +kernel__get_work_group_info(clobj_t kernel, cl_kernel_work_group_info param, + clobj_t device, generic_info *out) { return pyopencl::c_handle_error([&] { - *out = static_cast<pyopencl::kernel*>(ptr) - ->get_work_group_info(param, *static_cast<pyopencl::device*>( - ptr_device)); + *out = static_cast<pyopencl::kernel*>(kernel) + ->get_work_group_info(param, static_cast<pyopencl::device*>( + device)); }); } @@ -2501,60 +2315,61 @@ kernel__get_work_group_info(void *ptr, cl_kernel_work_group_info param, // {{{ image ::error* -_get_supported_image_formats(void *ptr_context, cl_mem_flags flags, +_get_supported_image_formats(clobj_t context, cl_mem_flags flags, cl_mem_object_type image_type, generic_info *out) { return pyopencl::c_handle_error([&] { *out = get_supported_image_formats( - *static_cast<pyopencl::context*>(ptr_context), - flags, image_type); + static_cast<pyopencl::context*>(context), flags, image_type); }); } -error *_create_image_2d( - void **ptr_image, void *ptr_context, cl_mem_flags flags, - cl_image_format *fmt, size_t width, size_t height, size_t pitch, - void *ptr_buffer, size_t size) +::error* +_create_image_2d(clobj_t *image, clobj_t context, cl_mem_flags flags, + cl_image_format *fmt, size_t width, size_t height, + size_t pitch, void *buffer, size_t size) { return pyopencl::c_handle_error([&] { - *ptr_image = create_image_2d( - *static_cast<pyopencl::context*>(ptr_context), flags, *fmt, - width, height, pitch, ptr_buffer, size); + *image = create_image_2d( + static_cast<pyopencl::context*>(context), flags, fmt, + width, height, pitch, buffer, size); }); } -error *_create_image_3d( - void **ptr_image, void *ptr_context, cl_mem_flags flags, - cl_image_format *fmt, size_t width, size_t height, size_t depth, - size_t pitch_x, size_t pitch_y, void *ptr_buffer, size_t size) +::error* +_create_image_3d(clobj_t *image, clobj_t context, cl_mem_flags flags, + cl_image_format *fmt, size_t width, size_t height, + size_t depth, size_t pitch_x, size_t pitch_y, + void *buffer, size_t size) { return pyopencl::c_handle_error([&] { - *ptr_image = create_image_3d( - *static_cast<pyopencl::context*>(ptr_context), flags, *fmt, - width, height, depth, pitch_x, pitch_y, ptr_buffer, size); + *image = create_image_3d( + static_cast<pyopencl::context*>(context), flags, fmt, + width, height, depth, pitch_x, pitch_y, buffer, size); }); } ::error* -image__get_image_info(void *ptr, cl_image_info param, generic_info *out) +image__get_image_info(clobj_t image, cl_image_info param, generic_info *out) { return pyopencl::c_handle_error([&] { - *out = static_cast<pyopencl::image*>(ptr)->get_image_info(param); + *out = static_cast<pyopencl::image*>(image)->get_image_info(param); }); } // }}} -::error *_enqueue_nd_range_kernel( - void **ptr_event, void *ptr_command_queue, void *ptr_kernel, - cl_uint work_dim, const size_t *global_work_offset, - const size_t *global_work_size, const size_t *local_work_size, - void **wait_for, uint32_t num_wait_for) +::error* +_enqueue_nd_range_kernel(clobj_t *event, clobj_t queue, clobj_t kernel, + cl_uint work_dim, const size_t *global_work_offset, + const size_t *global_work_size, + const size_t *local_work_size, + const clobj_t *wait_for, uint32_t num_wait_for) { return pyopencl::c_handle_error([&] { - *ptr_event = enqueue_nd_range_kernel( - *static_cast<pyopencl::command_queue*>(ptr_command_queue), - *static_cast<pyopencl::kernel*>(ptr_kernel), + *event = enqueue_nd_range_kernel( + static_cast<pyopencl::command_queue*>(queue), + static_cast<pyopencl::kernel*>(kernel), work_dim, global_work_offset, global_work_size, local_work_size, wait_for, num_wait_for); @@ -2562,71 +2377,73 @@ image__get_image_info(void *ptr, cl_image_info param, generic_info *out) } #if PYOPENCL_CL_VERSION >= 0x1020 -::error *_enqueue_marker_with_wait_list( - void **ptr_event, void *ptr_command_queue, void **wait_for, - uint32_t num_wait_for) +::error* +_enqueue_marker_with_wait_list(clobj_t *event, clobj_t queue, + const clobj_t *wait_for, uint32_t num_wait_for) { return pyopencl::c_handle_error([&] { - *ptr_event = enqueue_marker_with_wait_list( - *static_cast<pyopencl::command_queue*>(ptr_command_queue), + *event = enqueue_marker_with_wait_list( + static_cast<pyopencl::command_queue*>(queue), wait_for, num_wait_for); }); } ::error* -_enqueue_barrier_with_wait_list(void **ptr_event, void *ptr_command_queue, - void **wait_for, uint32_t num_wait_for) +_enqueue_barrier_with_wait_list(clobj_t *event, clobj_t queue, + const clobj_t *wait_for, uint32_t num_wait_for) { return pyopencl::c_handle_error([&] { - *ptr_event = enqueue_barrier_with_wait_list( - *static_cast<pyopencl::command_queue*>(ptr_command_queue), + *event = enqueue_barrier_with_wait_list( + static_cast<pyopencl::command_queue*>(queue), wait_for, num_wait_for); }); } #endif -::error *_enqueue_marker(void **ptr_event, void *ptr_command_queue) +::error* +_enqueue_marker(clobj_t *event, clobj_t queue) { return pyopencl::c_handle_error([&] { - *ptr_event = enqueue_marker( - *static_cast<pyopencl::command_queue*>(ptr_command_queue)); + *event = enqueue_marker( + static_cast<pyopencl::command_queue*>(queue)); }); } -::error *_enqueue_barrier(void *ptr_command_queue) +::error* +_enqueue_barrier(clobj_t queue) { return pyopencl::c_handle_error([&] { - enqueue_barrier(*static_cast<pyopencl::command_queue*>( - ptr_command_queue)); + enqueue_barrier(static_cast<pyopencl::command_queue*>(queue)); }); } // {{{ transfer enqueues -::error *_enqueue_read_buffer( - void **ptr_event, void *ptr_command_queue, void *ptr_memory_object_holder, - void *buffer, size_t size, size_t device_offset, void **wait_for, - uint32_t num_wait_for, int is_blocking) +::error* +_enqueue_read_buffer(clobj_t *event, clobj_t queue, clobj_t mem, + void *buffer, size_t size, size_t device_offset, + const clobj_t *wait_for, uint32_t num_wait_for, + int is_blocking) { return pyopencl::c_handle_error([&] { - *ptr_event = enqueue_read_buffer( - *static_cast<pyopencl::command_queue*>(ptr_command_queue), - *static_cast<pyopencl::memory_object_holder*>( - ptr_memory_object_holder), + *event = enqueue_read_buffer( + static_cast<pyopencl::command_queue*>(queue), + static_cast<pyopencl::memory_object_holder*>(mem), buffer, size, device_offset, wait_for, num_wait_for, (bool)is_blocking); }); } -::error *_enqueue_write_buffer( - void **ptr_event, void *ptr_command_queue, void *ptr_mem, - const void *buffer, size_t size, size_t device_offset, void **wait_for, - uint32_t num_wait_for, int is_blocking) +::error* +_enqueue_write_buffer(clobj_t *event, clobj_t queue, clobj_t mem, + const void *buffer, size_t size, size_t device_offset, + const clobj_t *wait_for, uint32_t num_wait_for, + int is_blocking) { return pyopencl::c_handle_error([&] { - *ptr_event = enqueue_write_buffer( - *static_cast<pyopencl::command_queue*>(ptr_command_queue), - *static_cast<pyopencl::memory_object_holder*>(ptr_mem), + *event = enqueue_write_buffer( + static_cast<pyopencl::command_queue*>(queue), + static_cast<pyopencl::memory_object_holder*>(mem), buffer, size, device_offset, wait_for, num_wait_for, (bool)is_blocking); }); @@ -2634,30 +2451,31 @@ _enqueue_barrier_with_wait_list(void **ptr_event, void *ptr_command_queue, ::error* -_enqueue_copy_buffer(void **ptr_event, void *ptr_command_queue, void *ptr_src, - void *ptr_dst, ptrdiff_t byte_count, size_t src_offset, - size_t dst_offset, void **wait_for, uint32_t num_wait_for) +_enqueue_copy_buffer(clobj_t *event, clobj_t queue, clobj_t src, clobj_t dst, + ptrdiff_t byte_count, size_t src_offset, size_t dst_offset, + const clobj_t *wait_for, uint32_t num_wait_for) { return pyopencl::c_handle_error([&] { - *ptr_event = enqueue_copy_buffer( - *static_cast<pyopencl::command_queue*>(ptr_command_queue), - *static_cast<pyopencl::memory_object_holder*>(ptr_src), - *static_cast<pyopencl::memory_object_holder*>(ptr_dst), + *event = enqueue_copy_buffer( + static_cast<pyopencl::command_queue*>(queue), + static_cast<pyopencl::memory_object_holder*>(src), + static_cast<pyopencl::memory_object_holder*>(dst), byte_count, src_offset, dst_offset, wait_for, num_wait_for); }); } ::error* -_enqueue_read_image(void **ptr_event, void *ptr_command_queue, void *ptr_mem, +_enqueue_read_image(clobj_t *event, clobj_t queue, clobj_t mem, size_t *origin, size_t *region, void *buffer, size_t size, - size_t row_pitch, size_t slice_pitch, void **wait_for, - uint32_t num_wait_for, int is_blocking) + size_t row_pitch, size_t slice_pitch, + const clobj_t *wait_for, uint32_t num_wait_for, + int is_blocking) { return pyopencl::c_handle_error([&] { - *ptr_event = enqueue_read_image( - *static_cast<pyopencl::command_queue*>(ptr_command_queue), - *static_cast<pyopencl::image*>(ptr_mem), + *event = enqueue_read_image( + static_cast<pyopencl::command_queue*>(queue), + static_cast<pyopencl::image*>(mem), origin, region, buffer, size, row_pitch, slice_pitch, wait_for, num_wait_for, (bool)is_blocking); }); @@ -2666,29 +2484,29 @@ _enqueue_read_image(void **ptr_event, void *ptr_command_queue, void *ptr_mem, // }}} ::error* -_command_queue_finish(void *ptr_command_queue) +_command_queue_finish(clobj_t queue) { return pyopencl::c_handle_error([&] { - static_cast<pyopencl::command_queue*>(ptr_command_queue)->finish(); + static_cast<pyopencl::command_queue*>(queue)->finish(); }); } ::error* -_command_queue_flush(void *ptr_command_queue) +_command_queue_flush(clobj_t queue) { return pyopencl::c_handle_error([&] { - static_cast<pyopencl::command_queue*>(ptr_command_queue)->flush(); + static_cast<pyopencl::command_queue*>(queue)->flush(); }); } intptr_t -_int_ptr(void* ptr, class_t class_) +_int_ptr(clobj_t obj) { -#define INT_PTR(CLSU, CLS) return (intptr_t)(static_cast<pyopencl::CLS*>(ptr)->data()); - SWITCHCLASS(INT_PTR); + return obj->intptr(); } -void* _from_int_ptr(void **ptr_out, intptr_t int_ptr_value, class_t class_) +::error* +_from_int_ptr(clobj_t *ptr_out, intptr_t int_ptr_value, class_t class_) { #define FROM_INT_PTR(CLSU, CLS) \ *ptr_out = new pyopencl::CLS((PYOPENCL_CL_##CLSU)int_ptr_value, \ @@ -2699,38 +2517,29 @@ void* _from_int_ptr(void **ptr_out, intptr_t int_ptr_value, class_t class_) }); } -long _hash(void *ptr, class_t class_) -{ -#define HASH(CLSU, CLS) \ - return intptr_t(static_cast<pyopencl::CLS*>(ptr)->data()); - SWITCHCLASS(HASH); -} - ::error* -_get_info(void *ptr, class_t class_, cl_uint param, generic_info *out) +_get_info(clobj_t obj, cl_uint param, generic_info *out) { -#define GET_INFO(CLSU, CLS) \ - *out = static_cast<pyopencl::CLS*>(ptr)->get_info(param); - return pyopencl::c_handle_error([&] { - SWITCHCLASS(GET_INFO); + *out = obj->get_info(param); }); } -void _delete(void *ptr, class_t class_) { -#define DELETE(CLSU, CLS) delete static_cast<pyopencl::CLS*>(ptr); - SWITCHCLASS(DELETE); +void +_delete(clobj_t obj) +{ + delete obj; } ::error* -_release_memobj(void *ptr) +_release_memobj(clobj_t obj) { return pyopencl::c_handle_error([&] { - static_cast<pyopencl::memory_object*>(ptr)->release(); + static_cast<pyopencl::memory_object*>(obj)->release(); }); } -int pyopencl_get_cl_version(void) +int pyopencl_get_cl_version() { return PYOPENCL_CL_VERSION; } @@ -2747,10 +2556,11 @@ int pyopencl_have_gl() } #ifdef HAVE_GL -error *_create_from_gl_buffer( - void **ptr, void *ptr_context, cl_mem_flags flags, GLuint bufobj) +error* +_create_from_gl_buffer(clobj_t *ptr, clobj_t context, + cl_mem_flags flags, GLuint bufobj) { - pyopencl::context *ctx = static_cast<pyopencl::context*>(ptr_context); + auto ctx = static_cast<pyopencl::context*>(context); return pyopencl::c_handle_error([&] { cl_mem mem = pyopencl_call_guarded(clCreateFromGLBuffer, ctx->data(), flags, bufobj); @@ -2759,10 +2569,11 @@ error *_create_from_gl_buffer( }); } -error *_create_from_gl_renderbuffer( - void **ptr, void *ptr_context, cl_mem_flags flags, GLuint bufobj) +error* +_create_from_gl_renderbuffer(clobj_t *ptr, clobj_t context, + cl_mem_flags flags, GLuint bufobj) { - pyopencl::context *ctx = static_cast<pyopencl::context*>(ptr_context); + auto ctx = static_cast<pyopencl::context*>(context); return pyopencl::c_handle_error([&] { cl_mem mem = pyopencl_call_guarded(clCreateFromGLRenderbuffer, ctx->data(), flags, bufobj); @@ -2771,29 +2582,29 @@ error *_create_from_gl_renderbuffer( }); } -::error *_enqueue_acquire_gl_objects( - void **ptr_event, void *ptr_command_queue, - void **ptr_mem_objects, uint32_t num_mem_objects, void **wait_for, - uint32_t num_wait_for) +::error* +_enqueue_acquire_gl_objects(clobj_t *event, clobj_t queue, + const clobj_t *mem_objects, + uint32_t num_mem_objects, + const clobj_t *wait_for, uint32_t num_wait_for) { return pyopencl::c_handle_error([&] { - *ptr_event = enqueue_gl_objects( - Acquire, *static_cast<pyopencl::command_queue*>( - ptr_command_queue), ptr_mem_objects, num_mem_objects, - wait_for, num_wait_for); + *event = enqueue_gl_objects( + Acquire, static_cast<pyopencl::command_queue*>(queue), + mem_objects, num_mem_objects, wait_for, num_wait_for); }); } ::error* -_enqueue_release_gl_objects(void **ptr_event, void *ptr_command_queue, - void **ptr_mem_objects, uint32_t num_mem_objects, - void **wait_for, uint32_t num_wait_for) +_enqueue_release_gl_objects(clobj_t *event, clobj_t queue, + const clobj_t *mem_objects, + uint32_t num_mem_objects, + const clobj_t *wait_for, uint32_t num_wait_for) { return pyopencl::c_handle_error([&] { - *ptr_event = enqueue_gl_objects( - Release, *static_cast<pyopencl::command_queue*>( - ptr_command_queue), ptr_mem_objects, num_mem_objects, - wait_for, num_wait_for); + *event = enqueue_gl_objects( + Release, static_cast<pyopencl::command_queue*>(queue), + mem_objects, num_mem_objects, wait_for, num_wait_for); }); } #endif /* HAVE_GL */ diff --git a/src/c_wrapper/wrap_cl.h b/src/c_wrapper/wrap_cl.h index ee029fbf87679ab64bac267c64827f08fefdf005..fabbb6c4fa545a97bb7688eaba49cbff6e9ccc14 100644 --- a/src/c_wrapper/wrap_cl.h +++ b/src/c_wrapper/wrap_cl.h @@ -59,6 +59,11 @@ #endif +namespace pyopencl { +struct clbase; +} +typedef pyopencl::clbase *clobj_t; + #ifdef __cplusplus extern "C" { #endif