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