diff --git a/doc/source/runtime.rst b/doc/source/runtime.rst index 547ce01876393cc7650b8fc4520e01fa331aa2cc..ccfa11726c820118e8afe6facf2a5a6f3f920708 100644 --- a/doc/source/runtime.rst +++ b/doc/source/runtime.rst @@ -526,73 +526,7 @@ Images Transfers ^^^^^^^^^ -.. function:: enqueue_copy(queue, dest, src, **kwargs) - - Copy from :class:`Image`, :class:`Buffer` or the host to - :class:`Image`, :class:`Buffer` or the host. (Note: host-to-host - copies are unsupported.) - - The following keyword arguments are available: - - :arg wait_for: (optional, default empty) - :arg is_blocking: Wait for completion. Defaults to *True*. - (Available on any copy involving host memory) - - :return: A :class:`NannyEvent` if the transfer involved a - host-side buffer, otherwise an :class:`Event`. - - :class:`Buffer` ↔ host transfers: - - :arg device_offset: offset in bytes (optional) - - :class:`Buffer` ↔ :class:`Buffer` transfers: - - :arg byte_count: (optional) - :arg src_offset: (optional) - :arg dest_offset: (optional) - - Rectangular :class:`Buffer` ↔ host transfers (CL 1.1 and newer): - - :arg buffer_origin: :class:`tuple` of :class:`int` of length - three or shorter. (mandatory) - :arg host_origin: :class:`tuple` of :class:`int` of length - three or shorter. (mandatory) - :arg region: :class:`tuple` of :class:`int` of length - three or shorter. (mandatory) - :arg buffer_pitches: :class:`tuple` of :class:`int` of length - two or shorter. (optional, "tightly-packed" if unspecified) - :arg host_pitches: :class:`tuple` of :class:`int` of length - two or shorter. (optional, "tightly-packed" if unspecified) - - :class:`Image` ↔ host transfers: - - :arg origin: :class:`tuple` of :class:`int` of length - three or shorter. (mandatory) - :arg region: :class:`tuple` of :class:`int` of length - three or shorter. (mandatory) - :arg pitches: :class:`tuple` of :class:`int` of length - two or shorter. (optional) - - :class:`Buffer` ↔ :class:`Image` transfers: - - :arg offset: offset in buffer (mandatory) - :arg origin: :class:`tuple` of :class:`int` of length - three or shorter. (mandatory) - :arg region: :class:`tuple` of :class:`int` of length - three or shorter. (mandatory) - - :class:`Image` ↔ :class:`Image` transfers: - - :arg src_origin: :class:`tuple` of :class:`int` of length - three or shorter. (mandatory) - :arg dest_origin: :class:`tuple` of :class:`int` of length - three or shorter. (mandatory) - :arg region: :class:`tuple` of :class:`int` of length - three or shorter. (mandatory) - - |std-enqueue-blurb| - - .. versionadded:: 2011.1 +.. autofunction:: enqueue_copy(queue, dest, src, **kwargs) Mapping Memory into Host Address Space ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/pyopencl/__init__.py b/pyopencl/__init__.py index 59628fcaaef5990d7bba66c77e35816a53fd2e1b..f7a4a5352eff42fb47827dbaf5e23d1789eb937a 100644 --- a/pyopencl/__init__.py +++ b/pyopencl/__init__.py @@ -1,3 +1,5 @@ +# -*- coding: utf-8 -*- + __copyright__ = "Copyright (C) 2009 Andreas Kloeckner" __license__ = """ @@ -420,7 +422,7 @@ def _add_functionality(): pass what = e.what + "\n\n" + (75*"="+"\n").join( - "Build on %s:\n\n%s" % (dev, log) + "Build on %s:\n\n%s" % (dev, log) for dev, log in self._get_build_logs()) code = e.code routine = e.routine @@ -580,7 +582,7 @@ def _add_functionality(): def image_format_repr(self): return "ImageFormat(%s, %s)" % ( - channel_order.to_string(self.channel_order, + channel_order.to_string(self.channel_order, "<unknown channel order 0x%x>"), channel_type.to_string(self.channel_data_type, "<unknown channel data type 0x%x>")) @@ -598,7 +600,7 @@ def _add_functionality(): except AttributeError: return str(val) else: - result = "%s failed: %s" % (val.routine(), + result = "%s failed: %s" % (val.routine(), status_code.to_string(val.code(), "<unknown error %d>") .lower().replace("_", " ")) if val.what(): @@ -809,6 +811,76 @@ if _cl.get_cl_header_version() >= (1,1): enqueue_copy_buffer_rect = _mark_copy_deprecated(_cl._enqueue_copy_buffer_rect) def enqueue_copy(queue, dest, src, **kwargs): + """Copy from :class:`Image`, :class:`Buffer` or the host to + :class:`Image`, :class:`Buffer` or the host. (Note: host-to-host + copies are unsupported.) + + The following keyword arguments are available: + + :arg wait_for: (optional, default empty) + :arg is_blocking: Wait for completion. Defaults to *True*. + (Available on any copy involving host memory) + + :return: A :class:`NannyEvent` if the transfer involved a + host-side buffer, otherwise an :class:`Event`. + + :class:`Buffer` ↔ host transfers: + + :arg device_offset: offset in bytes (optional) + + :class:`Buffer` ↔ :class:`Buffer` transfers: + + :arg byte_count: (optional) If not specified, defaults to the + size of the source in versions 2012.x and earlier, + and to the minimum of the size of the source and target + from 2013.1 on. + :arg src_offset: (optional) + :arg dest_offset: (optional) + + Rectangular :class:`Buffer` ↔ host transfers (CL 1.1 and newer): + + :arg buffer_origin: :class:`tuple` of :class:`int` of length + three or shorter. (mandatory) + :arg host_origin: :class:`tuple` of :class:`int` of length + three or shorter. (mandatory) + :arg region: :class:`tuple` of :class:`int` of length + three or shorter. (mandatory) + :arg buffer_pitches: :class:`tuple` of :class:`int` of length + two or shorter. (optional, "tightly-packed" if unspecified) + :arg host_pitches: :class:`tuple` of :class:`int` of length + two or shorter. (optional, "tightly-packed" if unspecified) + + :class:`Image` ↔ host transfers: + + :arg origin: :class:`tuple` of :class:`int` of length + three or shorter. (mandatory) + :arg region: :class:`tuple` of :class:`int` of length + three or shorter. (mandatory) + :arg pitches: :class:`tuple` of :class:`int` of length + two or shorter. (optional) + + :class:`Buffer` ↔ :class:`Image` transfers: + + :arg offset: offset in buffer (mandatory) + :arg origin: :class:`tuple` of :class:`int` of length + three or shorter. (mandatory) + :arg region: :class:`tuple` of :class:`int` of length + three or shorter. (mandatory) + + :class:`Image` ↔ :class:`Image` transfers: + + :arg src_origin: :class:`tuple` of :class:`int` of length + three or shorter. (mandatory) + :arg dest_origin: :class:`tuple` of :class:`int` of length + three or shorter. (mandatory) + :arg region: :class:`tuple` of :class:`int` of length + three or shorter. (mandatory) + + |std-enqueue-blurb| + + .. versionadded:: 2011.1 + """ + if isinstance(dest, MemoryObjectHolder): if dest.type == mem_object_type.BUFFER: if isinstance(src, MemoryObjectHolder): diff --git a/src/wrapper/wrap_cl.hpp b/src/wrapper/wrap_cl.hpp index 6c64ac9700c731591504bf022554a78d09e095cb..c71e33f6a46614f15511ad3c4438e66901ca9be5 100644 --- a/src/wrapper/wrap_cl.hpp +++ b/src/wrapper/wrap_cl.hpp @@ -1845,17 +1845,22 @@ namespace pyopencl command_queue &cq, memory_object_holder &src, memory_object_holder &dst, - size_t byte_count, + ptrdiff_t byte_count, size_t src_offset, size_t dst_offset, py::object py_wait_for) { PYOPENCL_PARSE_WAIT_FOR; - if (byte_count == 0) + 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, sizeof(byte_count), &byte_count, 0)); + (src.data(), CL_MEM_SIZE, sizeof(byte_count), &byte_count_src, 0)); + PYOPENCL_CALL_GUARDED(clGetMemObjectInfo, + (src.data(), CL_MEM_SIZE, sizeof(byte_count), &byte_count_dst, 0)); + byte_count = std::min(byte_count_src, byte_count_dst); } cl_event evt; diff --git a/src/wrapper/wrap_cl_part_1.cpp b/src/wrapper/wrap_cl_part_1.cpp index d441718ff200b2089838d58f2d2247d18baeb600..b9f55a0671bc993394e5e5526b2a3a47b3b4e93b 100644 --- a/src/wrapper/wrap_cl_part_1.cpp +++ b/src/wrapper/wrap_cl_part_1.cpp @@ -228,7 +228,7 @@ void pyopencl_expose_part_1() py::return_value_policy<py::manage_new_object>()); py::def("_enqueue_copy_buffer", enqueue_copy_buffer, (py::args("queue", "src", "dst"), - py::arg("byte_count")=0, + py::arg("byte_count")=-1, py::arg("src_offset")=0, py::arg("dst_offset")=0, py::arg("wait_for")=py::object()