12 #include <hipipe/build_config.hpp>
13 #ifdef HIPIPE_BUILD_PYTHON
16 #include <hipipe/core/python/initialize.hpp>
19 #include <boost/python.hpp>
20 #include <numpy/ndarrayobject.h>
25 namespace hipipe::python::utility {
30 struct to_ndarray_trait
32 using type_t = PyObject*;
34 static PyObject* convert(T val)
36 boost::python::object obj{std::move(val)};
47 #define HIPIPE_DEFINE_TO_NDARRAY_TRAIT(C_TYPE, NP_TYPE, TYPENUM) \
49 struct to_ndarray_trait<C_TYPE> \
51 using type_t = NP_TYPE; \
53 static NP_TYPE convert(C_TYPE val) \
58 static int typenum() \
64 HIPIPE_DEFINE_TO_NDARRAY_TRAIT(
bool, npy_bool, NPY_BOOL);
65 HIPIPE_DEFINE_TO_NDARRAY_TRAIT(std::int8_t, npy_byte, NPY_BYTE);
66 HIPIPE_DEFINE_TO_NDARRAY_TRAIT(std::uint8_t, npy_ubyte, NPY_UBYTE);
67 HIPIPE_DEFINE_TO_NDARRAY_TRAIT(std::int16_t, npy_int16, NPY_INT16);
68 HIPIPE_DEFINE_TO_NDARRAY_TRAIT(std::uint16_t, npy_uint16, NPY_UINT16);
69 HIPIPE_DEFINE_TO_NDARRAY_TRAIT(std::int32_t, npy_int32, NPY_INT32);
70 HIPIPE_DEFINE_TO_NDARRAY_TRAIT(std::uint32_t, npy_uint32, NPY_UINT32);
71 HIPIPE_DEFINE_TO_NDARRAY_TRAIT(std::int64_t, npy_int64, NPY_INT64);
72 HIPIPE_DEFINE_TO_NDARRAY_TRAIT(std::uint64_t, npy_uint64, NPY_UINT64);
73 HIPIPE_DEFINE_TO_NDARRAY_TRAIT(
float, npy_float, NPY_FLOAT);
74 HIPIPE_DEFINE_TO_NDARRAY_TRAIT(
double, npy_double, NPY_DOUBLE);
75 HIPIPE_DEFINE_TO_NDARRAY_TRAIT(
long double, npy_longdouble, NPY_LONGDOUBLE);
76 HIPIPE_DEFINE_TO_NDARRAY_TRAIT(PyObject*, PyObject*, NPY_OBJECT);
78 #undef HIPIPE_DEFINE_TO_NDARRAY_TRAIT
86 auto to_ndarray_element(T val)
88 return detail::to_ndarray_trait<T>::convert(std::move(val));
94 using ndarray_type_t =
typename detail::to_ndarray_trait<T>::type_t;
99 int to_ndarray_typenum()
101 return detail::to_ndarray_trait<T>::typenum();
109 PyObject* to_ndarray(std::vector<T> vec)
111 auto data = std::make_unique<detail::ndarray_type_t<T>[]>(vec.size());
112 for (std::size_t i = 0; i < vec.size(); ++i) {
114 if constexpr(std::is_same_v<T, bool>) {
115 data[i] = detail::to_ndarray_element((
bool)vec[i]);
117 data[i] = detail::to_ndarray_element(std::move(vec[i]));
120 npy_intp dims[1]{static_cast<npy_intp>(vec.size())};
122 PyObject* arr = PyArray_SimpleNewFromData(
123 1, dims, detail::to_ndarray_typenum<T>(), reinterpret_cast<void*>(data.release()));
124 if (!arr)
throw std::runtime_error{
"Cannot create Python NumPy ndarray."};
126 PyArray_ENABLEFLAGS(reinterpret_cast<PyArrayObject*>(arr), NPY_ARRAY_OWNDATA);
132 #endif // HIPIPE_BUILD_PYTHON