C++ 对 Python 的扩展——安全的内存访问和内存布局
Posted
技术标签:
【中文标题】C++ 对 Python 的扩展——安全的内存访问和内存布局【英文标题】:C++ extension to Python - safe memory access, and memory layout 【发布时间】:2020-01-07 09:24:56 【问题描述】:我正在使用作用于 Numpy 数组(非常大)的 c++ 函数来扩展 python 代码。 由于遗留问题,我目前同时拥有 PyBind 和 Python API 函数,都适用于 Python 3.6 及更高版本。 一旦我通过 ptr 访问内存,我很想确保内存布局与此 ptr 下的 c++ 数组完全对应。 我发现在这两种情况下,转置数组在 ptr 中的内容完全相同。我还发现通过 Python API 发送的子数组在 c++ 中给出的 ptr 与完整数组完全相同。在开发和测试的过程中,我还观察到了更多我认为奇怪的例子,但不能再重现它们了。 到目前为止,我在互联网上找不到任何食谱。我的解决方案是在 Python 中复制所有输入数组,例如 f(a.copy(), b.copy())
它似乎运作良好。 这是最佳/充分的解决方案吗? 我对如何生成输入数组没有任何限制。转置、子阵列、重塑,任意组合。
【问题讨论】:
你检查过使用 Pybind 的缓冲协议吗? pybind11.readthedocs.io/en/stable/advanced/pycpp/numpy.html 内存布局正好对应c++数组是什么意思?你想避免什么情况? PyBind11 代码正在使用 NDArray使用 pybind11,您可以使用 py::array::c_style
标志,如 Matt Eding 的链接中所述。 Numpy 的 C API 通过 NPY_ARRAY_C_CONTIGUOUS
标志提供了几乎相同的功能。无论哪种情况,如果需要满足布局要求,数组将被隐式复制;如果您更愿意拒绝此类参数(以避免沉默的低效率),您必须自己检查数组的 flags
。
【讨论】:
这太棒了!谢谢,正是我想要的。我被默认的 np 数组在 python 中具有 c 传染性这一事实蒙蔽了双眼。 也许是一个相关的问题?我相信我没有错过链接页面;)这一切原则上是否意味着通过修改输入的返回变量将值从 c++ 返回到 python 是危险的?如果我不能在同一个地方累积类似MC的块的结果并且需要在每个块上分配...... @Vladimir:许多 Python 类型应该是不可变的;对于ndarray
,可写性只是另一个可能强制复制的标志。以上是关于C++ 对 Python 的扩展——安全的内存访问和内存布局的主要内容,如果未能解决你的问题,请参考以下文章