1
#ifndef PYCUDA_WRAP_HELPERS_HEADER_SEEN
2
#define PYCUDA_WRAP_HELPERS_HEADER_SEEN
7
#include <boost/version.hpp>
8
#include <boost/python.hpp>
9
#include <boost/python/stl_iterator.hpp>
14
namespace py = boost::python;
19
#if (BOOST_VERSION/100) < 1035
20
#warning *******************************************************************
21
#warning **** Your version of Boost C++ is likely too old for PyOpenCL. ****
22
#warning *******************************************************************
28
#define PYTHON_ERROR(TYPE, REASON) \
30
PyErr_SetString(PyExc_##TYPE, REASON); \
31
throw boost::python::error_already_set(); \
34
#define ENUM_VALUE(NAME) \
37
#define DEF_SIMPLE_METHOD(NAME) \
38
def(#NAME, &cls::NAME)
40
#define DEF_SIMPLE_METHOD_WITH_ARGS(NAME, ARGS) \
41
def(#NAME, &cls::NAME, boost::python::args ARGS)
43
#define DEF_SIMPLE_FUNCTION(NAME) \
44
boost::python::def(#NAME, &NAME)
46
#define DEF_SIMPLE_FUNCTION_WITH_ARGS(NAME, ARGS) \
47
boost::python::def(#NAME, &NAME, boost::python::args ARGS)
49
#define DEF_SIMPLE_RO_MEMBER(NAME) \
50
def_readonly(#NAME, &cls::m_##NAME)
52
#define DEF_SIMPLE_RW_MEMBER(NAME) \
53
def_readwrite(#NAME, &cls::m_##NAME)
55
#define PYTHON_FOREACH(NAME, ITERABLE) \
56
BOOST_FOREACH(boost::python::object NAME, \
58
boost::python::stl_input_iterator<boost::python::object>(ITERABLE), \
59
boost::python::stl_input_iterator<boost::python::object>()))
61
#define COPY_PY_LIST(TYPE, NAME) \
63
boost::python::stl_input_iterator<TYPE>(py_##NAME), \
64
boost::python::stl_input_iterator<TYPE>(), \
65
std::back_inserter(NAME));
67
#define COPY_PY_COORD_TRIPLE(NAME) \
68
size_t NAME[3] = {0, 0, 0}; \
70
size_t my_len = len(py_##NAME); \
72
throw error("transfer", CL_INVALID_VALUE, #NAME "has too many components"); \
73
for (size_t i = 0; i < my_len; ++i) \
74
NAME[i] = py::extract<size_t>(py_##NAME[i])(); \
77
#define COPY_PY_PITCH_TUPLE(NAME) \
78
size_t NAME[2] = {0, 0}; \
79
if (py_##NAME.ptr() != Py_None) \
81
size_t my_len = len(py_##NAME); \
83
throw error("transfer", CL_INVALID_VALUE, #NAME "has too many components"); \
84
for (size_t i = 0; i < my_len; ++i) \
85
NAME[i] = py::extract<size_t>(py_##NAME[i])(); \
88
#define COPY_PY_REGION_TRIPLE(NAME) \
89
size_t NAME[3] = {1, 1, 1}; \
91
size_t my_len = len(py_##NAME); \
93
throw error("transfer", CL_INVALID_VALUE, #NAME "has too many components"); \
94
for (size_t i = 0; i < my_len; ++i) \
95
NAME[i] = py::extract<size_t>(py_##NAME[i])(); \
98
#define PYOPENCL_PARSE_NUMPY_ARRAY_SPEC \
99
PyArray_Descr *tp_descr; \
100
if (PyArray_DescrConverter(dtype.ptr(), &tp_descr) != NPY_SUCCEED) \
101
throw py::error_already_set(); \
103
py::extract<npy_intp> shape_as_int(py_shape); \
104
std::vector<npy_intp> shape; \
106
if (shape_as_int.check()) \
107
shape.push_back(shape_as_int()); \
109
COPY_PY_LIST(npy_intp, shape); \
111
NPY_ORDER order = PyArray_CORDER; \
112
PyArray_OrderConverter(order_py.ptr(), &order); \
115
if (order == PyArray_FORTRANORDER) \
116
ary_flags |= NPY_FARRAY; \
117
else if (order == PyArray_CORDER) \
118
ary_flags |= NPY_CARRAY; \
120
throw std::runtime_error("unrecognized order specifier"); \
122
#define PYOPENCL_RETURN_VECTOR(ITEMTYPE, NAME) \
124
py::list pyopencl_result; \
125
BOOST_FOREACH(ITEMTYPE item, NAME) \
126
pyopencl_result.append(item); \
127
return pyopencl_result; \
132
template <typename T>
133
inline boost::python::handle<> handle_from_new_ptr(T *ptr)
135
return boost::python::handle<>(
136
typename boost::python::manage_new_object::apply<T *>::type()(ptr));