文章目录
前言
本文旨在记录pytorch的API如何影响Tensor运算的‘内存共享性’和‘内存连续性’。’内存共享‘可以理解为浅拷贝;’内存连续’就是Tensor在信息区的内存空间上的连续性。 本文会结合代码介绍pytorch中的op是如何影响这两个性质的。
1、前置基础知识
1.1.Tensor的结构
因为涉及到Tensor的性质,因此,本节先简单回顾下Tensor的数据结构,Tensor包含信息区和存储区。信息区包含Tensor的一些维度信息(比如一个Tensor的shape=(2,3),变成(3,2),张量内容没变,变得只是我们看待这个张量的视角);存储区则是存储着数据。

深拷贝自然会同时拷贝两个区的内容;而维度变换操作往往仅影响信息区的内容,是为了减少张量计算中频繁的拷贝操作。
1.2.内存共享和内存连续API介绍
大家可先扫一眼下面的代码:这里简单介绍两个API,is_contiguous()能够判断一个Tensor的**信息区**上是否‘内存连续’;.data_ptr()能够返回张量在内存空间上的地址,可用于判断两个张量是否‘内存共享’。
# case 1: share contiguous And deepCopy?
x = torch.tensor([1,2,3], dtype=torch.float32)
y = x # shallow copy
print(x.is_contiguous(), y.is_contiguous()) # True, True
print(x.data_ptr() == y.data_ptr()) # True
# 若y发生额外的运算,此时pytorch会额外开辟新的内存,即转化成深拷贝!
y = y + 1 # x = [1,2,3], y = [2,3,4]
print(x.data_ptr() == y.data_ptr()) # False
我说下结论:说到底是python的语言特性。1)大多数赋值操作 = 全是浅拷贝,比如(y = x),因此,张量x和y内存连续且内存共享。也就是说:由于发生的是浅拷贝,即当我们对y做了某些op后,对应的x的值也会发生变化。2)但千万不能对y做运算(比如y = y +1),此时就由浅拷贝转化成了深拷贝,即python内部会自动开辟一块新的内存来存储y,即此时x和y各自内存连续但已经不共享内存了。(可能会forward的计算图产生影响)。
本文会在第2部分介绍一些pytorch中哪些op会对Tensor的内存连续性产生影响;在第3部分介绍pytorch中哪些op会对Tensor的内存共享性产生影响。
2、内存连续性
2.1.维度变换操作(transpose, permute)
# -------------- transpose op ------------------ #
# transpose op
x = torch.arange(0,6).view(2,3)
print(x.is_contiguous()) # True
y = x # shallow copy
y = y.transpose(0,1) # 张量的信息区发生变更,但存储区没发生变更,x和y共用一块存储区
# True: dont destropy ;False: transpose op destroy share contigouse
print(x.is_contiguous, y.is_contiguous())
print(x.data_ptr() == y

本文详细探讨了PyTorch中Tensor的内存管理机制,包括内存连续性和内存共享性。通过具体示例介绍了不同操作如transpose、view、cat等对Tensor内存属性的影响。

3200

被折叠的 条评论
为什么被折叠?



