torch.empty() 中 "out" 参数的奇怪行为
Odd behaviour of "out" argument in torch.empty()
我有一个像这样的样本张量:
In [137]: x = x.new_ones((5, 3), dtype=torch.double)
In [138]: x
Out[138]:
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
现在,我想通过使用带有 out
参数的 torch.empty()
覆盖内容来释放该张量的内存。
In [139]: torch.empty((5, 3), out=x)
Out[139]:
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
然而,原始张量中的值 x
仍然保持不变。如果是这种情况,那么 torch.empty
中的关键字参数 out
的目的是什么?我在这里错过了什么?
Here's empty
的 C++ 实现,带有来自源代码的输出参数。
Tensor& empty_out(Tensor& result, IntList size) {
if (result.is_sparse()) {
result.sparse_resize_and_clear_(size, size.size(), 0);
} else {
result.resize_(size);
}
return result;
}
因此,对于密集张量,它所做的只是适当地调整张量的大小——在您的情况下,大小是相同的。
In [21]: x = torch.ones((5, 3), dtype=torch.double)
In [22]: torch.empty((2, 3), out=x)
Out[22]:
tensor([[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
In [23]: torch.empty((2, 8), out=x)
Out[23]:
tensor([[ 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00,
1.0000e+00, 1.0000e+00, 1.0000e+00],
[ 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00,
1.0000e+00, 1.0000e+00, 4.6631e-310]], dtype=torch.float64)
首先,empty
不会释放内存——它只关心适当大小的张量的分配。在您的情况下,已经分配了这样一个张量,因此 empty
无关。它不会在内存中的其他地方分配一个新的空张量。在上面的第二个 empty
示例中,我们被迫分配一个更大的张量(2 * 8 = 16 与 5 * 3 = 15 相比),我们可以看到这个空数组中的最后一个元素是垃圾,因为它超出了先前已初始化的连续内存块。 empty
不会将您的整个张量强制清除为 0 或类似的东西,因为它又是未初始化的数据。
我有一个像这样的样本张量:
In [137]: x = x.new_ones((5, 3), dtype=torch.double)
In [138]: x
Out[138]:
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
现在,我想通过使用带有 out
参数的 torch.empty()
覆盖内容来释放该张量的内存。
In [139]: torch.empty((5, 3), out=x)
Out[139]:
tensor([[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
然而,原始张量中的值 x
仍然保持不变。如果是这种情况,那么 torch.empty
中的关键字参数 out
的目的是什么?我在这里错过了什么?
Here's empty
的 C++ 实现,带有来自源代码的输出参数。
Tensor& empty_out(Tensor& result, IntList size) {
if (result.is_sparse()) {
result.sparse_resize_and_clear_(size, size.size(), 0);
} else {
result.resize_(size);
}
return result;
}
因此,对于密集张量,它所做的只是适当地调整张量的大小——在您的情况下,大小是相同的。
In [21]: x = torch.ones((5, 3), dtype=torch.double)
In [22]: torch.empty((2, 3), out=x)
Out[22]:
tensor([[1., 1., 1.],
[1., 1., 1.]], dtype=torch.float64)
In [23]: torch.empty((2, 8), out=x)
Out[23]:
tensor([[ 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00,
1.0000e+00, 1.0000e+00, 1.0000e+00],
[ 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00, 1.0000e+00,
1.0000e+00, 1.0000e+00, 4.6631e-310]], dtype=torch.float64)
首先,empty
不会释放内存——它只关心适当大小的张量的分配。在您的情况下,已经分配了这样一个张量,因此 empty
无关。它不会在内存中的其他地方分配一个新的空张量。在上面的第二个 empty
示例中,我们被迫分配一个更大的张量(2 * 8 = 16 与 5 * 3 = 15 相比),我们可以看到这个空数组中的最后一个元素是垃圾,因为它超出了先前已初始化的连续内存块。 empty
不会将您的整个张量强制清除为 0 或类似的东西,因为它又是未初始化的数据。