For a general use case using a grid you could use .fold():
x = torch.arange(1, 17).float().view(1, 1, 4, 4)

kh, kw = 2, 2  # kernel_size
dh, dw = 2, 2  # stride
# get all image windows of size (kh, kw) and stride (dh, dw)
input_windows = x.unfold(2, kh, dh).unfold(3, kw, dw)
output = input_windows.contiguous().view(x.size())