为什么numpy.may_share_memory存在?
给出确切结果的挑战是什么?
被numpy.may_share_memory弃用的方法?
numpy.may_share_memory可能会给出误报,但不会给出假阴性.
没有人numpy.shares_memory给出假阳性而没有假阴性吗?
我使用numpy版本1.11.2.
看到:
And*_*eak 10
添加了一个新函数
np.shares_memory,可以准确检查两个数组是否有内存重叠.np.may_share_memory现在也可以选择花更多的精力来减少误报.
从语义上讲,这表明较旧的may_share_memory测试旨在得到一个宽松的猜测是否在阵列之间共享内存.如果肯定不是,那么可以相应地进行.如果有阳性检测(可能是假阳性),则必须小心.shares_memory另一方面,新功能允许精确检查.这需要更多的计算时间,但从长远来看可能是有益的,因为没有误报可以使用更多可能的优化.更宽松的检查may_share_memory可能只保证不会返回假阴性.
在文档方面may_share_memory和shares_memory,都有一个关键字参数,告诉numpy的用户进行检查严格程度要.
may_share_memory:
max_work : int, optional
Effort to spend on solving the overlap problem. See shares_memory for details. Default for may_share_memory is to do a bounds check.
Run Code Online (Sandbox Code Playgroud)
shares_memory:
max_work : int, optional
Effort to spend on solving the overlap problem (maximum number of candidate solutions to consider). The following special values are recognized:
max_work=MAY_SHARE_EXACT (default)
The problem is solved exactly. In this case, the function returns True only if there is an element shared between the arrays.
max_work=MAY_SHARE_BOUNDS
Only the memory bounds of a and b are checked.
Run Code Online (Sandbox Code Playgroud)
从文档来看,这表明这两个函数可能会调用相同的底层机制,但may_share_memory使用不太严格的默认设置进行检查.
让我们来看看实现:
static PyObject *
array_shares_memory(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kwds)
{
return array_shares_memory_impl(args, kwds, NPY_MAY_SHARE_EXACT, 1);
}
static PyObject *
array_may_share_memory(PyObject *NPY_UNUSED(ignored), PyObject *args, PyObject *kwds)
{
return array_shares_memory_impl(args, kwds, NPY_MAY_SHARE_BOUNDS, 0);
}
Run Code Online (Sandbox Code Playgroud)
使用签名调用相同的底层函数
static PyObject *
array_shares_memory_impl(PyObject *args, PyObject *kwds, Py_ssize_t default_max_work,
int raise_exceptions)
{}
Run Code Online (Sandbox Code Playgroud)
如果不深入研究源代码,在我看来这shares_memory是一个改进may_share_memory,它可以使用适当的关键字参数进行与后者相同的松散检查.较旧的功能可用于方便和向后兼容.
免责声明:这是我第一次看到源代码的这一部分,而我没有进一步调查array_shares_memory_impl,所以我的印象可能完全错误.
至于两个方法之间差异的具体示例(使用默认参数调用):在上面的链接中解释了may_share_memory它只检查数组绑定索引.如果它们是不相交的两个数组,然后有没有机会,他们可以共享内存.但如果它们不是不相交的,那么阵列仍然是独立的!
简单示例:通过切片对连续的内存块进行不相交的分区:
>>> import numpy as np
>>> v = np.arange(6)
>>> x = v[::2]
>>> y = v[1::2]
>>> np.may_share_memory(x,y)
True
>>> np.shares_memory(x,y)
False
>>> np.may_share_memory(x,y,max_work=np.MAY_SHARE_EXACT)
False
Run Code Online (Sandbox Code Playgroud)
如您所见,x并且y是同一阵列的两个不相交的切片.因此,它们的数据范围在很大程度上重叠(它们几乎相同,在内存中保存一个整数).但是,它们的元素实际上都不相同:一个包含偶数,另一个包含原始连续块的奇数元素.因此,may_share_memory正确断言数组可能共享内存,但在更严格的检查中,事实证明它们没有.
至于精确计算重叠的额外难度,可以将工作追溯到被调用的工作人员solve_may_share_memory,其中还包含许多有关正在发生的事情的有用评论.简而言之,就是这样
a quick check and return如果边界不重叠,否则MEM_OVERLAP_TOO_HARD,如果我们要求宽松检查(即may_share_memory使用默认参数),这是主叫方的处理是"我们不知道,所以返回True"因此,上面第3点的工作是需要另外完成的工作shares_memory(或者通常是严格的检查案例).