diff --git a/doc/runtime_memory.rst b/doc/runtime_memory.rst index ce2ee2227a1311ada8b3074c4bf3ea1d095d9151..fc121554842af4c6565d88fe1305082fd76cf7f5 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 ac7760f803376a317df3c9730d9bc695986caae3..91d6af106127b43e43fd76f0b94f7f6e29c3ea51 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 75a08a47e5748d7ae8fc3d7b2bb7557ee897a4fa..7cf2dc07f4332d7122dff0b17d4d88014362ebd3 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 6735d41fd7a348d9f76332d5ef8d36cd31906544..df56d0afac33399b826de33872cd5819497f367e 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;