Pytorch学习笔记——Contiguous vs non-contiguous tensor

本文深入探讨了PyTorch中张量的contiguous属性,解释了张量在内存中连续存储的重要性。通过示例展示了如何通过转置操作得到非连续张量,并说明了在非连续张量上执行某些操作(如view)时可能遇到的问题。文章指出,调用`.contiguous()`可能导致内存复制,以确保张量在内存中连续,这对于某些运算的效率至关重要。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

原文地址:https://discuss.pytorch.org/t/contigious-vs-non-contigious-tensor/30107

正文

Contiguous是一个标志,指示张量在内存中是否连续存储。
让我们举个例子来看看,我们如何得到一个非连续的张量。

# 创建一个形状是[4, 3]的张量
x = torch.arange(12).view(4, 3)
print(x, x.stride())

> tensor([[ 0,  1,  2],
        [ 3,  4,  5],
        [ 6,  7,  8],
        [ 9, 10, 11]]) 
# 步幅,stride
> (3, 1)   

如你所见,张量具有所要的形状,也就是[4, 3]。步幅(stride)也很有趣,它告诉我们,我们在内存中需要跳过多少个位置(step),才可以沿着某个轴(axis)移动到下一个位置。

如果我们看一下步幅(stride),我们会看到,我们必须跳过3个值才能转到新行,而只需跳过1个值就能转到下一列。
到目前为止都很好理解。
这些值按顺序存储在内存中,即内存单元应将数据[0,1,2,3,…,11]保存到连续地址空间。

现在让我们转置张量,并再次看一下步幅:

y = x.t()   # 转置
print(y, y.stride())
print(y.is_contiguous())

> tensor([[ 0,  3,  6,  9],
        [ 1,  4,  7, 10],
        [ 2,  5,  8, 11]]) 

> (1, 3)   # 步幅
> False    # 是否连续

print 语句正确地输出了张量的x的转置视图。
但是,步幅现在已经互换了
为了转到下一行,我们只需要跳过1个值,而转到下一列需要跳过3个值。

这也说得通,如果我们回想一下张量在内存中的布局:

注意:转置并没有让内存中的布局发生改变。

[0, 1, 2, 3, 4, ..., 11]

为了移动到下一列(例如,从0到3,我们必须跳过3个值。
因此,张量不再是不连续的!

这对我们来说并不是一个真正的问题,除了某些操作不起作用。
例如,如果我们尝试获得 y 的扁平化视图,我们将遇到运行时错误:

try:
    y = y.view(-1)   # 希望的到y的一维向量试图
except RuntimeError as e:
    print(e)
> invalid argument 2: view size is not compatible with input tensor's size and stride (at least one dimension spans across two contiguous subspaces). Call .contiguous() before .view().
So let’s call .contiguous() before the view call:

y = y.contiguous()   # 显示调用contiguous方法

>>> y
tensor([[ 0,  3,  6,  9],
        [ 1,  4,  7, 10],
        [ 2,  5,  8, 11]])
        
print(y.stride())
> (4, 1)

>>> y.view(-1)
tensor([ 0,  3,  6,  9,  1,  4,  7, 10,  2,  5,  8, 11])

现在,内存布局再次是连续的(看看步幅),view工作正常。
我不完全确定,但我假设调用contiguous会调用复制操作让内存再次连续。

也就是说,连续数组对于某些矢量化指令工作是必要的前提条件。

调用contiguous会导致内存复制操作吗?

如果在非连续张量上调用 contiguous,则将执行复制,否则,这将是一个没有影响的操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值