diff --git a/pyopencl/c_wrapper/wrap_cl_core.h b/pyopencl/c_wrapper/wrap_cl_core.h index 8210ba3395964f9ec9ae6ac3fcd3f929de5ec7f6..58649e62ab962fe686bac06f916c4aa804478f89 100644 --- a/pyopencl/c_wrapper/wrap_cl_core.h +++ b/pyopencl/c_wrapper/wrap_cl_core.h @@ -163,10 +163,18 @@ error *enqueue_fill_buffer(clobj_t *_evt, clobj_t _queue, clobj_t _mem, uint32_t num_wait_for); // enqueue_*_image* error *enqueue_read_image(clobj_t *event, clobj_t queue, clobj_t mem, - size_t *origin, size_t *region, void *buffer, - size_t row_pitch, size_t slice_pitch, + const size_t *origin, size_t origin_l, + const size_t *region, size_t region_l, + void *buffer, size_t row_pitch, size_t slice_pitch, const clobj_t *wait_for, uint32_t num_wait_for, int is_blocking, void (*ref)(unsigned long)); +error *enqueue_write_image(clobj_t *_evt, clobj_t _queue, clobj_t _mem, + const size_t *origin, size_t origin_l, + const size_t *region, size_t region_l, + const void *buffer, size_t row_pitch, + size_t slice_pitch, const clobj_t *_wait_for, + uint32_t num_wait_for, int is_blocking, + void (*ref)(unsigned long)); // CL Object intptr_t clobj__int_ptr(clobj_t obj); error *clobj__get_info(clobj_t obj, cl_uint param, generic_info *out); diff --git a/pyopencl/cffi_cl.py b/pyopencl/cffi_cl.py index 233e1a0336e7a4c1f6b3d7b74d4c65f5a54bca7c..846aab5eab347f60f267c5da5c332a15d9a74609 100644 --- a/pyopencl/cffi_cl.py +++ b/pyopencl/cffi_cl.py @@ -906,16 +906,38 @@ def _enqueue_fill_buffer(queue, mem, pattern, offset, size, wait_for=None): def _enqueue_read_image(queue, mem, origin, region, hostbuf, row_pitch=0, slice_pitch=0, wait_for=None, is_blocking=True): + origin_l = len(origin) + region_l = len(region) + if origin_l > 3 or region_l > 3: + raise RuntimeError("origin or region has too many components", + "enqueue_read_image") c_buf, size, _ = _c_buffer_from_obj(hostbuf, writable=True) ptr_event = _ffi.new('clobj_t*') c_wait_for, num_wait_for = _clobj_list(wait_for) # TODO check buffer size _handle_error(_lib.enqueue_read_image( - ptr_event, queue.ptr, mem.ptr, origin, region, c_buf, row_pitch, - slice_pitch, c_wait_for, num_wait_for, bool(is_blocking), - _get_ref_func(c_buf))) + ptr_event, queue.ptr, mem.ptr, origin, origin_l, region, region_l, + c_buf, row_pitch, slice_pitch, c_wait_for, num_wait_for, + bool(is_blocking), _get_ref_func(c_buf))) return _create_instance(NannyEvent, ptr_event[0]) +def _enqueue_write_image(queue, mem, origin, region, hostbuf, row_pitch=0, + slice_pitch=0, wait_for=None, is_blocking=True): + origin_l = len(origin) + region_l = len(region) + if origin_l > 3 or region_l > 3: + raise RuntimeError("origin or region has too many components", + "enqueue_read_image") + c_buf, size, _ = _c_buffer_from_obj(hostbuf) + _event = _ffi.new('clobj_t*') + c_wait_for, num_wait_for = _clobj_list(wait_for) + # TODO check buffer size + _handle_error(_lib.enqueue_read_image( + _event, queue.ptr, mem.ptr, origin, origin_l, region, region_l, + c_buf, row_pitch, slice_pitch, c_wait_for, num_wait_for, + bool(is_blocking), _get_ref_func(c_buf))) + return _create_instance(NannyEvent, _event[0]) + # TODO: write_image copy_image fill_image # copy_buffer_to_image copy_image_to_buffer diff --git a/src/c_wrapper/wrap_cl.cpp b/src/c_wrapper/wrap_cl.cpp index e1796b2618120528e997f238bd0c09c6fdf98ac1..cf3d56b4b6550e964cc94e8d612e259c48ca8736 100644 --- a/src/c_wrapper/wrap_cl.cpp +++ b/src/c_wrapper/wrap_cl.cpp @@ -2450,7 +2450,7 @@ enqueue_barrier(clobj_t _queue) }); } -// {{{ transfer enqueues +// {{{ enqueue_*_buffer* error* enqueue_read_buffer(clobj_t *_evt, clobj_t _queue, clobj_t _mem, @@ -2579,16 +2579,31 @@ enqueue_fill_buffer(clobj_t *_evt, clobj_t _queue, clobj_t _mem, void *pattern, }); } +// }}} + +// {{{ enqueue_*_image* + error* -enqueue_read_image(clobj_t *_evt, clobj_t _queue, clobj_t _mem, size_t *origin, - size_t *region, void *buffer, size_t row_pitch, - size_t slice_pitch, const clobj_t *_wait_for, - uint32_t num_wait_for, int is_blocking, - void (*ref)(unsigned long)) +enqueue_read_image(clobj_t *_evt, clobj_t _queue, clobj_t _mem, + const size_t *origin, size_t origin_l, + const size_t *region, size_t region_l, void *buffer, + size_t row_pitch, size_t slice_pitch, + const clobj_t *_wait_for, uint32_t num_wait_for, + int is_blocking, void (*ref)(unsigned long)) { auto wait_for = buf_from_class<event>(_wait_for, num_wait_for); auto queue = static_cast<command_queue*>(_queue); auto img = static_cast<image*>(_mem); + size_t _origin[3] = {0}; + if (origin_l < 3) { + memcpy(_origin, origin, sizeof(size_t) * origin_l); + origin = _origin; + } + size_t _region[3] = {0}; + if (region_l < 3) { + memcpy(_region, region, sizeof(size_t) * region_l); + region = _region; + } return c_handle_error([&] { cl_event evt; retry_mem_error<void>([&] { @@ -2602,6 +2617,40 @@ enqueue_read_image(clobj_t *_evt, clobj_t _queue, clobj_t _mem, size_t *origin, }); } +error* +enqueue_write_image(clobj_t *_evt, clobj_t _queue, clobj_t _mem, + const size_t *origin, size_t origin_l, + const size_t *region, size_t region_l, + const void *buffer, size_t row_pitch, size_t slice_pitch, + const clobj_t *_wait_for, uint32_t num_wait_for, + int is_blocking, void (*ref)(unsigned long)) +{ + auto wait_for = buf_from_class<event>(_wait_for, num_wait_for); + auto queue = static_cast<command_queue*>(_queue); + auto img = static_cast<image*>(_mem); + size_t _origin[3] = {0}; + if (origin_l < 3) { + memcpy(_origin, origin, sizeof(size_t) * origin_l); + origin = _origin; + } + size_t _region[3] = {0}; + if (region_l < 3) { + memcpy(_region, region, sizeof(size_t) * region_l); + region = _region; + } + return c_handle_error([&] { + cl_event evt; + retry_mem_error<void>([&] { + pyopencl_call_guarded( + clEnqueueWriteImage, queue->data(), img->data(), + cast_bool(is_blocking), origin, region, row_pitch, + slice_pitch, buffer, num_wait_for, + wait_for.get(), &evt); + }); + *_evt = new_nanny_event(evt, ref); + }); +} + // }}} intptr_t