标签: memoryview

如何为非连续的内存位置创建内存视图?

我在内存中有一个碎片结构,我想将它作为一个连续的内存视图来访问它.有没有一种简单的方法可以做到这一点,还是应该实现自己的解决方案?

例如,考虑由记录组成的文件格式.每条记录都有一个固定长度的标题,用于指定记录内容的长度.更高级别的逻辑结构可能分布在多个记录中.如果它可以将它自己的碎片内存位置视为一个简单的连续字节数组,那么它将使更高级别的结构更容易实现.

更新:

似乎python在内部支持这种"分段"缓冲区类型,至少基于文档的这一部分.但这只是C API.

UPDATE2:

据我所知,引用的C API - 称为旧式缓冲区 - 可以满足我的需求,但现在已经弃用,并且在较新版本的Python(3.X)中不可用.新的缓冲协议 - 在PEP 3118中指定- 提供了一种表示缓冲区的新方法.这个API在大多数用例中更有用(其中,表示缓冲区在内存中不连续的用例),但不支持这个特定的用例,其中一维数组可以完全自由地布局(多个不同)记忆中的大小块.

python memory memoryview

9
推荐指数
1
解决办法
1270
查看次数

Cython:对于类型化的内存视图,我应该使用np.float_t而不是double

关于cython中的内存视图,使用NumPy类型键入视图是否有任何优势,例如,如果我正在处理numpy浮点数组,np.float_t而不是简单地做double

我应该cdef以同样的方式输入,例如

ctypedef np.float64_t np_float_t
...

@cython.profile(False)
@cython.wraparound(False)
@cython.boundscheck(False)
cdef np_float_t mean_1d(np_float_t [:] v) nogil:
    cdef unsigned int n = v.shape[0]
    cdef np_float_t n_sum = 0.

    cdef Py_ssize_t i
    for i in range(n):
        n_sum += v[i]

    return n_sum / n
Run Code Online (Sandbox Code Playgroud)

python numpy typing cython memoryview

9
推荐指数
1
解决办法
3220
查看次数

Cython:在没有NumPy数组的情况下创建内存视图?

由于我发现内存视图方便快捷,我尝试避免在cython中创建NumPy数组并使用给定数组的视图.但是,有时无法避免,不能改变现有阵列而是创建新阵列.在上层函数中,这是不明显的,但在经常被称为子例程的情况下.考虑以下功能

#@cython.profile(False)
@cython.boundscheck(False)
@cython.wraparound(False)
@cython.nonecheck(False)
cdef double [:] vec_eq(double [:] v1, int [:] v2, int cond):
    ''' Function output corresponds to v1[v2 == cond]'''
    cdef unsigned int n = v1.shape[0]
    cdef unsigned int n_ = 0
    # Size of array to create
    cdef size_t i
    for i in range(n):
        if v2[i] == cond:
            n_ += 1
    # Create array for selection
    cdef double [:] s = np.empty(n_, dtype=np_float) # Slow line
    # Copy selection to new array
    n_ = 0 …
Run Code Online (Sandbox Code Playgroud)

python arrays numpy cython memoryview

9
推荐指数
1
解决办法
3355
查看次数

Cython:缓冲区类型不匹配,预期'int'但得到'long'

我无法将这个整数的内存视图传递给这个(相当简单的)函数.Python给了我这个错误:

ValueError: Buffer dtype mismatch, expected 'int' but got 'long'
Run Code Online (Sandbox Code Playgroud)

有人可以帮我理解发生了什么吗?搜索stackoverflow,似乎它与python如何解释类​​型以及C如何解释类​​型有关.

%%cython
def myfunction(int [:] y):
    pass

# Python code
import numpy as np
y = np.array([0, 0, 1, 1])
myfunction(y)
Run Code Online (Sandbox Code Playgroud)

ValueError从上面产生.

编辑:这是我发现的其他一些事情.

