c malloc数组指针在cython中返回

W9D*_*DKI 7 c python arrays numpy cython

如何有效地将cython中的malloc数组指针(或numpy数组指针)返回到python3.

只要我不返回数组指针,cython代码就可以正常工作

我想要:

def double complex* randn_zig(int n):
  ...
  r = malloc(n*n*sizeof(double complex))
  ...
  return r
Run Code Online (Sandbox Code Playgroud)

c11(gcc 11)等价物是:

double complex* randn_zig(int n){

    r = malloc(n*n*sizeof(double complex))

    return r
}
Run Code Online (Sandbox Code Playgroud)

我试过了 <double complex*> randn_zig(int n):

randn_zig(<double complex*> r, int n):

到目前为止,其他排列没有成功.c和cython代码版本的速度是Numby/pylab randn版本的5倍,如果我能找到一种方法来返回指向大型10 ^ 6到10 ^ 10双复数组的指针.

Syr*_*jor 8

Numpy C API

你的问题与这篇文章类似.

您可以使用下面的函数将C指针传递给Numpy数组.当Numpy阵列被回收时,内存将自动释放.如果你想要指针释放指针,你不应该设置NPY_OWNDATA标志.

import numpy as np
cimport numpy as np

cdef pointer_to_numpy_array_complex128(void * ptr, np.npy_intp size):
    '''Convert c pointer to numpy array.
    The memory will be freed as soon as the ndarray is deallocated.
    '''
    cdef extern from "numpy/arrayobject.h":
        void PyArray_ENABLEFLAGS(np.ndarray arr, int flags)
    cdef np.ndarray[np.complex128, ndim=1] arr = \
            np.PyArray_SimpleNewFromData(1, &size, np.NPY_COMPLEX128, ptr)
    PyArray_ENABLEFLAGS(arr, np.NPY_OWNDATA)
    return arr
Run Code Online (Sandbox Code Playgroud)

以供参考:

Cython Typed Memoryviews

当然,你也可以使用cython memoryview.

import numpy as np
cimport numpy as np

cdef np.complex128_t[:,:] view = <np.complex128_t[:n,:n]> c_pointer
numpy_arr = np.asarray(view)
Run Code Online (Sandbox Code Playgroud)

上面的代码将C指针传递给numpy数组.然而,这不会自动释放内存,你必须自己释放内存,否则会导致内存泄漏!


Sau*_*tro 0

我认为最好的方法是通过 NumPy 将 Python 创建的现有数组的指针传递给 Cython,否则似乎您必须将创建的数组的内容复制到malloc另一个数组,如这个玩具示例所示:

import numpy as np
cimport numpy as np

from libc.stdlib cimport malloc, free

def main():
  cdef int i, n=40
  cdef double complex *r
  cdef np.ndarray[np.complex128_t, ndim=1] a
  a = np.zeros(n*n, dtype=np.complex128)
  r = <double complex *>malloc(n*n*sizeof(double complex))
  for i in range(n*n):
      r[i] = 1.
  for i in range(n*n):
      a[i] = r[i]
  free(r)
  return a
Run Code Online (Sandbox Code Playgroud)