问题标签 [typed-memory-views]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票
1 回答
91 浏览

cython - 我可以在 Cython 中“fwrite”一个内存视图吗?

fwrite是否可以使用 ac函数将 numpy 数组写入磁盘?从 Cython 内存视图文档中,我了解到“它们可以处理 C 数组”,但我没有看到这样的明确示例。

这是我正在尝试的:

但我得到以下编译错误:

这可能吗?

0 投票
0 回答
108 浏览

python - 接口类型的内存视图与 python slice 对象

我想将一个__getitem__方法从 python 转换为接受来自 cython 的数组。在这个特定的应用程序中,我应该允许在第二个索引中切片。对于 python,我可以写:

一切都会很好。numbers但是,当我将变量声明为类型cdef public double[:,:] numbers并尝试使用 -object 调用-method__getitem__时,解释器不喜欢它。每当发生这种情况时,它都会抱怨TypeError: 'slice' object cannot be mapped as an integer。那么我的问题是:如果它是 a而不是整数,我将如何修改该行以便正确理解?yslicereturn self.bounds[x][y]yslice

0 投票
0 回答
31 浏览

python-3.x - 如何有效地构建内存视图数组

我想构建一个具有可变数量的内存视图的 cython 类。我希望能够在不复制大量数据的情况下对内存视图进行洗牌并重新排序。我想保留在编译类型时确定数组的基本类型(双精度)的好处。

到目前为止,我还没有设法有效地做到这一点。

这是基线类定义:

当我按如下方式运行速度基准测试时:

我每次运行 550 ns fill

现在我想在我的班级中有几个内存视图,所以我尝试了:

Container2与 相同Container,只是它拥有可变数量的类型化内存视图,而不仅仅是一个。

当我再次使用运行速度基准测试时

我现在每次运行得到 9.5 µs,因此与上面的比较,这意味着在一个大小为 1000 的阵列上每次运行需要 950 ns。

所以处理时间增加了一倍。

当然,必须有更好、更有效的方法。

0 投票
0 回答
135 浏览

python - 我的 Python/Cython 迭代基准测试是否具有代表性?

我想遍历 Python 程序中的大型数据结构并为每个元素执行一项任务。为简单起见,假设元素是整数,而任务只是一个增量。最后,最后一个递增的元素作为(虚拟)结果返回。为了寻找最好的结构/方法,我比较了这些结构在纯 Python 和 Cython 中的时间(我在其他地方找不到它们的直接比较):

  • Python列表
  • NumPy 数组/类型化内存视图
  • 具有底层 C++ 向量的 Cython 扩展类型

我计时的迭代是:

  • 列表迭代中的 Python foreach (it_list)
  • 具有显式元素访问的 Cython 列表迭代 (cit_list)
  • 数组迭代中的 Python foreach (it_nparray)
  • Python NumPy 向量化操作 (vec_nparray)
  • 具有显式元素访问的 Cython 内存视图迭代 (cit_memview)
  • 底层向量迭代中的 Python foreach (it_pyvector)
  • 通过 __iter__ (it_pyvector_iterator) 在底层向量迭代中的 Python foreach
  • 具有显式元素访问的 Cython 向量迭代 (cit_pyvector)
  • 通过 vector.iterator (cit_pyvector_iterator) 进行 Cython 向量迭代

我由此得出结论(时间如下):

  • NumPy 数组上的普通 Python 迭代非常慢(比 Python 列表迭代慢大约 10 倍)-> 不是一个好主意
  • 包装的 C++ 向量上的 Python 迭代也很慢(比 Python 列表迭代慢大约 1.5 倍)-> 不是一个好主意
  • Cython 对包装的 C++ 向量的迭代是最快的选择,大约等于 C 连续内存视图
  • 使用显式元素访问对向量的迭代比使用迭代器稍快 -> 为什么要使用迭代器?
  • 内存视图方法具有比扩展类型方法更大的开销

