// ascee_python.h // // Author: J.A. de Jong - ASCEE // // Description: // Routine to generate a Numpy array from an arbitrary buffer. Careful, this // code should both be C and C++ compatible!! ////////////////////////////////////////////////////////////////////// #pragma once #ifndef LASP_PYARRAY_H #define LASP_PYARRAY_H #define TRACERPLUS (-10) #include #ifdef LASP_DOUBLE_PRECISION #define LASP_NUMPY_FLOAT_TYPE NPY_FLOAT64 #define LASP_NUMPY_COMPLEX_TYPE NPY_COMPLEX128 #else #define LASP_NUMPY_FLOAT_TYPE NPY_FLOAT32 #endif #ifdef MS_WIN64 /** * Function passed to Python to use for cleanup of * foreignly obtained data. **/ static inline void capsule_cleanup(void *capsule) { void *memory = PyCapsule_GetPointer(capsule, NULL); free(memory); } #endif static inline PyObject *data_to_ndarray(void *data, int n_rows, int n_cols, int typenum, bool transfer_ownership, bool F_contiguous) { /* fprintf(stderr, "Enter data_to_ndarray\n"); */ assert(data); import_array(); npy_intp dims[2] = {n_rows, n_cols}; assert(n_rows > 0); assert(n_cols > 0); PyArrayObject *arr = (PyArrayObject *)PyArray_SimpleNewFromData(2, dims, typenum, data); if (!arr) { return NULL; } if (F_contiguous) { PyArray_ENABLEFLAGS(arr, NPY_ARRAY_F_CONTIGUOUS); } if (transfer_ownership == true) { #ifdef MS_WIN64 // The default destructor of Python cannot free the data, as it is allocated // with malloc. Therefore, with this code, we tell Numpy/Python to use // the capsule_cleanup constructor. See: // https://stackoverflow.com/questions/54269956/crash-of-jupyter-due-to-the-use-of-pyarray-enableflags/54278170#54278170 // Note that in general it was disadvised to build all C code with MinGW on // Windows. We do it anyway, see if we find any problems on the way. void *capsule = PyCapsule_New(mat->_data, NULL, capsule_cleanup); PyArray_SetBaseObject(arr, capsule); #endif /* fprintf(stderr, "============Ownership transfer================\n"); */ PyArray_ENABLEFLAGS(arr, NPY_OWNDATA); } /* fprintf(stderr, "Exit data_to_ndarray\n"); */ return (PyObject *) arr; } #endif // LASP_PYARRAY_H //////////////////////////////////////////////////////////////////////