Я пытаюсь преобразовать C double * в массив numpy на Cython, но пока не получилось.
Я нашел эти полезные ссылки:
Заставить NumPy ndarray стать владельцем памяти в Cython
https://github.com/numpy/numpy/issues/8253
Но каждый раз, когда я использую следующий файл .pyx с Cython, это приводит к краху Jupyter (мертвое ядро):
.c файл:
#include<stdlib.h>
#include "test.h"
double* test1(int n) {
double* A=(double*)calloc(n,sizeof(double));
int i;
for (i=0;i<n;i++) {
A[i]=i+0.5; }
return(A); }
Я также пытаюсь использовать malloc с тем же результатом.
.pyx файл:
cimport c_test
import numpy as np
cimport numpy as np
np.import_array()
ctypedef np.float64_t DTYPE_t
cdef extern from "numpy/arrayobject.h":
void PyArray_ENABLEFLAGS(np.ndarray arr, int flags)
cdef data_to_numpy_array_with_spec(void * ptr, np.npy_intp N, int t):
cdef np.ndarray[DTYPE_t, ndim=1] arr = np.PyArray_SimpleNewFromData(1, &N, t, ptr)
PyArray_ENABLEFLAGS(arr, np.NPY_OWNDATA)
return arr
def test(n):
cdef double* t1
t=data_to_numpy_array_with_spec(c_test.test1(n),n,np.NPY_FLOAT64)
return(t)
Функция c_fct.test1 возвращает C double * из n double, который я хочу преобразовать в пустой массив, которому принадлежат данные, чтобы избежать утечки памяти. Без строки PyArray_ENABLEFLAGS(t, np.NPY_ARRAY_OWNDATA)
все работает нормально, но память не освобождается при уничтожении массива numpy.
блокнот Jupyter:
import cy_test as ct
ct.test(1000)
c_test.pxd file:
cdef extern from "test.h":
double* test1(int n)
Мой файл setup.py выглядит так:
from setuptools import setup
from setuptools.extension import Extension
from Cython.Distutils import build_ext
from Cython.Build import cythonize
import numpy as np
ext_modules = cythonize([Extension("cy_test", ["cy_test.pyx","test.c"])])
setup(
name = 'Hello world app',
cmdclass = {'build_ext': build_ext},
ext_modules = ext_modules,
include_dirs=[np.get_include()]
)
Я думаю, что моя проблема может возникать по той же причине, что и в ссылке на github, но я не вижу, как ее решить (в моем случае указатель C уже существует, поэтому я думаю, что не могу использовать то же решение) .
Я работаю на Windows 10 с Anaconda 64bit, вот подробности версии:
3.7.1 (по умолчанию, 10 декабря 2018 г., 22:54:23) [MSC v.1915 64 бит (AMD64)]