Skip to content

← Shapes and Strides step 2 of 9

Medium Primitives

view refuses, reshape copies

These two lines look interchangeable. They are not, and the difference is the most useful thing in this track.

x.view(-1)
x.reshape(-1)

view promises

view returns a view or nothing. It will not allocate. If the flattening you asked for cannot be expressed as a stride change over the existing buffer, it raises:

RuntimeError: view size is not compatible with input tensor's
size and stride (at least one dimension spans across two
contiguous subspaces).

When can it not? Read a transposed matrix in row-major order and you jump around the buffer:

m  = [[0, 1, 2, 3],       buffer: 0 1 2 3 4 5 6 7 8 9 10 11
      [4, 5, 6, 7],
      [8, 9, 10, 11]]

m.t() read flat:  0 4 8 1 5 9 2 6 10 3 7 11
                  ^^^^^^^ stride 4, then jump back

No single stride produces that order from that buffer. So there is no view, and view says so.

reshape does not promise

reshape returns a view when it can and a copy when it cannot. It never raises, and it never tells you which one you got.

m.reshape(-1)      # a view.  0 bytes copied.
m.t().reshape(-1)  # a copy. 12 floats copied, silently.

That silence is the trade. reshape is the right default precisely because it always works, and it is a hazard in a hot loop for exactly the same reason: the version that allocates looks identical to the version that does not.

flatten behaves like reshape here, for the same reasons.

Which to reach for

Use reshape when you want the result and do not care how you got it. Use view when a copy would be a bug and you want to be told, which is most often inside a layer that runs a million times.

Your task

def flatten(x: torch.Tensor) -> torch.Tensor

Return x flattened to one dimension, for any input, contiguous or not.

The starter uses view and raises on half the cases. The harness reports whether the buffer was shared, and you will see it come back true for some inputs and false for others with the same correct code. That is the lesson, not a bug in your answer.