Skip to content

← Shapes and Strides step 7 of 9

Medium Primitives

Where a view starts in storage

Jump to the task

A strided tensor describes how to read values from a storage buffer. Its shape gives the size of each axis, its strides give the spacing between elements, and its storage offset locates the first element in that buffer. Offsets and strides are measured in elements, not bytes.

import torch

v = torch.arange(10)
s = v[3:7]
print(s.tolist())  # [3, 4, 5, 6]
print(s.storage_offset())  # 3
print(s.stride())  # (1,)

The slice shares the original storage but starts three elements into it.

Two different addresses

For these nonempty tensors, data_ptr() gives the address of the tensor's first element. The storage pointer gives the beginning of its underlying buffer:

print(s.data_ptr() == v.data_ptr())  # False
print(s.untyped_storage().data_ptr() == v.untyped_storage().data_ptr())  # True

Comparing first-element pointers would incorrectly report that this slice uses a separate buffer. For an ordinary nonempty strided tensor:

first-element address = storage address + storage_offset * element_size

The storage comparison answers this exercise's question for live, nonempty tensors on the same device. It is not a general overlap test: two slices can share a storage allocation while selecting completely disjoint elements. Pointer values also need device context, and empty tensors need separate handling.

A column can be a view too

m = torch.arange(20).reshape(4, 5)
col = m[:, 2]
print(col.storage_offset())  # 2
print(col.stride())  # (5,)
print(col.tolist())  # [2, 7, 12, 17]

The column begins at offset 2 and advances five elements at a time. It reuses the data buffer; only view metadata is needed. The offset is relative to the storage, not necessarily to the start of the tensor being sliced.

Your task

def describe(x: torch.Tensor, start: int, stop: int) -> dict

Describe the slice x[start:stop] using these fields:

Key Value
offset The slice's storage offset
stride Its single stride, as an integer
shares Whether its storage pointer matches x's storage pointer

The harness supplies a contiguous 1-D tensor with storage offset zero and indices satisfying 0 <= start < stop <= len(x). Every slice is nonempty and shares storage. The starter compares first-element addresses, so it incorrectly reports no sharing when start is positive.