类型化的memoryview作为成员的结构定义 [英] Struct definition with typed memoryview as member

查看:67
本文介绍了类型化的memoryview作为成员的结构定义的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

当前,我正在尝试使用具有键入的memoryview的结构来工作。例如,

Currently I am trying to get a struct with a typed memoryview to work. E.g.

ctypedef struct node:
    unsigned int[:] inds

据我所知,如果inds不是内存视图,则它可以正常工作。但是,使用memoryview并使用

If inds is not a memoryview it works flawlessly as far as I can see. However, with a memoryview and using something like

def testFunction():
    cdef node testNode   
    testNode.inds = numpy.ones(3,dtype=numpy.uint32)

我遇到了细分错误。有什么明显的我在忽略吗?或者键入的内存视图在结构中不起作用?

I get a Segmentation fault. Is there anything obvious I am overlooking or do typed memoryviews not work in structs?

编辑:

因此(由于拉尔斯曼的问题),我稍微重写了这个示例,以期希望能稍微澄清一下问题:

So I rewrote the example a little bit (due to larsman's questions) to hopefully clarify the problem a little bit:

def testFunction():
    cdef node testNode
    cdef unsigned int[:] tempInds
    tempInds = numpy.ones(3,dtype=numpy.uintc)
    testNode.inds = tempInds

仅最后一行会产生段错误。我不知道如何更详细地检查问题。对我来说,目前看来结构无法处理键入的内存视图...但是希望我会丢失一些东西。

Only the last line produces a segfault. I don't know how to check the problem in more detail. For me it currently just looks like the structs can't handle typed memory views... But hopefully I am missing something.

我正在使用Cython 0.20(现在才更新) ,以前的0.19给出了相同的错误)。还将Numpy也更新为1.8.0。

I am using Cython 0.20 (just updated now, previously 0.19 gave the same error). Updated Numpy to 1.8.0 as well.

编辑2:

如果有类似问题的人将来会读到此书:到目前为止,我进行了很多搜索,无法正常工作。由于除内存视图以外的所有其他功能都在工作,我想这是(轻松)不可能的。
由于多维数组的切片方便,我打算使用内存视图,但是显然它们不适用于结构。现在,我将一个C指针保存在该结构中,如果需要切片,则将它们强制转换为内存视图...必须非常小心,才能正确访问数组,但就我而言,它似乎可以工作。如果从现在开始的两周内此线程中没有解决的答案,那么我可能正在请求Cython的功能。

If anyone with similar problems reads this in the future: I searched quite a lot by now and can't get it to work. As everything else is working except for memory views I guess it is not (easily) possible. I intended to use memory views due to the convenient slicing of multidimensional arrays, but apparently they don't work in structs. Now I am saving a C pointer in the struct and cast them to a memory view if I need slicing... One has to be very careful that the arrays are accessed correctly, but in my case it seems to work. If there are no resolving answers in this thread in a couple of weeks from now I am maybe doing a feature request for Cython.

推荐答案

问题来自未初始化的内存,因为Cython缺少原始cdefed结构的构造函数。当进行testNode.inds = tempInds分配时,Cython尝试释放尚未正确初始化的testNode.inds并取消引用随机指针。

The problem comes from uninitialized memory because of Cython lack of constructors for primitive cdefed structs. When testNode.inds = tempInds assignment is made Cython tries to release testNode.inds which was not even initialized properly and dereferences random pointer.

这确实是Cython中的错误(请文件!),(据我所知)目前尚无解决方案,但这是一个有效的丑陋黑客。

This is indeed bug in Cython (please file!) and there's currently no solution (to my knowledge), but here's an ugly hack that works.

from libc.string cimport memset

ctypedef struct node:
    int dummy_hack
    unsigned int[:] inds

def testFunction():
    cdef node testNode
    cdef unsigned int[:] tempInds
    tempInds = numpy.ones(3,dtype=numpy.uintc)
    # zero init memory to avoid deref garbage
    memset(&testNode.dummy_hack, 0, sizeof(void*)*4)
    testNode.inds = tempInds

仅供参考。 C ++中的实际内存视图对象如下所示(在Cython 21.2上):

FYI. Actual memory view object in C++ looks like this (on Cython 21.2):

MemoryView object is 
__Pyx_memviewslice struct typedef struct {
  struct __pyx_memoryview_obj *memview;
  char *data;
  Py_ssize_t shape[8];
  Py_ssize_t strides[8];
  Py_ssize_t suboffsets[8];
};

这篇关于类型化的memoryview作为成员的结构定义的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