diff --git a/setup.py b/setup.py index beead668908834cf246af2fce5fc28c0b3a2ef78..19a21b330e6c9e23c08a9d24f21ac13d0fea4351 100644 --- a/setup.py +++ b/setup.py @@ -38,7 +38,11 @@ def get_config_schema(): IncludeDir, LibraryDir, Libraries, \ Switch, StringListOption - default_cxxflags = [] + default_cxxflags = [ + # Required for pybind11: + # https://pybind11.readthedocs.io/en/stable/faq.html#someclass-declared-with-greater-visibility-than-the-type-of-its-field-someclass-member-wattributes + "-fvisibility=hidden" + ] if 'darwin' in sys.platform: import platform @@ -219,12 +223,12 @@ def main(): ext_modules=[ NumpyExtension("_cl", [ - #"src/wrap_cl.cpp", + "src/wrap_cl.cpp", #"src/wrap_cl_part_1.cpp", #"src/wrap_cl_part_2.cpp", #"src/wrap_constants.cpp", "src/wrap_mempool.cpp", - #"src/bitlog.cpp", + "src/bitlog.cpp", ], include_dirs=INCLUDE_DIRS, library_dirs=conf["CL_LIB_DIR"], diff --git a/src/mempool.hpp b/src/mempool.hpp index 2895e1d0b6bfdee021a99fa9442a3377bca7a546..22b582fd499b2a86eecfa0bb66da9af20c15446d 100644 --- a/src/mempool.hpp +++ b/src/mempool.hpp @@ -135,7 +135,7 @@ namespace PYGPU_PACKAGE return *new_bin; } else - return *it->second; + return it->second; } void inc_held_blocks() @@ -241,7 +241,7 @@ namespace PYGPU_PACKAGE { for (bin_pair_t bin_pair: m_container) { - bin_t &bin = *bin_pair.second; + bin_t &bin = bin_pair.second; while (bin.size()) { @@ -272,7 +272,7 @@ namespace PYGPU_PACKAGE // free largest stuff first for (bin_pair_t bin_pair: reverse(m_container)) { - bin_t &bin = *bin_pair.second; + bin_t &bin = bin_pair.second; if (bin.size()) { diff --git a/src/numpy_init.hpp b/src/numpy_init.hpp index 146cae65dd7c8e884ade6fff594a0cf8cb22bbf8..2b54a2a542bce9a5bef896c968f08b83591b3021 100644 --- a/src/numpy_init.hpp +++ b/src/numpy_init.hpp @@ -2,6 +2,7 @@ #define _FAYHVVAAA_PYOPENCL_HEADER_SEEN_NUMPY_INIT_HPP +// #define NPY_NO_DEPRECATED_API NPY_1_7_API_VERSION #include #include diff --git a/src/tools.hpp b/src/tools.hpp index dcd1b50e8d1f54367265acc10d5c7e5b3fbcbfaf..30f4b08fd60543f292c8f6a5af25352dcb77e6d0 100644 --- a/src/tools.hpp +++ b/src/tools.hpp @@ -28,10 +28,7 @@ namespace pyopencl { namespace py = pybind11; - py::object gc_mod( - py::handle<>( - PyImport_ImportModule("gc"))); - gc_mod.attr("collect")(); + py::module::import("gc").attr("collect")(); } diff --git a/src/wrap_cl.cpp b/src/wrap_cl.cpp index 0b231ad0c68e8a6adeb0b505c07ea9370f48bb4a..29b546e7a07441323cdf6614907b2fe5995f5915 100644 --- a/src/wrap_cl.cpp +++ b/src/wrap_cl.cpp @@ -8,17 +8,17 @@ using namespace pyopencl; -extern void pyopencl_expose_constants(); -extern void pyopencl_expose_part_1(); -extern void pyopencl_expose_part_2(); -extern void pyopencl_expose_mempool(); +extern void pyopencl_expose_constants(py::module &m); +extern void pyopencl_expose_part_1(py::module &m); +extern void pyopencl_expose_part_2(py::module &m); +extern void pyopencl_expose_mempool(py::module &m); -PYBIND11_MODULE(_cl) +PYBIND11_MODULE(_cl, m) { - pyopencl_expose_constants(); - pyopencl_expose_part_1(); - pyopencl_expose_part_2(); - pyopencl_expose_mempool(); + pyopencl_expose_constants(m); + pyopencl_expose_part_1(m); + pyopencl_expose_part_2(m); + pyopencl_expose_mempool(m); } // vim: foldmethod=marker diff --git a/src/wrap_cl.hpp b/src/wrap_cl.hpp index e5add4718de3df759d8aa5f24d0e51cda814fbed..4eb86bd870a997b4587d3a2990dfe9baf3dd03df 100644 --- a/src/wrap_cl.hpp +++ b/src/wrap_cl.hpp @@ -70,7 +70,13 @@ #if PY_VERSION_HEX >= 0x03000000 #define PYOPENCL_USE_NEW_BUFFER_INTERFACE +#define PYOPENCL_STD_MOVE_IF_NEW_BUF_INTF(s) std::move(s) +#else +#define PYOPENCL_STD_MOVE_IF_NEW_BUF_INTF(s) (s) #endif + + + // }}} @@ -137,7 +143,7 @@ { \ PYTHON_FOREACH(py_dev, py_devices) \ devices_vec.push_back( \ - py::extract(py_dev)().data()); \ + (py_dev).cast().data()); \ num_devices = devices_vec.size(); \ devices = devices_vec.empty( ) ? NULL : &devices_vec.front(); \ } \ @@ -301,7 +307,7 @@ (FIRST_ARG, SECOND_ARG, param_value_size, \ param_value.empty( ) ? NULL : ¶m_value.front(), ¶m_value_size)); \ \ - return py::object( \ + return py::cast( \ param_value.empty( ) ? "" : std::string(¶m_value.front(), param_value_size-1)); \ } @@ -313,7 +319,7 @@ TYPE param_value; \ PYOPENCL_CALL_GUARDED(clGet##WHAT##Info, \ (FIRST_ARG, SECOND_ARG, sizeof(param_value), ¶m_value, 0)); \ - return py::object(param_value); \ + return py::cast(param_value); \ } // }}} @@ -328,7 +334,7 @@ event_wait_list.resize(len(py_wait_for)); \ PYTHON_FOREACH(evt, py_wait_for) \ event_wait_list[num_events_in_wait_list++] = \ - py::extract(evt)().data(); \ + evt.cast().data(); \ } #define PYOPENCL_WAITLIST_ARGS \ @@ -409,7 +415,7 @@ namespace pyopencl // {{{ buffer interface helper // #ifdef PYOPENCL_USE_NEW_BUFFER_INTERFACE - class py_buffer_wrapper : public boost::noncopyable + class py_buffer_wrapper : public noncopyable { private: bool m_initialized; @@ -450,7 +456,8 @@ namespace pyopencl // {{{ platform - class platform : boost::noncopyable + + class platform : noncopyable { private: cl_platform_id m_platform; @@ -515,8 +522,10 @@ namespace pyopencl // }}} + // {{{ device - class device : boost::noncopyable + + class device : noncopyable { public: enum reference_type_t { @@ -593,7 +602,7 @@ namespace pyopencl #if PYOPENCL_CL_VERSION >= 0x1020 else if (m_ref_type == REF_CL_1_2) - PYOPENCL_CALL_GUARDED(clReleaseDevice, (m_device)); + PYOPENCL_CALL_GUARDED_CLEANUP(clReleaseDevice, (m_device)); #endif } @@ -913,8 +922,10 @@ namespace pyopencl // }}} + // {{{ context - class context : public boost::noncopyable + + class context : public noncopyable { private: cl_context m_context; @@ -991,7 +1002,7 @@ namespace pyopencl case CL_WGL_HDC_KHR: case CL_CGL_SHAREGROUP_KHR: #endif - value = py::object(result[i+1]); + value = py::cast(result[i+1]); break; #endif @@ -1021,8 +1032,6 @@ namespace pyopencl }; - - inline std::vector parse_context_properties( py::object py_properties) @@ -1031,26 +1040,27 @@ namespace pyopencl if (py_properties.ptr() != Py_None) { - PYTHON_FOREACH(prop_tuple, py_properties) + PYTHON_FOREACH(prop_tuple_py, py_properties) { + py::tuple prop_tuple(prop_tuple_py.cast()); + if (len(prop_tuple) != 2) throw error("Context", CL_INVALID_VALUE, "property tuple must have length 2"); - cl_context_properties prop = - py::extract(prop_tuple[0]); + cl_context_properties prop = prop_tuple[0].cast(); props.push_back(prop); if (prop == CL_CONTEXT_PLATFORM) { - py::extract value(prop_tuple[1]); props.push_back( - reinterpret_cast(value().data())); + reinterpret_cast( + prop_tuple[1].cast().data())); } #if defined(PYOPENCL_GL_SHARING_VERSION) && (PYOPENCL_GL_SHARING_VERSION >= 1) #if defined(_WIN32) else if (prop == CL_WGL_HDC_KHR) { // size_t is a stand-in for HANDLE, hopefully has the same size. - size_t hnd = py::extract(prop_tuple[1]); + size_t hnd = (prop_tuple[1]).cast(); props.push_back(hnd); } #endif @@ -1065,11 +1075,10 @@ namespace pyopencl #endif ) { - py::object ctypes = py::import("ctypes"); + py::object ctypes = py::module::import("ctypes"); py::object prop = prop_tuple[1], c_void_p = ctypes.attr("c_void_p"); py::object ptr = ctypes.attr("cast")(prop, c_void_p); - py::extract value(ptr.attr("value")); - props.push_back(value); + props.push_back(ptr.attr("value").cast()); } #endif else @@ -1082,8 +1091,6 @@ namespace pyopencl } - - inline context *create_context_inner(py::object py_devices, py::object py_properties, py::object py_dev_type) @@ -1107,10 +1114,7 @@ namespace pyopencl std::vector devices; PYTHON_FOREACH(py_dev, py_devices) - { - py::extract dev(py_dev); - devices.push_back(dev().data()); - } + devices.push_back(py_dev.cast().data()); PYOPENCL_PRINT_CALL_TRACE("clCreateContext"); ctx = clCreateContext( @@ -1124,7 +1128,7 @@ namespace pyopencl { cl_device_type dev_type = CL_DEVICE_TYPE_DEFAULT; if (py_dev_type.ptr() != Py_None) - dev_type = py::extract(py_dev_type)(); + dev_type = py_dev_type.cast(); PYOPENCL_PRINT_CALL_TRACE("clCreateContextFromType"); ctx = clCreateContextFromType(props_ptr, dev_type, 0, 0, &status_code); @@ -1145,8 +1149,6 @@ namespace pyopencl } - - inline context *create_context(py::object py_devices, py::object py_properties, py::object py_dev_type) @@ -1156,13 +1158,11 @@ namespace pyopencl ) } - - - - // }}} + // {{{ command_queue + class command_queue { private: @@ -1271,8 +1271,10 @@ namespace pyopencl // }}} + // {{{ event/synchronization - class event : boost::noncopyable + + class event : noncopyable { private: cl_event m_event; @@ -1360,7 +1362,7 @@ namespace pyopencl public: nanny_event(cl_event evt, bool retain, std::unique_ptr &ward) - : event(evt, retain), m_ward(ward) + : event(evt, retain), m_ward(std::move(ward)) { } ~nanny_event() @@ -1370,8 +1372,7 @@ namespace pyopencl { if (m_ward.get()) { - return py::object(py::handle<>(py::borrowed( - m_ward->m_buf.obj))); + return py::reinterpret_borrow(m_ward->m_buf.obj); } else return py::object(); @@ -1427,7 +1428,7 @@ namespace pyopencl PYTHON_FOREACH(evt, events) event_wait_list[num_events_in_wait_list++] = - py::extract(evt)().data(); + evt.cast().data(); PYOPENCL_CALL_GUARDED_THREADED(clWaitForEvents, ( PYOPENCL_WAITLIST_ARGS)); @@ -1485,8 +1486,7 @@ namespace pyopencl std::vector event_list(len(py_events)); PYTHON_FOREACH(py_evt, py_events) - event_list[num_events++] = - py::extract(py_evt)().data(); + event_list[num_events++] = py_evt.cast().data(); PYOPENCL_CALL_GUARDED(clEnqueueWaitForEvents, ( cq.data(), num_events, event_list.empty( ) ? NULL : &event_list.front())); @@ -1543,6 +1543,7 @@ namespace pyopencl // }}} + // {{{ memory_object py::object create_mem_object_wrapper(cl_mem mem); @@ -1568,7 +1569,7 @@ namespace pyopencl - class memory_object : boost::noncopyable, public memory_object_holder + class memory_object : noncopyable, public memory_object_holder { public: #ifdef PYOPENCL_USE_NEW_BUFFER_INTERFACE @@ -1589,11 +1590,12 @@ namespace pyopencl if (retain) PYOPENCL_CALL_GUARDED(clRetainMemObject, (mem)); - m_hostbuf = hostbuf; + m_hostbuf = PYOPENCL_STD_MOVE_IF_NEW_BUF_INTF(hostbuf); } memory_object(memory_object &src) - : m_valid(true), m_mem(src.m_mem), m_hostbuf(src.m_hostbuf) + : m_valid(true), m_mem(src.m_mem), + m_hostbuf(PYOPENCL_STD_MOVE_IF_NEW_BUF_INTF(src.m_hostbuf)) { PYOPENCL_CALL_GUARDED(clRetainMemObject, (m_mem)); } @@ -1623,10 +1625,7 @@ namespace pyopencl { #ifdef PYOPENCL_USE_NEW_BUFFER_INTERFACE if (m_hostbuf.get()) - { - return py::object(py::handle<>(py::borrowed( - m_hostbuf->m_buf.obj))); - } + return py::reinterpret_borrow(m_hostbuf->m_buf.obj); else return py::object(); #else @@ -1651,7 +1650,7 @@ namespace pyopencl std::vector mem_objects; PYTHON_FOREACH(mo, py_mem_objects) - mem_objects.push_back(py::extract(mo)().data()); + mem_objects.push_back(mo.cast().data()); cl_event evt; PYOPENCL_RETRY_IF_MEM_ERROR( @@ -1692,7 +1691,7 @@ namespace pyopencl std::vector mem_objects; PYTHON_FOREACH(mo, py_mem_objects) - mem_objects.push_back(py::extract(mo)().data()); + mem_objects.push_back(mo.cast().data()); cl_event evt; PYOPENCL_RETRY_IF_MEM_ERROR( @@ -1709,6 +1708,7 @@ namespace pyopencl // }}} + // {{{ buffer inline cl_mem create_buffer( @@ -1778,7 +1778,7 @@ namespace pyopencl { public: buffer(cl_mem mem, bool retain, hostbuf_t hostbuf=hostbuf_t()) - : memory_object(mem, retain, hostbuf) + : memory_object(mem, retain, PYOPENCL_STD_MOVE_IF_NEW_BUF_INTF(hostbuf)) { } #if PYOPENCL_CL_VERSION >= 0x1010 @@ -1914,7 +1914,7 @@ namespace pyopencl try { - return new buffer(mem, false, retained_buf_obj); + return new buffer(mem, false, PYOPENCL_STD_MOVE_IF_NEW_BUF_INTF(retained_buf_obj)); } catch (...) { @@ -2252,13 +2252,14 @@ namespace pyopencl // }}} + // {{{ image class image : public memory_object { public: image(cl_mem mem, bool retain, hostbuf_t hostbuf=hostbuf_t()) - : memory_object(mem, retain, hostbuf) + : memory_object(mem, retain, PYOPENCL_STD_MOVE_IF_NEW_BUF_INTF(hostbuf)) { } py::object get_image_info(cl_image_info param_name) const @@ -2402,8 +2403,8 @@ namespace pyopencl context const &ctx, cl_mem_flags flags, cl_image_format const &fmt, - py::object shape, - py::object pitches, + py::tuple shape, + py::tuple pitches, py::object buffer) { if (shape.ptr() == Py_None) @@ -2458,8 +2459,8 @@ namespace pyopencl cl_mem mem; if (dims == 2) { - size_t width = py::extract(shape[0]); - size_t height = py::extract(shape[1]); + size_t width = (shape[0]).cast(); + size_t height = (shape[1]).cast(); size_t pitch = 0; if (pitches.ptr() != Py_None) @@ -2467,7 +2468,7 @@ namespace pyopencl if (py::len(pitches) != 1) throw pyopencl::error("Image", CL_INVALID_VALUE, "invalid length of pitch tuple"); - pitch = py::extract(pitches[0]); + pitch = (pitches[0]).cast(); } // check buffer size @@ -2488,9 +2489,9 @@ namespace pyopencl } else if (dims == 3) { - size_t width = py::extract(shape[0]); - size_t height = py::extract(shape[1]); - size_t depth = py::extract(shape[2]); + size_t width = (shape[0]).cast(); + size_t height = (shape[1]).cast(); + size_t depth = (shape[2]).cast(); size_t pitch_x = 0; size_t pitch_y = 0; @@ -2501,8 +2502,8 @@ namespace pyopencl throw pyopencl::error("Image", CL_INVALID_VALUE, "invalid length of pitch tuple"); - pitch_x = py::extract(pitches[0]); - pitch_y = py::extract(pitches[1]); + pitch_x = (pitches[0]).cast(); + pitch_y = (pitches[1]).cast(); } // check buffer size @@ -2533,7 +2534,7 @@ namespace pyopencl try { - return new image(mem, false, retained_buf_obj); + return new image(mem, false, PYOPENCL_STD_MOVE_IF_NEW_BUF_INTF(retained_buf_obj)); } catch (...) { @@ -2612,7 +2613,7 @@ namespace pyopencl try { - return new image(mem, false, retained_buf_obj); + return new image(mem, false, PYOPENCL_STD_MOVE_IF_NEW_BUF_INTF(retained_buf_obj)); } catch (...) { @@ -2849,6 +2850,7 @@ namespace pyopencl // }}} + // {{{ maps class memory_map { @@ -2911,7 +2913,7 @@ namespace pyopencl for (npy_intp sdim: shape) size_in_bytes *= sdim; - py::handle<> result; + py::object result; cl_event evt; cl_int status_code; @@ -2937,14 +2939,14 @@ namespace pyopencl std::unique_ptr map; try { - result = py::handle<>(PyArray_NewFromDescr( + result = py::object(py::reinterpret_steal(PyArray_NewFromDescr( &PyArray_Type, tp_descr, shape.size(), shape.empty() ? NULL : &shape.front(), strides.empty() ? NULL : &strides.front(), - mapped, ary_flags, /*obj*/NULL)); + mapped, ary_flags, /*obj*/NULL))); - if (size_in_bytes != (npy_uintp) PyArray_NBYTES(result.get())) + if (size_in_bytes != (npy_uintp) PyArray_NBYTES(result.ptr())) throw pyopencl::error("enqueue_map_buffer", CL_INVALID_VALUE, "miscalculated numpy array size (not contiguous?)"); @@ -2957,9 +2959,9 @@ namespace pyopencl throw; } - py::handle<> map_py(handle_from_new_ptr(map.release())); - PyArray_BASE(result.get()) = map_py.get(); - Py_INCREF(map_py.get()); + py::object map_py(handle_from_new_ptr(map.release())); + PyArray_BASE(result.ptr()) = map_py.ptr(); + Py_INCREF(map_py.ptr()); return py::make_tuple( result, @@ -3020,16 +3022,16 @@ namespace pyopencl throw; } - py::handle<> result = py::handle<>(PyArray_NewFromDescr( + py::object result = py::reinterpret_steal(PyArray_NewFromDescr( &PyArray_Type, tp_descr, shape.size(), shape.empty() ? NULL : &shape.front(), strides.empty() ? NULL : &strides.front(), mapped, ary_flags, /*obj*/NULL)); - py::handle<> map_py(handle_from_new_ptr(map.release())); - PyArray_BASE(result.get()) = map_py.get(); - Py_INCREF(map_py.get()); + py::object map_py(handle_from_new_ptr(map.release())); + PyArray_BASE(result.ptr()) = map_py.ptr(); + Py_INCREF(map_py.ptr()); return py::make_tuple( result, @@ -3039,8 +3041,10 @@ namespace pyopencl // }}} + // {{{ sampler - class sampler : boost::noncopyable + + class sampler : noncopyable { private: cl_sampler m_sampler; @@ -3107,9 +3111,10 @@ namespace pyopencl // }}} + // {{{ program - class program : boost::noncopyable + class program : noncopyable { public: enum program_kind_type { KND_UNKNOWN, KND_SOURCE, KND_BINARY }; @@ -3183,7 +3188,7 @@ namespace pyopencl size_t total_size = std::accumulate(sizes.begin(), sizes.end(), 0); - boost::scoped_array result( + std::unique_ptr result( new unsigned char[total_size]); std::vector result_ptrs; @@ -3202,7 +3207,8 @@ namespace pyopencl ptr = result.get(); for (unsigned i = 0; i < sizes.size(); ++i) { - py::handle<> binary_pyobj( + py::object binary_pyobj( + py::reinterpret_steal( #if PY_VERSION_HEX >= 0x03000000 PyBytes_FromStringAndSize( reinterpret_cast(ptr), sizes[i]) @@ -3210,7 +3216,7 @@ namespace pyopencl PyString_FromStringAndSize( reinterpret_cast(ptr), sizes[i]) #endif - ); + )); py_result.append(binary_pyobj); ptr += sizes[i]; } @@ -3278,13 +3284,14 @@ namespace pyopencl std::vector header_names; std::vector programs; - PYTHON_FOREACH(name_hdr_tup, py_headers) + PYTHON_FOREACH(name_hdr_tup_py, py_headers) { + py::tuple name_hdr_tup = py::reinterpret_borrow(name_hdr_tup_py); if (py::len(name_hdr_tup) != 2) throw error("Program.compile", CL_INVALID_VALUE, "epxected (name, header) tuple in headers list"); - std::string name = py::extract(name_hdr_tup[0]); - program &prg = py::extract(name_hdr_tup[1]); + std::string name = (name_hdr_tup[0]).cast(); + program &prg = (name_hdr_tup[1]).cast(); header_names.push_back(name); programs.push_back(prg.data()); @@ -3342,23 +3349,23 @@ namespace pyopencl inline program *create_program_with_binary( context &ctx, - py::object py_devices, - py::object py_binaries) + py::sequence py_devices, + py::sequence py_binaries) { std::vector devices; std::vector binaries; std::vector sizes; std::vector binary_statuses; - int num_devices = len(py_devices); + size_t num_devices = len(py_devices); if (len(py_binaries) != num_devices) throw error("create_program_with_binary", CL_INVALID_VALUE, "device and binary counts don't match"); - for (int i = 0; i < num_devices; ++i) + for (size_t i = 0; i < num_devices; ++i) { devices.push_back( - py::extract(py_devices[i])().data()); + (py_devices[i]).cast().data()); const void *buf; PYOPENCL_BUFFER_SIZE_T len; @@ -3457,7 +3464,7 @@ namespace pyopencl std::vector programs; PYTHON_FOREACH(py_prg, py_programs) { - program &prg = py::extract(py_prg); + program &prg = (py_prg).cast(); programs.push_back(prg.data()); } @@ -3498,6 +3505,7 @@ namespace pyopencl // }}} + // {{{ kernel class local_memory { @@ -3516,7 +3524,7 @@ namespace pyopencl - class kernel : boost::noncopyable + class kernel : noncopyable { private: cl_kernel m_kernel; @@ -3591,7 +3599,7 @@ namespace pyopencl { buf_wrapper.get(py_buffer.ptr(), PyBUF_ANY_CONTIGUOUS); } - catch (py::error_already_set) + catch (py::error_already_set &) { PyErr_Clear(); throw error("Kernel.set_arg", CL_INVALID_VALUE, @@ -3621,26 +3629,26 @@ namespace pyopencl return; } - py::extract ex_mo(arg); - if (ex_mo.check()) + try { - set_arg_mem(arg_index, ex_mo()); + set_arg_mem(arg_index, arg.cast()); return; } + catch (py::cast_error &) { } - py::extract ex_loc(arg); - if (ex_loc.check()) + try { - set_arg_local(arg_index, ex_loc()); + set_arg_local(arg_index, arg.cast()); return; } + catch (py::cast_error &) { } - py::extract ex_smp(arg); - if (ex_smp.check()) + try { - set_arg_sampler(arg_index, ex_smp()); + set_arg_sampler(arg_index, arg.cast()); return; } + catch (py::cast_error &) { } set_arg_buf(arg_index, arg); } @@ -3866,6 +3874,8 @@ namespace pyopencl // }}} + +#if 0 // {{{ gl interop inline bool have_gl() @@ -4026,7 +4036,7 @@ namespace pyopencl \ std::vector mem_objects; \ PYTHON_FOREACH(mo, py_mem_objects) \ - mem_objects.push_back(py::extract(mo)().data()); \ + mem_objects.push_back((mo).cast()().data()); \ \ cl_event evt; \ PYOPENCL_CALL_GUARDED(clEnqueue##What##GLObjects, ( \ @@ -4068,7 +4078,7 @@ namespace pyopencl #if PYOPENCL_CL_VERSION >= 0x1020 if (py_platform.ptr() != Py_None) { - platform &plat = py::extract(py_platform); + platform &plat = (py_platform).cast(); func_ptr = (func_ptr_type) clGetExtensionFunctionAddressForPlatform( plat.data(), "clGetGLContextInfoKHR"); @@ -4134,6 +4144,8 @@ namespace pyopencl #endif // }}} +#endif + // {{{ deferred implementation bits @@ -4223,13 +4235,13 @@ namespace pyopencl } inline - py::handle<> get_mem_obj_host_array( + py::object get_mem_obj_host_array( py::object mem_obj_py, py::object shape, py::object dtype, py::object order_py) { memory_object_holder const &mem_obj = - py::extract(mem_obj_py); + (mem_obj_py).cast(); PyArray_Descr *tp_descr; if (PyArray_DescrConverter(dtype.ptr(), &tp_descr) != NPY_SUCCEED) throw py::error_already_set(); @@ -4241,16 +4253,16 @@ namespace pyopencl "Only MemoryObject with USE_HOST_PTR " "is supported."); - py::extract shape_as_int(shape); std::vector dims; - - if (shape_as_int.check()) - dims.push_back(shape_as_int()); - else - std::copy( - py::stl_input_iterator(shape), - py::stl_input_iterator(), - back_inserter(dims)); + try + { + dims.push_back(py::cast(shape)); + } + catch (py::cast_error &) + { + for (auto it: shape) + dims.push_back(it.cast()); + } NPY_ORDER order = PyArray_CORDER; PyArray_OrderConverter(order_py.ptr(), &order); @@ -4272,24 +4284,23 @@ namespace pyopencl (mem_obj.data(), CL_MEM_SIZE, sizeof(mem_obj_size), &mem_obj_size, 0)); - py::handle<> result = py::handle<>(PyArray_NewFromDescr( + py::object result = py::reinterpret_steal(PyArray_NewFromDescr( &PyArray_Type, tp_descr, dims.size(), &dims.front(), /*strides*/ NULL, host_ptr, ary_flags, /*obj*/NULL)); - if ((size_t) PyArray_NBYTES(result.get()) > mem_obj_size) + if ((size_t) PyArray_NBYTES(result.ptr()) > mem_obj_size) throw pyopencl::error("MemoryObject.get_host_array", CL_INVALID_VALUE, "Resulting array is larger than memory object."); - PyArray_BASE(result.get()) = mem_obj_py.ptr(); + PyArray_BASE(result.ptr()) = mem_obj_py.ptr(); Py_INCREF(mem_obj_py.ptr()); return result; } // }}} - } diff --git a/src/wrap_cl_part_1.cpp b/src/wrap_cl_part_1.cpp index cff0734fdece4bf47a1cb22cbde0cb00b99b2f95..14ec060c8481cad884225fdbb4945f4f540a4a0e 100644 --- a/src/wrap_cl_part_1.cpp +++ b/src/wrap_cl_part_1.cpp @@ -8,12 +8,12 @@ using namespace pyopencl; -void pyopencl_expose_part_1() +void pyopencl_expose_part_1(py::module &m) { py::docstring_options doc_op; doc_op.disable_cpp_signatures(); - py::def("get_cl_header_version", get_cl_header_version); + m.def("get_cl_header_version", get_cl_header_version); // {{{ platform DEF_SIMPLE_FUNCTION(get_platforms); @@ -125,22 +125,22 @@ void pyopencl_expose_part_1() DEF_SIMPLE_FUNCTION(wait_for_events); #if PYOPENCL_CL_VERSION >= 0x1020 - py::def("_enqueue_marker_with_wait_list", enqueue_marker_with_wait_list, + m.def("_enqueue_marker_with_wait_list", enqueue_marker_with_wait_list, (py::arg("queue"), py::arg("wait_for")=py::object()), py::return_value_policy()); #endif - py::def("_enqueue_marker", enqueue_marker, + m.def("_enqueue_marker", enqueue_marker, (py::arg("queue")), py::return_value_policy()); - py::def("_enqueue_wait_for_events", enqueue_wait_for_events, + m.def("_enqueue_wait_for_events", enqueue_wait_for_events, (py::arg("queue"), py::arg("wait_for")=py::object())); #if PYOPENCL_CL_VERSION >= 0x1020 - py::def("_enqueue_barrier_with_wait_list", enqueue_barrier_with_wait_list, + m.def("_enqueue_barrier_with_wait_list", enqueue_barrier_with_wait_list, (py::arg("queue"), py::arg("wait_for")=py::object()), py::return_value_policy()); #endif - py::def("_enqueue_barrier", enqueue_barrier, py::arg("queue")); + m.def("_enqueue_barrier", enqueue_barrier, py::arg("queue")); #if PYOPENCL_CL_VERSION >= 0x1010 { @@ -168,7 +168,7 @@ void pyopencl_expose_part_1() .def(py::self != py::self) .def("__hash__", &cls::hash) - .add_property("int_ptr", to_int_ptr, + .def_property("int_ptr", to_int_ptr, "Return an integer corresponding to the pointer value " "of the underlying :c:type:`cl_mem`. " "Use :meth:`from_int_ptr` to turn back into a Python object." @@ -180,7 +180,7 @@ void pyopencl_expose_part_1() py::class_ >( "MemoryObject", py::no_init) .DEF_SIMPLE_METHOD(release) - .add_property("hostbuf", &cls::hostbuf) + .def_property("hostbuf", &cls::hostbuf) .def("from_int_ptr", memory_object_from_int, "(static method) Return a new Python object referencing the C-level " \ @@ -197,7 +197,7 @@ void pyopencl_expose_part_1() } #if PYOPENCL_CL_VERSION >= 0x1020 - py::def("enqueue_migrate_mem_objects", enqueue_migrate_mem_objects, + m.def("enqueue_migrate_mem_objects", enqueue_migrate_mem_objects, (py::args("queue", "mem_objects"), py::arg("flags")=0, py::arg("wait_for")=py::object() @@ -206,7 +206,7 @@ void pyopencl_expose_part_1() #endif #ifdef cl_ext_migrate_memobject - py::def("enqueue_migrate_mem_object_ext", enqueue_migrate_mem_object_ext, + m.def("enqueue_migrate_mem_object_ext", enqueue_migrate_mem_object_ext, (py::args("queue", "mem_objects"), py::arg("flags")=0, py::arg("wait_for")=py::object() @@ -241,21 +241,21 @@ void pyopencl_expose_part_1() // {{{ transfers // {{{ byte-for-byte - py::def("_enqueue_read_buffer", enqueue_read_buffer, + m.def("_enqueue_read_buffer", enqueue_read_buffer, (py::args("queue", "mem", "hostbuf"), py::arg("device_offset")=0, py::arg("wait_for")=py::object(), py::arg("is_blocking")=true ), py::return_value_policy()); - py::def("_enqueue_write_buffer", enqueue_write_buffer, + m.def("_enqueue_write_buffer", enqueue_write_buffer, (py::args("queue", "mem", "hostbuf"), py::arg("device_offset")=0, py::arg("wait_for")=py::object(), py::arg("is_blocking")=true ), py::return_value_policy()); - py::def("_enqueue_copy_buffer", enqueue_copy_buffer, + m.def("_enqueue_copy_buffer", enqueue_copy_buffer, (py::args("queue", "src", "dst"), py::arg("byte_count")=-1, py::arg("src_offset")=0, @@ -269,7 +269,7 @@ void pyopencl_expose_part_1() // {{{ rectangular #if PYOPENCL_CL_VERSION >= 0x1010 - py::def("_enqueue_read_buffer_rect", enqueue_read_buffer_rect, + m.def("_enqueue_read_buffer_rect", enqueue_read_buffer_rect, (py::args("queue", "mem", "hostbuf", "buffer_origin", "host_origin", "region"), py::arg("buffer_pitches")=py::object(), @@ -278,7 +278,7 @@ void pyopencl_expose_part_1() py::arg("is_blocking")=true ), py::return_value_policy()); - py::def("_enqueue_write_buffer_rect", enqueue_write_buffer_rect, + m.def("_enqueue_write_buffer_rect", enqueue_write_buffer_rect, (py::args("queue", "mem", "hostbuf", "buffer_origin", "host_origin", "region"), py::arg("buffer_pitches")=py::object(), @@ -287,7 +287,7 @@ void pyopencl_expose_part_1() py::arg("is_blocking")=true ), py::return_value_policy()); - py::def("_enqueue_copy_buffer_rect", enqueue_copy_buffer_rect, + m.def("_enqueue_copy_buffer_rect", enqueue_copy_buffer_rect, (py::args("queue", "src", "dst", "src_origin", "dst_origin", "region"), py::arg("src_pitches")=py::object(), @@ -302,7 +302,7 @@ void pyopencl_expose_part_1() // }}} #if PYOPENCL_CL_VERSION >= 0x1020 - py::def("_enqueue_fill_buffer", enqueue_fill_buffer, + m.def("_enqueue_fill_buffer", enqueue_fill_buffer, (py::args("queue", "mem", "pattern", "offset", "size"), py::arg("wait_for")=py::object()), py::return_value_policy()); diff --git a/src/wrap_cl_part_2.cpp b/src/wrap_cl_part_2.cpp index 4d010796ad5382838c724c049907a48c0dc33453..3ebc5a654d757acfe1ec8454fe567fb45fe15784 100644 --- a/src/wrap_cl_part_2.cpp +++ b/src/wrap_cl_part_2.cpp @@ -45,32 +45,29 @@ using namespace pyopencl; -void pyopencl_expose_part_2() +void pyopencl_expose_part_2(py::module &m) { - py::docstring_options doc_op; - doc_op.disable_cpp_signatures(); - // {{{ image #if PYOPENCL_CL_VERSION >= 0x1020 { typedef cl_image_desc cls; - py::class_("ImageDescriptor") + py::class_(m, "ImageDescriptor") .def_readwrite("image_type", &cls::image_type) - .add_property("shape", &image_desc_dummy_getter, image_desc_set_shape) + .def_property("shape", &image_desc_dummy_getter, image_desc_set_shape) .def_readwrite("array_size", &cls::image_array_size) - .add_property("pitches", &image_desc_dummy_getter, image_desc_set_pitches) + .def_property("pitches", &image_desc_dummy_getter, image_desc_set_pitches) .def_readwrite("num_mip_levels", &cls::num_mip_levels) .def_readwrite("num_samples", &cls::num_samples) - .add_property("buffer", &image_desc_dummy_getter, image_desc_set_buffer) + .def_property("buffer", &image_desc_dummy_getter, image_desc_set_buffer) ; } #endif { typedef image cls; - py::class_, boost::noncopyable>( - "Image", py::no_init) + py::class_/* , boost::noncopyable */>( + m, "Image"/* , py::no_init */) .def("__init__", make_constructor(create_image, py::default_call_policies(), (py::args("context", "flags", "format"), @@ -94,15 +91,15 @@ void pyopencl_expose_part_2() .def("__init__", py::make_constructor(make_image_format)) .def_readwrite("channel_order", &cls::image_channel_order) .def_readwrite("channel_data_type", &cls::image_channel_data_type) - .add_property("channel_count", &get_image_format_channel_count) - .add_property("dtype_size", &get_image_format_channel_dtype_size) - .add_property("itemsize", &get_image_format_item_size) + .def_property("channel_count", &get_image_format_channel_count) + .def_property("dtype_size", &get_image_format_channel_dtype_size) + .def_property("itemsize", &get_image_format_item_size) ; } DEF_SIMPLE_FUNCTION(get_supported_image_formats); - py::def("_enqueue_read_image", enqueue_read_image, + m.def("_enqueue_read_image", enqueue_read_image, (py::args("queue", "mem", "origin", "region", "hostbuf"), py::arg("row_pitch")=0, py::arg("slice_pitch")=0, @@ -110,7 +107,7 @@ void pyopencl_expose_part_2() py::arg("is_blocking")=true ), py::return_value_policy()); - py::def("_enqueue_write_image", enqueue_write_image, + m.def("_enqueue_write_image", enqueue_write_image, (py::args("queue", "mem", "origin", "region", "hostbuf"), py::arg("row_pitch")=0, py::arg("slice_pitch")=0, @@ -119,21 +116,21 @@ void pyopencl_expose_part_2() ), py::return_value_policy()); - py::def("_enqueue_copy_image", enqueue_copy_image, + m.def("_enqueue_copy_image", enqueue_copy_image, (py::args("queue", "src", "dest", "src_origin", "dest_origin", "region"), py::arg("wait_for")=py::object()), py::return_value_policy()); - py::def("_enqueue_copy_image_to_buffer", enqueue_copy_image_to_buffer, + m.def("_enqueue_copy_image_to_buffer", enqueue_copy_image_to_buffer, (py::args("queue", "src", "dest", "origin", "region", "offset"), py::arg("wait_for")=py::object()), py::return_value_policy()); - py::def("_enqueue_copy_buffer_to_image", enqueue_copy_buffer_to_image, + m.def("_enqueue_copy_buffer_to_image", enqueue_copy_buffer_to_image, (py::args("queue", "src", "dest", "offset", "origin", "region"), py::arg("wait_for")=py::object()), py::return_value_policy()); #if PYOPENCL_CL_VERSION >= 0x1020 - py::def("enqueue_fill_image", enqueue_write_image, + m.def("enqueue_fill_image", enqueue_write_image, (py::args("queue", "mem", "color", "origin", "region"), py::arg("wait_for")=py::object()), py::return_value_policy()); @@ -151,7 +148,7 @@ void pyopencl_expose_part_2() ; } - py::def("enqueue_map_buffer", enqueue_map_buffer, + m.def("enqueue_map_buffer", enqueue_map_buffer, (py::args("queue", "buf", "flags", "offset", "shape", "dtype"), @@ -159,7 +156,7 @@ void pyopencl_expose_part_2() py::arg("strides")=py::object(), py::arg("wait_for")=py::object(), py::arg("is_blocking")=true)); - py::def("enqueue_map_image", enqueue_map_image, + m.def("enqueue_map_image", enqueue_map_image, (py::args("queue", "img", "flags", "origin", "region", "shape", "dtype"), @@ -237,7 +234,7 @@ void pyopencl_expose_part_2() } #if PYOPENCL_CL_VERSION >= 0x1020 - py::def("unload_platform_compiler", unload_platform_compiler); + m.def("unload_platform_compiler", unload_platform_compiler); #endif // }}} @@ -265,12 +262,12 @@ void pyopencl_expose_part_2() typedef local_memory cls; py::class_("LocalMemory", py::init(py::arg("size"))) - .add_property("size", &cls::size) + .def_property("size", &cls::size) ; } - py::def("enqueue_nd_range_kernel", enqueue_nd_range_kernel, + m.def("enqueue_nd_range_kernel", enqueue_nd_range_kernel, (py::args("queue", "kernel"), py::arg("global_work_size"), py::arg("local_work_size"), @@ -279,7 +276,7 @@ void pyopencl_expose_part_2() py::arg("g_times_l")=false ), py::return_value_policy()); - py::def("enqueue_task", enqueue_task, + m.def("enqueue_task", enqueue_task, (py::args("queue", "kernel"), py::arg("wait_for")=py::object() ), @@ -333,19 +330,19 @@ void pyopencl_expose_part_2() ; } - py::def("enqueue_acquire_gl_objects", enqueue_acquire_gl_objects, + m.def("enqueue_acquire_gl_objects", enqueue_acquire_gl_objects, (py::args("queue", "mem_objects"), py::arg("wait_for")=py::object() ), py::return_value_policy()); - py::def("enqueue_release_gl_objects", enqueue_release_gl_objects, + m.def("enqueue_release_gl_objects", enqueue_release_gl_objects, (py::args("queue", "mem_objects"), py::arg("wait_for")=py::object() ), py::return_value_policy()); #if defined(cl_khr_gl_sharing) && (cl_khr_gl_sharing >= 1) - py::def("get_gl_context_info_khr", get_gl_context_info_khr, + m.def("get_gl_context_info_khr", get_gl_context_info_khr, (py::args("properties", "param_name"), py::arg("platform")=py::object())); #endif diff --git a/src/wrap_helpers.hpp b/src/wrap_helpers.hpp index 866e800208c2deabf54b6ef98c4aaaaefc51589f..6afaa73d4b30cc2237ee503bd7bcb5cd61f2f11c 100644 --- a/src/wrap_helpers.hpp +++ b/src/wrap_helpers.hpp @@ -20,14 +20,17 @@ namespace py = pybind11; #define DEF_SIMPLE_METHOD(NAME) \ def(#NAME, &cls::NAME) +#define DEF_SIMPLE_STATIC_METHOD(NAME) \ + def_static(#NAME, &cls::NAME) + #define DEF_SIMPLE_METHOD_WITH_ARGS(NAME, ARGS) \ def(#NAME, &cls::NAME, boost::python::args ARGS) #define DEF_SIMPLE_FUNCTION(NAME) \ - boost::python::def(#NAME, &NAME) + m.def(#NAME, &NAME) #define DEF_SIMPLE_FUNCTION_WITH_ARGS(NAME, ARGS) \ - boost::python::def(#NAME, &NAME, boost::python::args ARGS) + m.def(#NAME, &NAME, py::args ARGS) #define DEF_SIMPLE_RO_MEMBER(NAME) \ def_readonly(#NAME, &cls::m_##NAME) @@ -36,43 +39,46 @@ namespace py = pybind11; def_readwrite(#NAME, &cls::m_##NAME) #define PYTHON_FOREACH(NAME, ITERABLE) \ - for (py::object NAME: ITERABLE) + for (py::handle NAME: ITERABLE) #define COPY_PY_LIST(TYPE, NAME) \ - std::copy( \ - boost::python::stl_input_iterator(py_##NAME), \ - boost::python::stl_input_iterator(), \ - std::back_inserter(NAME)); + { \ + for (auto it: py_##NAME) \ + NAME.push_back(it.cast()); \ + } #define COPY_PY_COORD_TRIPLE(NAME) \ size_t NAME[3] = {0, 0, 0}; \ { \ - size_t my_len = len(py_##NAME); \ + py::tuple py_tup_##NAME = py_##NAME; \ + size_t my_len = len(py_tup_##NAME); \ if (my_len > 3) \ throw error("transfer", CL_INVALID_VALUE, #NAME "has too many components"); \ for (size_t i = 0; i < my_len; ++i) \ - NAME[i] = py::extract(py_##NAME[i])(); \ + NAME[i] = py_tup_##NAME[i].cast(); \ } #define COPY_PY_PITCH_TUPLE(NAME) \ size_t NAME[2] = {0, 0}; \ if (py_##NAME.ptr() != Py_None) \ { \ - size_t my_len = len(py_##NAME); \ + py::tuple py_tup_##NAME = py_##NAME; \ + size_t my_len = len(py_tup_##NAME); \ if (my_len > 2) \ throw error("transfer", CL_INVALID_VALUE, #NAME "has too many components"); \ for (size_t i = 0; i < my_len; ++i) \ - NAME[i] = py::extract(py_##NAME[i])(); \ + NAME[i] = py_tup_##NAME[i].cast(); \ } #define COPY_PY_REGION_TRIPLE(NAME) \ size_t NAME[3] = {1, 1, 1}; \ { \ - size_t my_len = len(py_##NAME); \ + py::tuple py_tup_##NAME = py_##NAME; \ + size_t my_len = len(py_tup_##NAME); \ if (my_len > 3) \ throw error("transfer", CL_INVALID_VALUE, #NAME "has too many components"); \ for (size_t i = 0; i < my_len; ++i) \ - NAME[i] = py::extract(py_##NAME[i])(); \ + NAME[i] = py_tup_##NAME[i].cast(); \ } #define PYOPENCL_PARSE_NUMPY_ARRAY_SPEC \ @@ -80,13 +86,15 @@ namespace py = pybind11; if (PyArray_DescrConverter(dtype.ptr(), &tp_descr) != NPY_SUCCEED) \ throw py::error_already_set(); \ \ - py::extract shape_as_int(py_shape); \ std::vector shape; \ - \ - if (shape_as_int.check()) \ - shape.push_back(shape_as_int()); \ - else \ + try \ + { \ + shape.push_back(py_shape.cast()); \ + } \ + catch (py::cast_error &) \ + { \ COPY_PY_LIST(npy_intp, shape); \ + } \ \ NPY_ORDER order = PyArray_CORDER; \ PyArray_OrderConverter(py_order.ptr(), &order); \ @@ -108,7 +116,7 @@ namespace py = pybind11; #define PYOPENCL_RETURN_VECTOR(ITEMTYPE, NAME) \ { \ py::list pyopencl_result; \ - BOOST_FOREACH(ITEMTYPE item, NAME) \ + for (ITEMTYPE item: NAME) \ pyopencl_result.append(item); \ return pyopencl_result; \ } @@ -116,10 +124,9 @@ namespace py = pybind11; namespace { template - inline boost::python::handle<> handle_from_new_ptr(T *ptr) + inline py::object handle_from_new_ptr(T *ptr) { - return boost::python::handle<>( - typename boost::python::manage_new_object::apply::type()(ptr)); + return py::cast(ptr); } template diff --git a/src/wrap_mempool.cpp b/src/wrap_mempool.cpp index c785d168f78dba52684f3af336d5b1a86ab67dc5..78fa9acd5d1ad7c0d2479a09ce087686be8458b8 100644 --- a/src/wrap_mempool.cpp +++ b/src/wrap_mempool.cpp @@ -5,13 +5,12 @@ #include #include #include "wrap_helpers.hpp" -// #include "wrap_cl.hpp" +#include "wrap_cl.hpp" #include "mempool.hpp" #include "tools.hpp" - namespace { class cl_allocator_base @@ -209,16 +208,14 @@ namespace template void expose_memory_pool(Wrapper &wrapper) { - typedef typename Wrapper::wrapped_type cls; + typedef typename Wrapper::type cls; wrapper - .add_property("held_blocks", &cls::held_blocks) - .add_property("active_blocks", &cls::active_blocks) - .DEF_SIMPLE_METHOD(bin_number) - .DEF_SIMPLE_METHOD(alloc_size) + .def_property("held_blocks", &cls::held_blocks) + .def_property("active_blocks", &cls::active_blocks) + .DEF_SIMPLE_STATIC_METHOD(bin_number) + .DEF_SIMPLE_STATIC_METHOD(alloc_size) .DEF_SIMPLE_METHOD(free_held) .DEF_SIMPLE_METHOD(stop_holding) - .staticmethod("bin_number") - .staticmethod("alloc_size") ; } } @@ -226,47 +223,53 @@ namespace -void pyopencl_expose_mempool() +void pyopencl_expose_mempool(py::module &m) { - py::def("bitlog2", pyopencl::bitlog2); + m.def("bitlog2", pyopencl::bitlog2); { typedef cl_allocator_base cls; - py::class_ wrapper("_tools_AllocatorBase", py::no_init); + py::class_ wrapper( + m, "_tools_AllocatorBase"/*, py::no_init */); wrapper - .def("__call__", allocator_call, - py::return_value_policy()) + .def("__call__", allocator_call) ; } { typedef cl_deferred_allocator cls; - py::class_ > wrapper("_tools_DeferredAllocator", - py::init< + py::class_> wrapper( + m, "_tools_DeferredAllocator"); + wrapper + .def(py::init< + std::shared_ptr const &>()) + .def(py::init< std::shared_ptr const &, - py::optional >()); + cl_mem_flags>()) + ; } { typedef cl_immediate_allocator cls; - py::class_ > wrapper("_tools_ImmediateAllocator", - py::init >()); + py::class_> wrapper( + m, "_tools_ImmediateAllocator"); + wrapper + .def(py::init()) + .def(py::init()) + ; } { typedef pyopencl::memory_pool cls; py::class_< - cls, boost::noncopyable, - std::shared_ptr > wrapper("MemoryPool", - py::init() - ); + cls, /* boost::noncopyable, */ + std::shared_ptr> wrapper( m, "MemoryPool"); wrapper - .def("allocate", device_pool_allocate, - py::return_value_policy()) - .def("__call__", device_pool_allocate, - py::return_value_policy()) + .def(py::init()) + .def("allocate", device_pool_allocate) + .def("__call__", device_pool_allocate) // undoc for now .DEF_SIMPLE_METHOD(set_trace) ; @@ -276,9 +279,9 @@ void pyopencl_expose_mempool() { typedef pooled_buffer cls; - py::class_ >( - "PooledBuffer", py::no_init) + py::class_ >( + m, "PooledBuffer"/* , py::no_init */) .def("release", &cls::free) ; }