Repository: pytorch/pytorch

Issue:
[docs] Tensor.set_ (arguments)
Python documentation or the interface is lacking here:
`Tensor.set_(source=None, storage_offset=0, size=None, stride=None)`
I was only able to call it when the first argument is positional and is a `Storage` and all other arguments are given as either positional or keyword but no defaults. 

pytorch version: 0.3.1





Discussion:
`.set_()` works on master
```
>>> x.set_()

[torch.FloatTensor of size (0,)]

```
Hmm can you be clearer on what you expect to see? All of the following works for me on master:
```python
>>> x = torch.randn(0)
>>> x

[torch.FloatTensor of size (0,)]

>>> y = torch.randn(3)
>>> y

 0.5596
-1.3084
 0.0580
[torch.FloatTensor of size (3,)]

>>> x.set_(y.storage(), y.storage_offset(), y.size(), y.stride())

 0.5596
-1.3084
 0.0580
[torch.FloatTensor of size (3,)]

>>> x

 0.5596
-1.3084
 0.0580
[torch.FloatTensor of size (3,)]

>>> x.set_(y.storage(), y.storage_offset(), y.size(), stride=y.stride())

 0.5596
-1.3084
 0.0580
[torch.FloatTensor of size (3,)]

>>> x.set_(y.storage(), y.storage_offset(), y.size())

 0.5596
-1.3084
 0.0580
[torch.FloatTensor of size (3,)]

>>> x.set_(y.storage(), 1, [2])

-1.3084
 0.0580
[torch.FloatTensor of size (2,)]

>>> x.set_(y.storage(), size=[2], storage_offset=1)

-1.3084
 0.0580
[torch.FloatTensor of size (2,)]


```
I've checked all the above cases work for me on 0.3.1.
What doesn't work on 0.3.1 or is not conforming to the documented interface `set_(source=None, storage_offset=0, size=None, stride=None) → Tensor`:

`x.set_(y, size=[2], storage_offset=1)`
(the doc says source can be Tensor or Storage)
TypeError: set_ received an invalid combination of arguments - got (torch.FloatTensor, storage_offset=int, size=list)

`x.set_(source = y.storage(), size=[2], storage_offset=1)`
TypeError: set_ received an invalid combination of arguments - got (storage_offset=int, size=list, source=torch.FloatStorage, )

`x.set_(None, size=[2], storage_offset=0)`
TypeError: set_ received an invalid combination of arguments - got (NoneType, storage_offset=int, size=list)

`x.set_(y.storage(), size=[2]) `
(expecting the default storage_offset=0)
TypeError...

With a bit more digging I can see that the following works 
`x.set_(storage=y.storage())`
`x.set_(source=y)`
`x.set_(sourceStorage=y.storage(), size=[2], storage_offset=0)`
but is not matching to the documented python interface.

Resolving patch:
diff --git a/aten/src/ATen/function_wrapper.py b/aten/src/ATen/function_wrapper.py
--- a/aten/src/ATen/function_wrapper.py
+++ b/aten/src/ATen/function_wrapper.py
@@ -286,7 +286,7 @@ def __init__(self, reason):
 CONSTANT_REPLACEMENTS = [
     ('AS_REAL', '${AS_REAL}'),
     ('__storage_size.get\\(\\)',
-     'THLongStorageView(static_cast<int64_t>(storage.size()), THLongStorageViewKind::LENGTH)'),
+     'THLongStorageView(static_cast<int64_t>(source.size()), THLongStorageViewKind::LENGTH)'),
     ('__last_dim', 'self.ndimension()-1'),
 ]
 


Test patch:
diff --git a/test/test_torch.py b/test/test_torch.py
--- a/test/test_torch.py
+++ b/test/test_torch.py
@@ -5805,6 +5805,19 @@ def test_tensor_set(self):
         self.assertEqual(t1.size(), size)
         self.assertEqual(t1.stride(), stride)
 
+        # test argument names
+        t1 = torch.Tensor()
+        # 1. case when source is tensor
+        t1.set_(source=t2)
+        self.assertEqual(t1.storage()._cdata, t2.storage()._cdata)
+        # 2. case when source is storage
+        t1.set_(source=t2.storage())
+        self.assertEqual(t1.storage()._cdata, t2.storage()._cdata)
+        # 3. case when source is storage, and other args also specified
+        t1.set_(source=t2.storage(), storage_offset=0, size=size, stride=stride)
+        self.assertEqual(t1.size(), size)
+        self.assertEqual(t1.stride(), stride)
+
     def test_equal(self):
         # Contiguous, 1D
         t1 = torch.Tensor((3, 4, 9, 10))