multidimensional-array – 将多维内存视图传递给c-function

以下线程中的答案对我没有帮助,因为我有多维数组
Passing memoryview to C function.

我有以下测试代码:

头文件:

//cm.h
double per(double **marr,int rows,int cols);

带C功能的文件

//cm.c
#include <stdio.h>
double per(double **marr,int rows,int cols){
    int i,j;
    for (i=0;i<rows;i++){
        for (j=0;j<cols;j++){
            //Just update the array
            marr[i][j] = (double)(i+1)*(j+1);
        }
    }
}

Cython文件:

#m.pyz
import numpy as np
cimport numpy as np
from cython.view cimport array as cvarray

cdef extern from 'cm.h':
    double per(double **marr,int rows,int cols);

def test(double[:,::1] x):
    cdef int rows = x.shape[0]
    cdef int cols = x.shape[1]
    per(x,rows,cols)
    for i in range(rows):
        for j in range(cols):
            print x[i,j]

和错误消息:

Error compiling Cython file:
------------------------------------------------------------
...
    double per(double **marr,int rows,int cols);

def test(double[:,::1] x):
    cdef int rows = x.shape[0]
    cdef int cols = x.shape[1]
    per(x,rows,cols)
        ^
------------------------------------------------------------

m.pyx:12:9: Cannot assign type 'double[:, ::1]' to 'double **'

我已经读过类型化的内存视图是在Cython中处理Python数组的最现代的方法,但是我不知道如何做到这一点.我在C中有一些数字配方,它们运行在动态制作的大型多维数组上.
我试图做一个完全错误的方式?

最佳答案 在内部,memoryview实际上存储为一维数组以及有关维度大小的一些信息.见
http://docs.cython.org/src/userguide/memoryviews.html#brief-recap-on-c-fortran-and-strided-memory-layouts

(稍微注意一点,你可以使用具有“间接”维度的内存视图,它将事物存储为指针的指针.这只有在它们已经具有像这样的内存分配的视图时才有意义 – 例如,如果你构建一个像C中那样的2D数组.你不会从(比方说)numpy对象那里得到那些,所以我会忽略这个细节).

您将C更改为

// pass a 1D array, and then calculate where we should be looking in it
// based on the stride
double per(double *marr,int rows,int cols, int row_stride, int col_stride){
    int i,j;
    for (i=0;i<rows;i++){
        for (j=0;j<cols;j++){
            //Just update the array
            marr[row_stride*i + col_stride*j] = (double)(i+1)(j+1);
        }
    }
}

然后,Cython代码需要进行更改以向其传递步幅(以字节存储,因此除以itemsize以获得C期望的“双数”的步幅)以及第一个元素的地址

// also update the cdef defintion for per...
per(&x[0,0],x.shape[0],x.shape[1],
     x.strides[0]/x.itemsize,x.strides[1]/x.itemsize)
点赞