View on portion of tensor
I have a multiple dimensions tensor, let's take this simple one as example:

out = torch.Tensor(3, 4, 5)


I have to get a portion/subpart of this tensor out[:,0,:] and then apply the method view(-1), but it's not possible:

 out[:,0,:].view(-1)


RuntimeError: invalid argument 2: view size is not compatible with input tensor's size and stride (at least one dimension spans across two contiguous subspaces). Call .contiguous() before .view(). at ../aten/src/TH/generic/THTensor.cpp:203

A solution is to clone the subpart:

 out[:,0,:].clone().view(-1)


Is there a better/faster solution than cloning?

What you did will work fine. That said, a more portable approach would be to use reshape which will return a view when possible, but will create a contiguous copy if necessary. That way it will do the fastest thing possible. In your case the data must be copied, but by always using reshape there are cases where a copy won't be produced.

So you could use

out[:,0,:].reshape(-1)




Gotcha

There's one important gotcha here. If you perform in-place operations on the output of reshape then that may or may not affect the original tensor, depending on whether or not a view or copy was returned.

For example, assuming out is already contiguous then in this case

&gt;&gt;&gt; x = out[:,0,:].reshape(-1)    # returns a copy
&gt;&gt;&gt; x[0] = 10
&gt;&gt;&gt; print(out[0,0,0].item() == 10)
False


x is a copy so changes to it don't affect out. But in this case

&gt;&gt;&gt; x = out[:,:,0].reshape(-1)     # returns a view
&gt;&gt;&gt; x[0] = 10
&gt;&gt;&gt; print(out[0,0,0].item() == 10)
True


x is a view, so in-place changes to x will change out as well.



Alternatives

A couple alternative are

out[:,0,:].flatten()    # .flatten is just a special case of .reshape


and

out[:,0,:].contiguous().view(-1)


Though if you want the fastest approach I recommend against the latter method using contiguous().view since, in general, it is more likely than reshape or flatten to return a copy. This is because contiguous will create a copy even if the underlying data has the same number of bytes between subsequent entries. Therefore, there's a difference between

out[:,:,0].contiguous().view(-1)       # creates a copy


and

out[:,:,0].flatten()                   # creates a non-contiguous view (b/c underlying data has uniform spacing of out.shape[2] values between entries)


where the contiguous().view approach forces a copy since out[:,:,0] is not contiguous, but flatten/reshape would create a view since the underlying data is uniformly spaced.

Sometimes contiguous() won't create a copy, for example compare

out[0,:,:].contiguous().view(-1)       # creates a view b/c out[0,:,:] already is contiguous


and

out[0,:,:].flatten()                   # creates a view


which both produce a view of the original data without copying since out[0,:,:] is already contiguous.



If you want to ensure that the out is decoupled completely from its flattened counterpart then the original approach using .clone() is the way to go.