我现在的问题是:我的数字可靠吗(我做错了什么或错过了什么)?这是否符合您对现实世界示例的经验?我还能做些什么来改进迭代吗?在我使用的代码和时间下方。顺便说一句,我在 Jupyter 笔记本中使用它。非常感谢您的建议和评论!

相对时间(最小值 1.000),对于不同的数据结构大小 n:

赛通代码:

Python代码:

对于基准:

0 投票
1 回答
116 浏览

cython - 使用 nogil 对 memoryviews 进行引用计数

我不太明白如何在大型/更长的 nogil 部分中使用 memoryviews 完成引用计数。让我们假设基本上我所有的代码都是 nogil,除了在深处创建一个 numpy-array-to-memoryview 。内存视图被返回并向上使用。

一个相当简单的例子是

我假设当 someFun() 返回 memoryview 时,numpy 数组的引用计数仍应为 1。Cython 之后如何处理引用计数?我的意思是即使内存视图/数组被取消引用,也不允许更改引用计数,对吗?如果上面有几个带有 nogil 代码的层,它怎么知道取消对 memoryview 的引用,并且可能与 someFun() 不同,memoryview 没有向上返回?

编辑:所以我想出了一个相当粗略的方法来做更多的测试。我的代码现在看起来像这样。

对我来说有趣的部分是在第一站mv仍然分配了数组/内存视图,但是当我取消引用它直到第二站才被释放。我只检查了内存使用情况htop(这就是为什么选择如此大的数组),可能有更好的方法。显然,我想要发生的自由/引用计数行为,但是当它没有 GIL 时它会这样做很奇怪。也许内存视图不完全是nogil?

有人可以解释这是否是可靠的行为吗?

0 投票
1 回答
436 浏览

null - 如何在 cython 中检查 Null 中的内存视图是否存在

我想检查内存视图是否用无初始化。我有这样的功能:

编译时出现此错误:

将 None 分配给内存视图是否存在问题?如果不是这种情况,我该怎么做才能检测到 NULL 值?

谢谢!

0 投票
0 回答
101 浏览

python - 在 Cython 中将 int 指针(数组)转换为 int typed-memoryview 会在运行时引发 ValueError

问题描述

我有这个功能:

当我将它放在一个名为 test.pyx 的单独文件上时,编译它并从 CPython 的解释器中调用它,它工作正常。我这样称呼它:

当我将此函数添加到现有库(在具有多个文件和依赖项的大项目中)时,问题就来了,它编译得很好,但是当我调用它时会抛出一个错误:

如您所见,它特别抱怨这一行:

两种情况下的函数完全一样,而且我传递了相同的N值,真的很奇怪。

有谁知道在哪种情况下可以简单地强制int *转换来int[:]抛出 ValueError?


语境

我正在尝试向 PyAV 库添加一些功能,因此我将该功能添加到此文件中:

https://github.com/PyAV-Org/PyAV/blob/main/av/video/frame.pyx

当我这样称呼它时它会抛出:

我在 MacOS 10.15.7 上,使用 Python 3.7.7 和 Cython 0.29.21 和 Clang 11.0.3 编译器。


更新 1

我已经检查了 Cython 为该test()函数生成的 C 代码,两种情况下都是相同的,这是为有问题的行生成的代码:

所以我开始用调用注释行,__PYX_ERR()发现引发 ValueError 的行是这样的:

这一行更新了__Pyx_memviewslice之前声明的 a:

这个函数很可能会设置错误:

__Pyx_PyObject_to_MemoryviewSlice_ds_int()

所以也许演员(PyObject *)__pyx_t_1做错了什么或者__pyx_t_1不是它所期望的。

但我真的不知道这一切是如何工作的,所以也许还有其他原因导致这种行为,比如一些编译器标志?

0 投票
1 回答
140 浏览

numpy - Cython Memoryview 中的阵列广播

我在 cython 中创建了一个类型化的内存视图,并想将它乘以一个标量:

函数foo()执行此任务但不是很方便/可读。

A *= pi但是,函数中的行bar()无法编译:Invalid operand types for '*' (double_t[:, :]; double).

有没有办法在 cython memoryview 上执行这样的广播操作?