1 #ifndef hamr_buffer_handle_h
2 #define hamr_buffer_handle_h
4 #include "hamr_config.h"
7 #include "hamr_gil_state.h"
18 #define array_interface_tt_declare(ENDIAN, KIND, SIZE, CPP_T) \
20 template <> struct array_interface_tt<CPP_T> \
23 static constexpr size_t elemsize() \
28 static constexpr char typekind() \
33 static constexpr bool little_endian() \
35 return (#ENDIAN) [0] == '<'; \
38 static constexpr const char *descr() \
40 return #ENDIAN #KIND #SIZE; \
43 array_interface_tt_declare(<, i, 1,
char)
44 array_interface_tt_declare(<, i, 2,
short)
45 array_interface_tt_declare(<, i, 4,
int)
46 array_interface_tt_declare(<, i, 8,
long)
47 array_interface_tt_declare(<, i, 8,
long long)
48 array_interface_tt_declare(<, u, 1,
unsigned char)
49 array_interface_tt_declare(<, u, 2,
unsigned short)
50 array_interface_tt_declare(<, u, 4,
unsigned int)
51 array_interface_tt_declare(<, u, 8,
unsigned long)
52 array_interface_tt_declare(<, u, 8,
unsigned long long)
53 array_interface_tt_declare(<, f, 4,
float)
54 array_interface_tt_declare(<, f, 8,
double)
61 #define buffer_handle_tt_declare(CPP_T, SWIG_T) \
62 template <> struct buffer_handle_tt<CPP_T> \
64 static swig_type_info *swig_type() \
70 buffer_handle_tt_declare(
float, SWIGTYPE_p_hamr__buffer_handleT_float_t)
71 buffer_handle_tt_declare(
double, SWIGTYPE_p_hamr__buffer_handleT_double_t)
72 buffer_handle_tt_declare(
char, SWIGTYPE_p_hamr__buffer_handleT_char_t)
73 buffer_handle_tt_declare(
short, SWIGTYPE_p_hamr__buffer_handleT_short_t)
74 buffer_handle_tt_declare(
int, SWIGTYPE_p_hamr__buffer_handleT_int_t)
75 buffer_handle_tt_declare(
long, SWIGTYPE_p_hamr__buffer_handleT_long_t)
76 buffer_handle_tt_declare(
long long, SWIGTYPE_p_hamr__buffer_handleT_long_long_t)
77 buffer_handle_tt_declare(
unsigned char, SWIGTYPE_p_hamr__buffer_handleT_unsigned_char_t)
78 buffer_handle_tt_declare(
unsigned short, SWIGTYPE_p_hamr__buffer_handleT_unsigned_short_t)
79 buffer_handle_tt_declare(
unsigned int, SWIGTYPE_p_hamr__buffer_handleT_unsigned_int_t)
80 buffer_handle_tt_declare(
unsigned long, SWIGTYPE_p_hamr__buffer_handleT_unsigned_long_t)
81 buffer_handle_tt_declare(
unsigned long long, SWIGTYPE_p_hamr__buffer_handleT_unsigned_long_long_t)
96 m_read_only(0), m_cpu_accessible(0), m_cuda_accessible(0),
106 buffer_handle(
const std::shared_ptr<const T> &src,
size_t size,
128 PyObject *get_cuda_array_interface();
133 PyObject *get_numpy_array_interface();
141 PyObject *get_array_interface();
143 void to_stream(std::ostream &os)
const;
145 std::shared_ptr<T> m_data;
148 int m_cpu_accessible;
149 int m_cuda_accessible;
154 template <
typename T>
155 std::ostream &operator<<(std::ostream &os,
const buffer_handle<T> &buf)
162 template <
typename T>
163 void buffer_handle<T>::to_stream(std::ostream &os)
const
165 os <<
"buffer_handle<" <<
typeid(T).name() <<
sizeof(T)
166 <<
"> m_data = " <<
size_t(this->m_data.get())
167 <<
" m_size = " << this->m_size <<
" m_read_only = "
168 << this->m_read_only <<
" m_cpu_accessible = "
169 << this->m_cpu_accessible <<
" m_cuda_accessible = "
170 << this->m_cuda_accessible;
174 template <
typename T>
177 size_t stream) : m_data(src), m_size(size), m_read_only(read_only),
183 std::cerr <<
"buffer_handle::construct " << *
this << std::endl;
188 template <
typename T>
197 template <
typename T>
202 std::cerr <<
"buffer_handle::destruct " << *
this << std::endl;
207 template <
typename T>
209 m_data(other.m_data), m_size(other.m_size),
210 m_read_only(other.m_read_only), m_cpu_accessible(other.m_cpu_accessible),
211 m_cuda_accessible(other.m_cuda_accessible), m_stream(other.m_stream)
215 std::cerr <<
"buffer_handle::copy construct " << *
this << std::endl;
220 template <
typename T>
222 m_data(std::move(other.m_data)), m_size(other.m_size),
223 m_read_only(other.m_read_only), m_cpu_accessible(other.m_cpu_accessible),
224 m_cuda_accessible(other.m_cuda_accessible), m_stream(other.m_stream)
228 std::cerr <<
"buffer_handle::move construct " << *
this << std::endl;
233 template <
typename T>
238 if (!m_cuda_accessible)
240 PyErr_SetString(PyExc_AttributeError,
241 "The data is not accessible from CUDA");
247 std::cerr <<
"buffer_handle<" <<
typeid(T).name() <<
sizeof(T)
248 <<
">::get_cuda_array_interface()" << std::endl;
251 return this->get_array_interface();
255 template <
typename T>
260 if (!m_cpu_accessible)
262 PyErr_SetString(PyExc_AttributeError,
263 "The data is not accessible from the CPU");
269 std::cerr <<
"buffer_handle<" <<
typeid(T).name() <<
sizeof(T)
270 <<
">::get_numpy_array_interface()" << std::endl;
273 return this->get_array_interface();
277 template <
typename T>
281 PyObject *shape = PyTuple_New(1);
282 PyTuple_SetItem(shape, 0, PyLong_FromLong(m_size));
289 PyObject *descr_tup = PyTuple_New(2);
290 PyTuple_SetItem(descr_tup, 0, PyUnicode_FromString(
""));
291 PyTuple_SetItem(descr_tup, 1, typestr);
292 PyObject *descr = PyList_New(1);
293 PyList_SetItem(descr, 0, descr_tup);
296 PyObject *
data = PyTuple_New(2);
297 PyTuple_SetItem(
data, 0, PyLong_FromSize_t(
size_t(m_data.get())));
298 PyTuple_SetItem(
data, 1, PyBool_FromLong(m_read_only));
301 PyObject *strides = Py_None;
304 PyObject *mask = Py_None;
307 PyObject *strm = PyLong_FromSize_t(m_stream);
310 PyObject *version = PyLong_FromLong(3);
313 PyObject *aint = PyDict_New();
314 PyDict_SetItemString(aint,
"shape", shape);
315 PyDict_SetItemString(aint,
"typestr", typestr);
316 PyDict_SetItemString(aint,
"descr", descr);
317 PyDict_SetItemString(aint,
"data",
data);
318 PyDict_SetItemString(aint,
"strides", strides);
319 PyDict_SetItemString(aint,
"mask", mask);
320 PyDict_SetItemString(aint,
"stream", strm);
321 PyDict_SetItemString(aint,
"version", version);