为了澄清,如果我声明y以下方式,则此错误仍然存​​在:

y = np.array([0, 0, 1, 1], dtype='int')
y = np.array([0, 0, 1, 1], dtype=np.int)
y = np.array([0, 0, 1, 1], dtype=np.int64)
Run Code Online (Sandbox Code Playgroud)

然而,它的工作原理,如果我宣布y

y = np.array([0, 0, 1, 1], dtype=np.int32)
Run Code Online (Sandbox Code Playgroud)

有没有人想提出为什么会这样的建议?会np.int32在不同的电脑上投入工作吗?(我使用macbook pro retina,2013年.)

python numpy cython memoryview

9
推荐指数
1
解决办法
8289
查看次数

Cython:将单个元素分配给多维内存视图切片

每当我为多维内存视图的一个切片分配单个值时,Cython似乎都会使用错误的步幅,除非该切片沿第一个维度。我在下面给出一个完整的例子:

# bug.py
import numpy as np

def bug():
    #cdef int[:, ::1] a
    a = 2*np.ones((2, 2), dtype=np.intc)
    a[:, :1] = 1
    print(np.asarray(a))
Run Code Online (Sandbox Code Playgroud)

如果我们在Python中运行此代码(例如python3 -c 'import bug; bug.bug()'),我们将得到

[[1 2]
 [1 2]]
Run Code Online (Sandbox Code Playgroud)

按预期打印。现在,通过将文件重命名为bug.pyx,用Cython对其进行编译,并将以下文件保存在Makefile同一目录中,

# Makefile
python = python3
python_config = $(python)-config
CC = gcc
CFLAGS  = $(shell $(python_config) --cflags) -fPIC
CFLAGS += $(shell $(python_config) --includes)
python_libdir = $(shell $(python) -c "import sysconfig; \
    print(sysconfig.get_config_var('LIBDIR'));")
LDLIBS  = -L$(python_libdir) -Wl,-rpath=$(python_libdir)
LDLIBS += $(shell $(python_config) --libs)
LDFLAGS …
Run Code Online (Sandbox Code Playgroud)

python cython slice python-3.x memoryview

8
推荐指数
1
解决办法
244
查看次数

如何在cython中获取类型化内存视图的大小

是否有可能在cython中获得MemoryView的大小?理想情况下,我正在寻找像arr.shapenumpy 这样的东西.

python cython python-3.x memoryview

7
推荐指数
1
解决办法
1350
查看次数

如何在Cython中的新式缓冲区对象中包装C指针和长度?

我在Cython中编写了一个Python 2.7扩展模块. 如何创建一个实现新式缓冲区接口的Python对象,该接口包含C库提供给我的大块内存? 内存块只是一串字节,而不是结构或多维数组.我给了一个const void *指针和一个长度,以及一些指针保持有效的细节.

我无法复制内存 - 这会破坏我的应用程序的性能.

使用我可以简单使用的旧式缓冲区对象PyBuffer_FromMemory(),但我似乎无法找到一种类似的简单方法来生成新式缓冲区对象.

我是否必须创建自己的实现缓冲区接口的类?或者Cython提供了一种简单的方法吗?

我已经阅读了Cython文档中的Unicode和Passing StringsTyped Memoryviews页面,但文档不精确且不够完整,并且没有类似于我想要做的示例.

这是我尝试过的(test.pyx):

from libc.stdlib cimport malloc
from libc.string cimport memcpy

## pretend that this function is in some C library and that it does
## something interesting.  (this function is unrelated to the problem
## I'm experiencing -- this is just an example function that returns a
## chunk of memory that I want to wrap in …
Run Code Online (Sandbox Code Playgroud)

python cython python-c-extension python-2.7 memoryview

7
推荐指数
2
解决办法
2097
查看次数

在字节对象上获取指向python memoryview的指针

我有一条蟒蛇memoryview指向一个bytes对象,我想在 cython 中对其执行一些处理。

