Странное поведение аргумента "out" в torch.empty () - PullRequest
0 голосов
/ 13 октября 2018

У меня есть примерный тензор, подобный следующему:

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)

Теперь я хочу освободить память этого тензора, переписав содержимое с помощью torch.empty(), который принимает аргумент out.

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 остаются прежними.Если это так, то какова цель этого ключевого аргумента out в torch.empty?Что мне здесь не хватает?

1 Ответ

0 голосов
/ 13 октября 2018

Вот реализация C ++ empty с параметром out из исходного кода.

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 или что-то в этом роде, потому что, опять же, это неинициализированные данные.

...