Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/335.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Cython:理解带有间接相邻内存布局的类型化内存视图_Python_Cython_Typed Memory Views - Fatal编程技术网

Python Cython:理解带有间接相邻内存布局的类型化内存视图

Python Cython:理解带有间接相邻内存布局的类型化内存视图,python,cython,typed-memory-views,Python,Cython,Typed Memory Views,我想了解更多关于Cython的精彩和内存布局indirect\u continuous 根据间接法,当“指针列表是连续的”时使用 还有一个示例用法: 如果我错了,请纠正我,但是我假设“连续的int”列表的指针“连续列表”的意思是类似于由下面的C++虚伪代码创建的数组: //我们要创建一个“指向连续整数列表的连续指针列表” 整数**数组; //分配行指针 //这是与第一个维度相关的“连续指针列表”: 数组=新整数*[行计数] //分配一些行,每行都是“连续的整数列表” 数组[0]=新整数[COL

我想了解更多关于Cython的精彩和内存布局
indirect\u continuous

根据
间接法,当“指针列表是连续的”时使用

还有一个示例用法:

如果我错了,请纠正我,但是我假设“连续的int”列表的指针“连续列表”的意思是类似于由下面的C++虚伪代码创建的数组:

//我们要创建一个“指向连续整数列表的连续指针列表”
整数**数组;
//分配行指针
//这是与第一个维度相关的“连续指针列表”:
数组=新整数*[行计数]
//分配一些行,每行都是“连续的整数列表”
数组[0]=新整数[COL_COUNT]{1,2,3}
因此,如果我理解正确,那么在我的Cython代码中,应该可以从
int**
中获得如下的memoryview:

cdef int**list_of_pointers=get_pointers()
cdef int[::view.indirect_continuous,::1]view=指针列表
但我得到编译错误:

cdef int[::view.indirect_contiguous, ::1] view = <int[:ROW_COUNT:view.indirect_contiguous,:COL_COUNT:1]> list_of_pointers
                                                                                                        ^                                                                                                                              
------------------------------------------------------------

memview_test.pyx:76:116: Pointer base type does not match cython.array base type
cdef int[::view.indirect_continuous,::1]view=指针列表
^                                                                                                                              
------------------------------------------------------------
memview_test.pyx:76:116:指针基类型与cython.array基类型不匹配
我做错了什么?
我是否遗漏了任何类型转换,或者我是否误解了间接连续的概念?

让我们澄清一下:类型化内存视图只能用于实现的对象

原始C指针显然没有实现缓冲区协议。但您可能会问,为什么下面的快速脏代码会起作用:

%%cython    
from libc.stdlib cimport calloc
def f():
    cdef int* v=<int *>calloc(4, sizeof(int))
    cdef int[:] b = <int[:4]>v
    return b[0] # leaks memory, so what?
在您的情况下,
跨步
偏移
将是

  • strips=[sizeof(int*),sizeof(int)]
    (即在普通
    x86\u 64
    机器上的
    [8,4]
  • 偏移量=[0,-1]
    ,即只有第一个维度是间接的
获取元素
[x,y]
的地址将按如下方式进行:

  • A
    行中,
    指针
    设置为
    buf
    ,假设
    buf
  • 第一维度:
    • 在第
      B
      行中,
      指针
      变为
      BUF+x*8
      ,并指向指向第x行的指针位置
    • 因为
      suboffset[0]>=0
      ,我们在
      C
      行中取消对指针的引用,因此它显示了地址
      行X
      ——第X行的开始
  • 第二维度:
    • 在第
      B行
      中,我们使用
      步长
      获得
      y
      元素的地址,即
      指针=行X+4*y

    • 第二维度是直接的(由
      suboffset[1]表示),这可能不可能仅通过强制转换实现-例如,请参见似乎手动构造缓冲区接口的示例。很好,非常感谢您的详细解释。我将深入了解缓冲区协议的详细信息
      
      %%cython    
      from libc.stdlib cimport calloc
      def f():
          cdef int* v=<int *>calloc(4, sizeof(int))
          cdef int[:] b = <int[:4]>v
          return b[0] # leaks memory, so what?
      
      void *get_item_pointer(int ndim, void *buf, Py_ssize_t *strides,
                             Py_ssize_t *suboffsets, Py_ssize_t *indices) {
          char *pointer = (char*)buf;    // A
          int i;
          for (i = 0; i < ndim; i++) {
              pointer += strides[i] * indices[i]; // B
              if (suboffsets[i] >=0 ) {
                  pointer = *((char**)pointer) + suboffsets[i];  // C
              }
          }
          return (void*)pointer;  // D
      }