为什么需要Tensor.contiguous()
Tensor.contiguous()作用
Returns a contiguous in memory tensor containing the same data as self tensor. If self tensor is already in the specified memory format, this function returns the self tensor.
作用在官方文档里,描述的看似清晰但又模棱两可。例如x是一个Tensor,
x.contiguous()
的作用就是返回一个在内存中连续的Tensor,其data与Tensor
x
一致。如果源x本来就在内存中连续的话,那就返回其本身。
为什么要有Tensor.contiguous()?
Reference: StackOverflow–Why do we need contiguous?
在PyTorch中,有些对Tensor的操作并不实际改变tensor的内容,而只是改变如何根据索引检索到tensor的byte location的方式。
这些操作有:
,
narrow()
,
view()
,
expand()
,
transpose()
permute()
例如: 当我们调用
transpose()
时,PyTorch并不会生成一个具有新的layout(大概可以翻译为布局)的新tensor。该操作仅仅改变了tensor中的
meta information
(元信息),所以offset和stride可以正确作用于新的shape。但是转置后的tensor和源tensor在事实上是共享同一块内存空间的。
>>> x = torch.randn(3,2)
>>> print(x)
tensor([[ 0.9181, 1.4266],
[-0.1432, -0.7514],
[ 0.9809, -0.5079]])
>>> print(x[0,0])
tensor(0.9181)
>>> y = x.transpose(1,0)
>>> print(y)
tensor([[ 0.9181, -0.1432, 0.9809],
[ 1.4266, -0.7514, -0.5079]])
>>> print(y[0,0])
tensor(0.9181)
这就是
contiguous
的来源。上述例子中
x
是连续的,但是
y
不是,因为
y
的内存布局与从头开始新建一个与
y
shape相同的tensor的内存布局不同。
需要注意的是,contiguous这个单词有点被误解了,它并不是指tensor的内容在内存块上不连续。字节仍然是分配在同一个内存块上的,问题在于其元素之间的顺序order。
而当我们调用
contiguous()
时,实际上它是会复制一个张量,同时元素之间在内存上的顺序与从零开始新建的相同shape的张量一致。