将2D Cython指针返回到Python数组

斯特凡诺

我目前正在从Cython向C传递以下指针:

    #convert the input Python 2D array to a memory view
    cdef double[:,:] a_cython= np.asarray(a,order="C")
    #define a pointer of a pointer with dimensions of a
    cdef double** point_to_a = <double **>malloc(N * sizeof(double*))
    #initialize the pointer
    if not point_to_a: raise MemoryError
    #try:
    for i in range(N):
        point_to_a[i] = &a_cython[i, 0]

    #pass this double pointer to a C function
    logistic_sigmoid(&point_to_a[0], N,M)

其中a是一个numpy数组,其尺寸为N x Mpoint_to_a是指向Cython memoryview的指针的Cython指针a_cython由于a来自Python的输入是二维数组,因此我认为这是将信息直接传递给C的最佳方法。通道运行顺利且计算正确。但是,我现在正尝试重新转换回point_to_a一个numpy数组,但是我有点挣扎。

我正在考虑各种解决方案。我想研究在整个过程中是否可以保留N维数组,因此我在Cython中尝试了这种方法:

    #define a integer array for dimensions
    cdef np.npy_intp dims[2]
    dims[0]=  N
    dims[1] = M
    #create a new memory view and PyArray_SimpleNewFromData to deal with the pointer
    cdef np.ndarray[double, ndim=2] new_a =  np.PyArray_SimpleNewFromData(2, &dims[0], np.NPY_DOUBLE, point_to_a)

但是,当我转换new_a为np.array时,因为array = np.asarray(new_a)我只有一个0的数组。你有什么想法?

非常感谢

ad

一旦使用int**(或类似方法),数据就处于所谓的间接内存布局中。Cython的类型化内存视图支持间接内存布局(例如,请参见Cython:了解具有indirect_contignuous内存布局的类型化内存视图),但是实现此接口的类并不多。

Numpy的ndarray不实现间接内存布局-它们仅支持直接内存布局(例如,type的指针,int*而不是int**),因此将int**num传递给numpy数组将无济于事。

好处是,因为您与共享内存a_cython,所以这些值已就地更新。您可以通过返回base键入的内存视图-object来获取基础的numpy数组,即

return a_cython.base # returns 2d-numpy array.

根本不需要复制内存!


但是内存管理存在一些问题(例如,您需要free point_to_a)。

在您的情况下,这可能是一个矫kill过正,但是我借此机会无耻地插入了我的一个库indirect_buffer:因为间接内存布局缓冲区的替代品很少,而且不时需要一个,所以我创建了一个以避免编写始终相同的代码。

使用indirect_buffer您的函数可能如下所示:

%%cython
#just an example for a c-function
cdef extern from *:
    """
    void fillit(int** ptr, int N, int M){
       int cnt=0;
       for(int i=0;i<N;i++){
          for(int j=0;j<M;j++){
            ptr[i][j]=cnt++;
          }
       }
    }
    """
    void fillit(int** ptr, int N, int M)

from indirect_buffer.buffer_impl cimport IndirectMemory2D
def py_fillit(a):
    #create collection, it is a view of a
    indirect_view=IndirectMemory2D.cy_view_from_rows(a, readonly=False)
    fillit(<int**>indirect_view.ptr, indirect_view.shape[0], indirect_view.shape[1])
    # values are updated directly in a

现在可以使用,例如:

import numpy as np
a=np.zeros((3,4), dtype=np.int32)
py_fillit(a)
print(a)
# prints as expected:
#  array([[ 0,  1,  2,  3],
#         [ 4,  5,  6,  7],
#         [ 8,  9, 10, 11]])

上面的版本做了很多正确的事情:内存管理,缓冲区锁定等等。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

将两个指针返回到动态数组

来自分类Dev

将数组地址从函数返回到指针(C ++)

来自分类Dev

将数组地址从函数返回到指针(C ++)

来自分类Dev

将2D数组的2D数组转换为单个2D数组

来自分类Dev

C ++将动态指针传递给2D数组

来自分类Dev

尝试将2D数组作为指针访问

来自分类Dev

将数组插入2D数组

来自分类Dev

将数组插入2D数组

来自分类Dev

将2D数组左移

来自分类Dev

如何将2D数组设置为2D返回

来自分类Dev

将2D数组传输到文件中并返回

来自分类Dev

Python:将2D数组插入MySQL表

来自分类Dev

将图像作为2D数组导入python

来自分类Dev

Python:将元组转换为2D数组

来自分类Dev

Python:将2D数组插入MySQL表

来自分类Dev

将python中的2D数组与条件进行比较

来自分类Dev

Python:将 2D numpy 数组变成字典

来自分类Dev

使用ctypes将malloc的数组从C返回到Python

来自分类Dev

Python:将值读入空数组,然后返回到文件

来自分类Dev

将 2d 数组索引为 1d

来自分类Dev

将2d数组指针参数分配给本地数组指针变量

来自分类Dev

使用指针时将2D数组用作多个1D数组

来自分类Dev

使用指针时将2D数组用作多个1D数组

来自分类Dev

2D数组(指向指针的指针)

来自分类Dev

Java | 将2D int数组转换为2D char数组以进行println

来自分类Dev

将2d numpy数组的行组合合并为2d数组

来自分类Dev

将2d数组转换为其他类型的2d数组。int [,] => ushort [,]

来自分类Dev

将指针从库返回到应用

来自分类Dev

如何将2d数组复制到临时2d数组中并返回它?