From fed6f6e570883d223581c231c5594856795a129f Mon Sep 17 00:00:00 2001 From: Andreas Kloeckner <inform@tiker.net> Date: Fri, 18 Jun 2010 02:14:06 -0400 Subject: [PATCH] Implement CL 1.1. sub-buffer creation. --- doc/make_constants.py | 2 +- doc/source/index.rst | 2 +- doc/source/{reference.rst => runtime.rst} | 13 ++++- doc/upload-docs.sh | 1 + src/wrapper/wrap_cl.cpp | 9 ++++ src/wrapper/wrap_cl.hpp | 64 ++++++++++++++++++++--- 6 files changed, 79 insertions(+), 12 deletions(-) rename doc/source/{reference.rst => runtime.rst} (97%) diff --git a/doc/make_constants.py b/doc/make_constants.py index 07d140d9..3b60fc7c 100644 --- a/doc/make_constants.py +++ b/doc/make_constants.py @@ -104,7 +104,7 @@ const_ext_lookup = { } cls_ext_lookup = { - cl.buffer_create_type: ("CL_1.1", "0.92"), + #cl.buffer_create_type: ("CL_1.1", "0.92"), } diff --git a/doc/source/index.rst b/doc/source/index.rst index f1f1747f..9fd85142 100644 --- a/doc/source/index.rst +++ b/doc/source/index.rst @@ -69,7 +69,7 @@ Contents .. toctree:: :maxdepth: 2 - reference + runtime misc Note that this guide does not explain OpenCL programming and technology. Please diff --git a/doc/source/reference.rst b/doc/source/runtime.rst similarity index 97% rename from doc/source/reference.rst rename to doc/source/runtime.rst index 349c6e06..238c7268 100644 --- a/doc/source/reference.rst +++ b/doc/source/runtime.rst @@ -1,7 +1,7 @@ .. _reference-doc: -Reference Documentation -======================= +OpenCL Platform/Runtime Documentation +===================================== Version Queries --------------- @@ -260,6 +260,15 @@ Buffers :class:`Buffer` is a subclass of :class:`MemoryObject`. + .. method:: get_sub_region(origin, size, flags=0) + + .. method:: __getitem__(slc) + + *slc* is a :class:`slice` object indicating from which byte index range + a sub-buffer is to be created. The *flags* argument of + :meth:`get_sub_region` is set to the same flags with which *self* was + created. + .. function:: enqueue_read_buffer(queue, mem, hostbuf, device_offset=0, wait_for=None, is_blocking=False) |std-enqueue-blurb| diff --git a/doc/upload-docs.sh b/doc/upload-docs.sh index bdc4e689..cd5e34f1 100755 --- a/doc/upload-docs.sh +++ b/doc/upload-docs.sh @@ -1,3 +1,4 @@ #! /bin/sh +cp build/html/runtime.rst build/html/reference.rst rsync --progress --verbose --archive --delete build/html/* buster:doc/pyopencl diff --git a/src/wrapper/wrap_cl.cpp b/src/wrapper/wrap_cl.cpp index 1d37a053..66d2984a 100644 --- a/src/wrapper/wrap_cl.cpp +++ b/src/wrapper/wrap_cl.cpp @@ -464,12 +464,14 @@ BOOST_PYTHON_MODULE(_cl) ADD_ATTR(PROFILING_COMMAND_, END); } +/* not needed--filled in automatically by implementation. #ifdef CL_VERSION_1_1 { py::class_<buffer_create_type> cls("buffer_create_type", py::no_init); ADD_ATTR(BUFFER_CREATE_TYPE_, REGION); } #endif +*/ // }}} @@ -588,6 +590,13 @@ BOOST_PYTHON_MODULE(_cl) py::arg("size")=0, py::arg("hostbuf")=py::object() ))) +#ifdef CL_VERSION_1_1 + .def("get_sub_region", &cls::get_sub_region, + (py::args("origin", "size"), py::arg("flags")=0), + py::return_value_policy<py::manage_new_object>()) + .def("__getitem__", &cls::getitem, + py::return_value_policy<py::manage_new_object>()) +#endif ; } diff --git a/src/wrapper/wrap_cl.hpp b/src/wrapper/wrap_cl.hpp index 0dc5edf3..ea4c0ccc 100644 --- a/src/wrapper/wrap_cl.hpp +++ b/src/wrapper/wrap_cl.hpp @@ -1074,42 +1074,90 @@ namespace pyopencl buffer(cl_mem mem, bool retain, py::object *hostbuf=0) : memory_object(mem, retain, hostbuf) { } + +#ifdef CL_VERSION_1_1 + buffer *get_sub_region( + size_t origin, size_t size, cl_mem_flags flags) const + { + cl_buffer_region region = { origin, size}; + cl_int status_code; + cl_mem mem = clCreateSubBuffer(data(), flags, + CL_BUFFER_CREATE_TYPE_REGION, ®ion, &status_code); + + PYOPENCL_PRINT_CALL_TRACE("clCreateSubBuffer"); + if (status_code != CL_SUCCESS) + throw pyopencl::error("Buffer.get_sub_region", status_code); + + try + { + return new buffer(mem, false); + } + catch (...) + { + PYOPENCL_CALL_GUARDED(clReleaseMemObject, (mem)); + throw; + } + } + + buffer *getitem(py::object slc) const + { + Py_ssize_t start, end, stride, length; + + size_t my_length; + PYOPENCL_CALL_GUARDED(clGetMemObjectInfo, + (data(), CL_MEM_SIZE, sizeof(my_length), &my_length, 0)); + + if (PySlice_GetIndicesEx(reinterpret_cast<PySliceObject *>(slc.ptr()), + my_length, &start, &end, &stride, &length) != 0) + throw py::error_already_set(); + + if (stride != 1) + throw pyopencl::error("Buffer.__getitem__", CL_INVALID_VALUE, + "Buffer slice must have stride 1"); + + cl_mem_flags my_flags; + PYOPENCL_CALL_GUARDED(clGetMemObjectInfo, + (data(), CL_MEM_FLAGS, sizeof(my_flags), &my_flags, 0)); + + return get_sub_region(start, end, my_flags); + } +#endif }; - memory_object *create_buffer( + buffer *create_buffer( context &ctx, cl_mem_flags flags, size_t size, - py::object buffer + py::object py_hostbuf ) { - if (buffer.ptr() != Py_None && + if (py_hostbuf.ptr() != Py_None && !(flags & (CL_MEM_USE_HOST_PTR | CL_MEM_COPY_HOST_PTR))) PyErr_Warn(PyExc_UserWarning, "'hostbuf' was passed, " "but no memory flags to make use of it."); void *buf = 0; py::object *retained_buf_obj = 0; - if (buffer.ptr() != Py_None) + if (py_hostbuf.ptr() != Py_None) { PYOPENCL_BUFFER_SIZE_T len; if (flags & CL_MEM_USE_HOST_PTR) { - if (PyObject_AsWriteBuffer(buffer.ptr(), &buf, &len)) + if (PyObject_AsWriteBuffer(py_hostbuf.ptr(), &buf, &len)) throw py::error_already_set(); } else { if (PyObject_AsReadBuffer( - buffer.ptr(), const_cast<const void **>(&buf), &len)) + py_hostbuf.ptr(), const_cast<const void **>(&buf), &len)) throw py::error_already_set(); } if (flags & CL_MEM_USE_HOST_PTR) - retained_buf_obj = &buffer; + retained_buf_obj = &py_hostbuf; if (size > size_t(len)) throw pyopencl::error("Buffer", CL_INVALID_VALUE, @@ -1127,7 +1175,7 @@ namespace pyopencl try { - return new memory_object(mem, false, retained_buf_obj); + return new buffer(mem, false, retained_buf_obj); } catch (...) { -- GitLab