Pytorch 0.4.0: There are three ways to create tensors on CUDA device. Is there some difference between them?
I failed in the third way. t3 is still on CPU. No idea why.

a = np.random.randn(1, 1, 2, 3)

t1 = torch.tensor(a)
t1 = t3.to(torch.device('cuda'))

t2 = torch.tensor(a)
t2 = t2.cuda() 

t3 = torch.tensor(a, device=torch.device('cuda'))


All three methods worked for me. 

In 1 and 2, you create a tensor on CPU and then move it to GPU when you use .to(device) or .cuda(). They are the same here.

However, when you use .to(device) method you can explicitly tell torch to move to specific GPU by setting device=torch.device("cuda:&lt;id&gt;"). with .cuda() you have to do .cuda(&lt;id&gt;) to move to some particular GPU. 



Why do these two methods exist then?

.to(device) was introduced in 0.4 because it is easier to declare device variable at top of the code as 

device = torch.device("cuda") if torch.cuda.is_available() else torch.device("cpu")

and use .to(device) everywhere. This makes it quite easy to switch from CPU to GPU and vice-versa

Before this, we had to use .cuda() and your code will have if check for cuda.is_available() everywhere which made it cumbersome to switch between GPU/CPU.



The third method doesn't create a tensor on the CPU and directly copies data to GPU, which is more efficient. 
