diff --git a/pyopencl/_cffi.py b/pyopencl/_cffi.py index 06c2e9121d8d2abb75c5cb4b108605d78af0d199..5c23341ee0da76de4bcf86c927bcd1ea93ffeb62 100644 --- a/pyopencl/_cffi.py +++ b/pyopencl/_cffi.py @@ -81,6 +81,16 @@ typedef cl_uint cl_event_info; typedef cl_uint cl_command_type; typedef cl_uint cl_profiling_info; +typedef struct _cl_image_format { + cl_channel_order image_channel_order; + cl_channel_type image_channel_data_type; +} cl_image_format; + +typedef struct _cl_buffer_region { + size_t origin; + size_t size; +} cl_buffer_region; + """ with open(os.path.join(current_directory, 'wrap_cl_core.h')) as _f: diff --git a/pyopencl/_init.py b/pyopencl/_init.py index 704dd7b499d4359170790898129b679d0ad8d0da..3b110de7f7d859ad4d9412c1049a13a7faf6270a 100644 --- a/pyopencl/_init.py +++ b/pyopencl/_init.py @@ -510,31 +510,31 @@ def _add_functionality(): # }}} - # # {{{ ImageFormat + # {{{ ImageFormat - # def image_format_repr(self): - # return "ImageFormat(%s, %s)" % ( - # channel_order.to_string(self.channel_order, - # ""), - # channel_type.to_string(self.channel_data_type, - # "")) + def image_format_repr(self): + return "ImageFormat(%s, %s)" % ( + channel_order.to_string(self.channel_order, + ""), + channel_type.to_string(self.channel_data_type, + "")) - # def image_format_eq(self, other): - # return (self.channel_order == other.channel_order - # and self.channel_data_type == other.channel_data_type) + def image_format_eq(self, other): + return (self.channel_order == other.channel_order + and self.channel_data_type == other.channel_data_type) - # def image_format_ne(self, other): - # return not image_format_eq(self, other) + def image_format_ne(self, other): + return not image_format_eq(self, other) - # def image_format_hash(self): - # return hash((type(self), self.channel_order, self.channel_data_type)) + def image_format_hash(self): + return hash((type(self), self.channel_order, self.channel_data_type)) - # ImageFormat.__repr__ = image_format_repr - # ImageFormat.__eq__ = image_format_eq - # ImageFormat.__ne__ = image_format_ne - # ImageFormat.__hash__ = image_format_hash + ImageFormat.__repr__ = image_format_repr + ImageFormat.__eq__ = image_format_eq + ImageFormat.__ne__ = image_format_ne + ImageFormat.__hash__ = image_format_hash - # # }}} + # }}} # # {{{ Image diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py index 7c7b63bdbf3f11b2f2b6773da9d5e24103f95289..24f64704a892eb218b1f896383717fb3fe0c465f 100644 --- a/pyopencl/cffi_cl.py +++ b/pyopencl/cffi_cl.py @@ -166,7 +166,7 @@ def _parse_context_properties(properties): else: raise RuntimeError("Context", status_code.INVALID_VALUE, "invalid context property") props.append(0) - return _ffi.new('intptr_t[]', props) + return _ffi.new('cl_context_properties[]', props) class Context(_Common): @@ -336,6 +336,8 @@ def _generic_info_to_python(info): ret = ''.join(a[0] for a in value) elif type_.startswith('generic_info['): ret = list(map(_generic_info_to_python, value)) + elif type_.startswith('cl_image_format['): + ret = [ImageFormat(imf.image_channel_order, imf.image_channel_data_type) for imf in value] else: ret = list(value) else: @@ -532,6 +534,66 @@ def _create_gl_enqueue(what): enqueue_acquire_gl_objects = _create_gl_enqueue(_lib._enqueue_acquire_gl_objects) enqueue_release_gl_objects = _create_gl_enqueue(_lib._enqueue_release_gl_objects) +class ImageFormat(object): + def __init__(self, channel_order=0, channel_type=0): + self.channel_order = channel_order + self.channel_data_type = channel_type + + @property + def channel_count(self): + try: + return { + channel_order.R: 1, + channel_order.A: 1, + channel_order.RG: 2, + channel_order.RA: 2, + channel_order.RGB: 3, + channel_order.RGBA: 4, + channel_order.BGRA: 4, + channel_order.INTENSITY: 1, + channel_order.LUMINANCE: 1, + }[self.channel_order] + except KeyError: + raise LogicError("ImageFormat.channel_count", + status_code.INVALID_VALUE, + "unrecognized channel order") + + @property + def dtype_size(self): + try: + return { + channel_type.SNORM_INT8: 1, + channel_type.SNORM_INT16: 2, + channel_type.UNORM_INT8: 1, + channel_type.UNORM_INT16: 2, + channel_type.UNORM_SHORT_565: 2, + channel_type.UNORM_SHORT_555: 2, + channel_type.UNORM_INT_101010: 4, + channel_type.SIGNED_INT8: 1, + channel_type.SIGNED_INT16: 2, + channel_type.SIGNED_INT32: 4, + channel_type.UNSIGNED_INT8: 1, + channel_type.UNSIGNED_INT16: 2, + channel_type.UNSIGNED_INT32: 4, + channel_type.HALF_FLOAT: 2, + channel_type.FLOAT: 4, + }[self.channel_data_type] + except KeyError: + raise LogicError("ImageFormat.channel_dtype_size", + status_code.INVALID_VALUE, + "unrecognized channel data type") + + @property + def itemsize(self): + return self.channel_count * self.dtype_size + + +def get_supported_image_formats(context, flags, image_type): + info = _ffi.new('generic_info *') + _handle_error(_lib._get_supported_image_formats(context.ptr, flags, image_type, info)) + return _generic_info_to_python(info) + + class Image(MemoryObject): _id = 'image' diff --git a/src/c_wrapper/wrap_cl.cpp b/src/c_wrapper/wrap_cl.cpp index a42497365adfefbbf804c68e9daad895881d7293..8c3c027e97a77c0372b84c4dc07eee7848352409 100644 --- a/src/c_wrapper/wrap_cl.cpp +++ b/src/c_wrapper/wrap_cl.cpp @@ -1348,90 +1348,23 @@ namespace pyopencl -// // {{{ image formats - -// inline -// cl_image_format *make_image_format(cl_channel_order ord, cl_channel_type tp) -// { -// std::auto_ptr result(new cl_image_format); -// result->image_channel_order = ord; -// result->image_channel_data_type = tp; -// return result.release(); -// } - -// inline -// py::list get_supported_image_formats( -// context const &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, -// 0, NULL, &num_image_formats)); - -// std::vector formats(num_image_formats); -// PYOPENCL_CALL_GUARDED(clGetSupportedImageFormats, ( -// ctx.data(), flags, image_type, -// formats.size(), formats.empty( ) ? NULL : &formats.front(), NULL)); - -// PYOPENCL_RETURN_VECTOR(cl_image_format, formats); -// } - -// inline -// cl_uint get_image_format_channel_count(cl_image_format const &fmt) -// { -// switch (fmt.image_channel_order) -// { -// case CL_R: return 1; -// case CL_A: return 1; -// case CL_RG: return 2; -// case CL_RA: return 2; -// case CL_RGB: return 3; -// case CL_RGBA: return 4; -// case CL_BGRA: return 4; -// case CL_INTENSITY: return 1; -// case CL_LUMINANCE: return 1; -// default: -// throw pyopencl::error("ImageFormat.channel_dtype_size", -// CL_INVALID_VALUE, -// "unrecognized channel order"); -// } -// } - -// inline -// cl_uint get_image_format_channel_dtype_size(cl_image_format const &fmt) -// { -// switch (fmt.image_channel_data_type) -// { -// case CL_SNORM_INT8: return 1; -// case CL_SNORM_INT16: return 2; -// case CL_UNORM_INT8: return 1; -// case CL_UNORM_INT16: return 2; -// case CL_UNORM_SHORT_565: return 2; -// case CL_UNORM_SHORT_555: return 2; -// case CL_UNORM_INT_101010: return 4; -// case CL_SIGNED_INT8: return 1; -// case CL_SIGNED_INT16: return 2; -// case CL_SIGNED_INT32: return 4; -// case CL_UNSIGNED_INT8: return 1; -// case CL_UNSIGNED_INT16: return 2; -// case CL_UNSIGNED_INT32: return 4; -// case CL_HALF_FLOAT: return 2; -// case CL_FLOAT: return 4; -// default: -// throw pyopencl::error("ImageFormat.channel_dtype_size", -// CL_INVALID_VALUE, -// "unrecognized channel data type"); -// } -// } + // {{{ image formats + inline + generic_info get_supported_image_formats(context const &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, + 0, NULL, &num_image_formats)); + + std::vector formats(num_image_formats); + PYOPENCL_CALL_GUARDED(clGetSupportedImageFormats, + (ctx.data(), flags, image_type, + formats.size(), formats.empty( ) ? NULL : &formats.front(), NULL)); + + PYOPENCL_GET_ARRAY_INFO(cl_image_format, formats); + } -// inline -// cl_uint get_image_format_item_size(cl_image_format const &fmt) -// { -// return get_image_format_channel_count(fmt) -// * get_image_format_channel_dtype_size(fmt); -// } // // }}} @@ -2984,6 +2917,11 @@ void _free2(void **p, uint32_t size) { return 0; } +::error *_get_supported_image_formats(void *ptr_context, cl_mem_flags flags, cl_mem_object_type image_type, generic_info *out) { + C_HANDLE_ERROR(*out = get_supported_image_formats(*static_cast(ptr_context), flags, image_type);); + return 0; +} + ::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) { C_HANDLE_ERROR( diff --git a/src/c_wrapper/wrap_cl_core.h b/src/c_wrapper/wrap_cl_core.h index af3f35a11fb8e9709571a5b6ca666e1b785aa97e..22cf2e2671fc611334247b08085df673d1c19130 100644 --- a/src/c_wrapper/wrap_cl_core.h +++ b/src/c_wrapper/wrap_cl_core.h @@ -48,6 +48,9 @@ error *event__wait(void *ptr_event); error *_create_kernel(void **ptr_kernel, void *ptr_program, char *name); error *kernel__set_arg_mem_buffer(void *ptr_kernel, cl_uint arg_index, void *ptr_buffer); 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); + 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); @@ -65,6 +68,7 @@ void _free2(void**, uint32_t size); unsigned bitlog2(unsigned long v); + /* gl interop */ int have_gl();