docs: def blockshaped(arr, nrows, ncols):
      """
      Return an new array of shape (n, nrows, ncols) where
      n * nrows * ncols = arr.size
  
      If arr is a 2D array, the returned array looks like n subblocks with
      each subblock preserving the "physical" layout of arr.
      """
      h, w = arr.shape
      return (arr.reshape(h // nrows, nrows, -1, ncols)
                 .swapaxes(1, 2)
                 .reshape(-1, nrows, ncols))