MegEngine Python 层 Tensor 行为#
从逻辑上来讲,各层之间的引用关系如下图所示:
三者均通过 refcount 进行资源管理,在引用归零时就释放资源,其中:
Python Tensor 只包含对 C++ Tensor 的引用;用户可通过
id(a)
是否一直来验证是否发生了变化C++ Tensor 包含:shape / stride / 对 Storage 的引用指针
Storage 包含:一段显存,即 ptr + length
在各种情况中,各层变量之间的指向关系变化如下表所示:
解释器变量行为 |
Python Tensor |
C++ Tensor |
Storage |
---|---|---|---|
|
不变 |
新建 |
新建,老的 ref - 1 |
|
新建,老的 ref -1 |
新建 |
新建,老的 ref - 1 |
|
新建 |
新建 |
新建并拷贝必须的部分 |
|
新建 |
新建 |
复用老的,即 ref + 1 |
|
新建 |
新建 |
复用老的 |
|
新建 |
新建 |
复用老的 |
|
不变 |
新建 |
新建并拷贝,老 ref - 1 |
|
不变 |
不变 |
不变 |
习题:基于以上的内容,就比较容易推导出以下的一些组合的行为了:
a = mge.tensor([1, 2]); b = a; b += 1; print(a)
a = mge.tensor([1, 2]); b = a; b = b + 1; print(a)
a = mge.tensor([1, 2]); b = a[0]; b += 1; print(a)
a = mge.tensor([1, 2]); b = a; a[0] += 1; print(b)
正确答案
[2, 3]
[1, 2]
[1, 2]
[2, 2]
如果你觉得这个行为很奇怪,你可能会希望了解 Python 可变/不可变变量的行为区别。