在Open3D的open3d.core.Tensor
中,strides
表示每个维度上所占用内存的步幅大小。步幅大小指的是在内存中相邻两个元素之间所间隔的字节数,而不是元素个数。
具体地说,对于一个shape
为(s_0, s_1, ..., s_n)
的tensor来说,它在第i
个维度上的步幅大小为$t_i$。其中,$t_i$的计算公式为:
$$ t_i = \prod_{j=i+1}^n s_j \times element_size $$
其中,$element_size$表示tensor中一个元素所占的字节数。在Open3D中,默认的元素大小为4个字节(即32位浮点数)。
除了shape
和data
外,strides
也是一个tensor的重要属性之一,它可以提供有关内存连续性和内存布局的信息。如果所有维度上的步幅大小相等,则tensor是连续的(即C连续性),即相邻两个元素在内存中是紧密排列的。如果只有某些维度上的步幅大小相等,则tensor是非连续的(即Fortran连续性),即相邻两个元素在内存中有可能是断开的。
在实际使用中,可以通过contiguous()
方法将tensor转换为其C连续版本,以提高tensor在计算过程中的效率。
示例代码如下:
import open3d as o3d
import numpy as np
# 定义一个非连续的tensor
data_np = np.array([[[1, 2], [3, 4]], [[5, 6], [7, 8]]], dtype=np.float32)
tensor = o3d.core.Tensor(data_np, device=o3d.core.Device("CPU:0")).permute([2, 0, 1]) # permute改变维度顺序
print('非连续tensor:', tensor)
print('非连续tensor的步幅大小:', tensor.strides())
# 将tensor转换为C连续版本
tensor_cont = tensor.contiguous()
print('C连续tensor:', tensor_cont)
print('C连续tensor的步幅大小:', tensor_cont.strides())
执行结果如下所示:
非连续tensor: Tensor[size={2, 2, 2}, stride={8, 4, 16}, CPU:0, float32, is_contiguous=False, requires_grad=False]
非连续tensor的步幅大小: (8, 4, 16)
C连续tensor: Tensor[size={2, 2, 2}, stride={16, 8, 4}, CPU:0, float32, is_contiguous=True, requires_grad=False]
C连续tensor的步幅大小: (16, 8, 4)
可以看到,tensor
是一个非连续tensor,它在第0维度上的步幅大小为8,这意味着相邻两行之间需要间隔8个字节才能到达下一个元素。而在其C连续版本中,tensor_cont
在所有维度上的步幅大小都相等,为16,这意味着相邻两个元素之间连续排列在内存中,不存在间隔。