lasp/lasp/c/lasp_pyarray.h

77 lines
2.4 KiB
C

// 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 <numpy/ndarrayobject.h>
#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
//////////////////////////////////////////////////////////////////////