在PyTorch中,是什么使张量具有不连续的内存?

时间:2019-01-08 15:54:33

标签: pytorch

根据this SOthis PyTorch discussion,PyTorch的{​​{1}}函数仅适用于连续内存,而view无效。在第二个链接中,作者甚至声称:

  

[{reshape]将在不连续的张量上引发错误。

但是张量何时具有不连续的内存?

2 个答案:

答案 0 :(得分:2)

This是一个很好的答案,它在NumPy和PyTorch的上下文中解释了该主题,本质上是相同的。 PyTorch的文档通常不会提到函数输出是否(不)连续,这可以根据操作的类型(具有一定的经验和对实现的理解)来猜测。根据经验,大多数操作在构造新张量时都保持连续性。如果操作就地在阵列上工作并更改其跨度,则可能会看到不连续的输出。下面有几个例子

import torch

t = torch.randn(10, 10)

def check(ten):
    print(ten.is_contiguous())

check(t) # True

# flip sets the stride to negative, but element j is still adjacent to
# element i, so it is contiguous
check(torch.flip(t, (0,))) # True

# if we take every 2nd element, adjacent elements in the resulting array
# are not adjacent in the input array
check(t[::2]) # False

# if we transpose, we lose contiguity, as in case of NumPy
check(t.transpose(0, 1)) # False

# if we transpose twice, we first lose and then regain contiguity
check(t.transpose(0, 1).transpose(0, 1)) # True

通常,如果您具有不连续的张量t,则可以通过调用t = t.contiguous()使它成为连续的。如果t是连续的,则对t.contiguous()的调用本质上是无操作的,因此您可以这样做,而不会冒很大的性能损失的风险。

答案 1 :(得分:1)

我认为您的标题contiguous memory有点误导。据我了解,PyTorch中的contiguous表示张量中的相邻元素实际上在内存中是否彼此相邻。让我们举一个简单的例子:

x = torch.tensor([[1, 2, 3], [4, 5, 6]]) # x is contiguous
y = torch.transpose(0, 1) # y is non-contiguous

根据documentation of tranpose()

  

返回张量,它是输入的转置版本。给定的尺寸dim0和dim1被交换。

     

生成的张量与输入张量共享其基础存储,因此更改其中一个的内容将更改另一个的内容。

使上面示例中的xy 共享相同的内存空间。但是,如果用is_contiguous()检查它们的连续性,则会发现x是连续的,而y不是。现在,您会发现contiguity没有引用contiguous memory

由于x是连续的,因此x[0][0]x[0][1]在内存中彼此相邻。但是y[0][0]y[0][1]不是。这就是contiguous的意思。