我的问题是:

  • 因为 bytes对象不可写,cython 不允许从中构造类型化(cython)内存视图
  • 我也不能使用指针,因为我无法获得指向 memoryview 开始的指针

例子:

在蟒蛇中:

array = memoryview(b'abcdef')[3:]
Run Code Online (Sandbox Code Playgroud)

在cython中:

  • cdef char * my_ptr = &array[0] 无法编译消息: Cannot take address of Python variable
  • cdef char[:] my_view = array 运行时失败并显示以下消息: BufferError: memoryview: underlying buffer is not writable

怎么解决这个问题?

python pointers cython memoryview typed-memory-views

7
推荐指数
2
解决办法
4515
查看次数

在 Python 中正确丢弃指向 mmap 内存的 ctypes 指针

我遇到的问题是,在创建指向 mmap-s 的指针后,我无法在 Python 中正确关闭 mmap-s。我的用例是打开文件(通常是与硬件一起工作的 UIO 设备,但普通文件也会出现此问题),对它们进行内存映射,然后将它们用作 ctypes 结构的缓冲区。通常是数据结构或数组。一个最小的例子如下所示:

import ctypes as ct
import mmap
import os

fileno = os.open('/tmp/testfile', os.O_RDWR | os.O_SYNC)
map = mmap.mmap(fileno, 32768, flags=mmap.MAP_SHARED)
memory = (ct.c_uint32 * 8192).from_buffer(map)

# Use the memory object to do things here

del memory
map.close()
os.close(fileno)
Run Code Online (Sandbox Code Playgroud)

那时一切都很好。

但是,有时我需要调用一些也需要访问该内存的 C 库函数,因此我必须传入指向它们的指针。我使用以下方法创建该指针:

ptr = ct.cast(memory, ct.c_void_p)
Run Code Online (Sandbox Code Playgroud)

除了一件事之外,所有这些都运作良好。一旦我创建了这样的指针,我就无法再关闭内存映射。举个稍微扩展一下的例子:

import ctypes as ct
import mmap
import os

fileno = os.open('/tmp/testfile', os.O_RDWR | os.O_SYNC)
map = mmap.mmap(fileno, 32768, flags=mmap.MAP_SHARED)
memory = (ct.c_uint32 * 8192).from_buffer(map) …
Run Code Online (Sandbox Code Playgroud)

python ctypes pointers mmap memoryview

7
推荐指数
1
解决办法
3271
查看次数

mpi4py中的共享内存

我使用MPImpi4py)脚本(在单个节点上),该脚本可用于非常大的对象。为了让所有进程都可以访问该对象,我通过分发了该对象comm.bcast()。这会将对象复制到所有进程,并占用大量内存,尤其是在复制过程中。因此,我想共享诸如指针之类的东西,而不是对象本身。我发现一些memoryview有用的功能有助于增强流程中对象的工作。同样,对象的实际内存地址也可以通过memoryview对象字符串表示形式进行访问,并且可以这样分配:

from mpi4py import MPI

comm = MPI.COMM_WORLD
rank = comm.Get_rank()

if rank:
    content_pointer = comm.bcast(root = 0)
    print(rank, content_pointer)
else:
    content = ''.join(['a' for i in range(100000000)]).encode()
    mv = memoryview(content)
    print(mv)
    comm.bcast(str(mv).split()[-1][: -1], root = 0)
Run Code Online (Sandbox Code Playgroud)

打印:

<memory at 0x7f362a405048>
1 0x7f362a405048
2 0x7f362a405048
...
Run Code Online (Sandbox Code Playgroud)

这就是为什么我认为必须有一种方法可以在另一个过程中重构对象。但是,我在文档中找不到有关如何执行此操作的线索。

简而言之,我的问题是:是否可以在中同一节点上的进程之间共享对象mpi4py

mpi shared-memory python-3.x memoryview mpi4py

6
推荐指数
2
解决办法
1928
查看次数