From 530845d345b1bd358355f64c941ae4fb67cf868c Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner <inform@tiker.net> Date: Wed, 16 Sep 2020 14:09:17 -0500 Subject: [PATCH] Add pipe support --- doc/runtime_memory.rst | 20 +++++++++++ pyopencl/__init__.py | 7 +++- src/wrap_cl.hpp | 79 ++++++++++++++++++++++++++++++++++++++++-- src/wrap_cl_part_2.cpp | 30 ++++++++++++++++ 4 files changed, 132 insertions(+), 4 deletions(-) diff --git a/doc/runtime_memory.rst b/doc/runtime_memory.rst index ce2ee222..fc121554 100644 --- a/doc/runtime_memory.rst +++ b/doc/runtime_memory.rst @@ -381,3 +381,23 @@ Samplers |comparable| +Pipes +----- + +.. class:: Pipe(context, flags, packet_size, max_packets, properties) + + See :class:`mem_flags` for values of *flags*. + + :arg properties: a sequence + of keys and values from :class:`pipe_properties` as accepted + by :c:func:`clCreatePipe`. The trailing *0* is added automatically + and does not need to be included. + + This function Requires OpenCL 2 or newer. + + .. versionadded:: 2020.3 + + .. method:: get_pipe_info(param) + + See :class:`pipe_info` for values of *param*. + diff --git a/pyopencl/__init__.py b/pyopencl/__init__.py index ac7760f8..91d6af10 100644 --- a/pyopencl/__init__.py +++ b/pyopencl/__init__.py @@ -156,6 +156,10 @@ from pyopencl._cl import ( # noqa: F401 Image, Sampler, + + # This class is available unconditionally, even though CL only + # has it on CL2.0 and newer. + Pipe, ) try: @@ -1014,7 +1018,7 @@ def _add_functionality(): class _ImageInfoGetter: def __init__(self, event): from warnings import warn - warn("Image.image.attr is deprecated. " + warn("Image.image.attr is deprecated and will go away in 2021. " "Use Image.attr directly, instead.") self.event = event @@ -1297,6 +1301,7 @@ def _add_functionality(): _cl.MemoryObjectHolder: (MemoryObjectHolder.get_info, _cl.mem_info, []), Image: (_cl.Image.get_image_info, _cl.image_info, []), + Pipe: (_cl.Image.get_pipe_info, _cl.pipe_info, []), Program: (Program.get_info, _cl.program_info, []), Kernel: (Kernel.get_info, _cl.kernel_info, []), _cl.Sampler: (Sampler.get_info, _cl.sampler_info, []), diff --git a/src/wrap_cl.hpp b/src/wrap_cl.hpp index 75a08a47..7cf2dc07 100644 --- a/src/wrap_cl.hpp +++ b/src/wrap_cl.hpp @@ -30,8 +30,7 @@ // CL 1.2 undecided: // clSetPrintfCallback -// CL 2.0 missing: -// pipes +// CL 2.0 complete // CL 2.1 missing: // clGetKernelSubGroupInfo @@ -2580,7 +2579,7 @@ namespace pyopencl #endif default: - throw error("MemoryObject.get_image_info", CL_INVALID_VALUE); + throw error("Image.get_image_info", CL_INVALID_VALUE); } } }; @@ -3059,6 +3058,80 @@ namespace pyopencl // }}} + // {{{ pipe + + class pipe : public memory_object + { + public: + pipe(cl_mem mem, bool retain) + : memory_object(mem, retain) + { } + + py::object get_pipe_info(cl_pipe_info param_name) const + { +#if PYOPENCL_CL_VERSION >= 0x2000 + switch (param_name) + { + case CL_PIPE_PACKET_SIZE: + case CL_PIPE_MAX_PACKETS: + PYOPENCL_GET_TYPED_INFO(Pipe, data(), param_name, cl_uint); + + default: + throw error("Pipe.get_pipe_info", CL_INVALID_VALUE); + } +#else + throw error("Pipes not available. PyOpenCL was not compiled against a CL2+ header.", + CL_INVALID_VALUE); +#endif + } + }; + +#if PYOPENCL_CL_VERSION >= 0x2000 + inline + pipe *create_pipe( + context const &ctx, + cl_mem_flags flags, + cl_uint pipe_packet_size, + cl_uint pipe_max_packets, + py::sequence py_props) + { + PYOPENCL_STACK_CONTAINER(cl_pipe_properties, props, py::len(py_props) + 1); + { + size_t i = 0; + for (auto prop: py_props) + props[i++] = py::cast<cl_pipe_properties>(prop); + props[i++] = 0; + } + + cl_int status_code; + PYOPENCL_PRINT_CALL_TRACE("clCreatePipe"); + + cl_mem mem = clCreatePipe( + ctx.data(), + flags, + pipe_packet_size, + pipe_max_packets, + PYOPENCL_STACK_CONTAINER_GET_PTR(props), + &status_code); + + if (status_code != CL_SUCCESS) + throw pyopencl::error("Pipe", status_code); + + try + { + return new pipe(mem, false); + } + catch (...) + { + PYOPENCL_CALL_GUARDED(clReleaseMemObject, (mem)); + throw; + } +} +#endif + + // }}} + + // {{{ maps class memory_map { diff --git a/src/wrap_cl_part_2.cpp b/src/wrap_cl_part_2.cpp index 6735d41f..df56d0af 100644 --- a/src/wrap_cl_part_2.cpp +++ b/src/wrap_cl_part_2.cpp @@ -222,6 +222,36 @@ void pyopencl_expose_part_2(py::module &m) // }}} + // {{{ pipe + + { + typedef pyopencl::pipe cls; + py::class_<cls, memory_object>(m, "Pipe", py::dynamic_attr()) +#if PYOPENCL_CL_VERSION >= 0x2000 + .def( + py::init( + []( + context const &ctx, + cl_mem_flags flags, + cl_uint pipe_packet_size, + cl_uint pipe_max_packets, + py::sequence py_props) + { + return create_pipe(ctx, flags, pipe_packet_size, pipe_max_packets, py_props); + }), + py::arg("context"), + py::arg("flags"), + py::arg("packet_size"), + py::arg("max_packets"), + py::arg("properties") + ) +#endif + .DEF_SIMPLE_METHOD(get_pipe_info) + ; + } + + // }}} + // {{{ memory_map { typedef memory_map cls; -- GitLab