class_docstr: The 'vgg7' waifu2x network.
  Lower quality and slower than even upconv7 (nevermind cunet), but is very easy to implement and test.
class_docstr_tok: ["The","'vgg7","'","waifu2x","network",".","Lower","quality","and","slower","than","even","upconv7","(","nevermind","cunet",")",",","but","is","very","easy","to","implement","and","test","."]
docstr: Given an ndarray image as loaded by image_load (NOT a tensor), scales it, pads it, splits it up, forwards the pieces, and reconstitutes it.
  Note that you really shouldn't try to run anything not (1, 3, *, *) through this.
docstr_tok: ["Given","an","ndarray","image","as","loaded","by","image_load","(","NOT","a","tensor",")",",","scales","it",",","pads","it",",","splits","it","up",",","forwards","the","pieces",",","and","reconstitutes","it",".","Note","that","you","really","should","n't","try","to","run","anything","not","(","1",",","3",",","*",",","*",")","through","this","."]
code: def forward_tiled(
      self, image: numpy.ndarray, tile_size: int
  ) -> numpy.ndarray:
      """
      Given an ndarray image as loaded by image_load (NOT a tensor), scales it, pads it, splits it up, forwards the pieces, and reconstitutes it.
      Note that you really shouldn't try to run anything not (1, 3, *, *) through this.
      """
      # Constant that only really gets repeated a ton here.
      context = 7
      context2 = context + context
  
      # Notably, numpy is used here because it makes this fine manipulation a lot simpler.
      # Scaling first - repeat on axis 2 and axis 3 (Y & X)
      image = image.repeat(2, 2).repeat(2, 3)
  
      # Resulting image buffer. This is made before the input is padded,
      #  since the input has the padded shape right now.
      image_out = numpy.zeros(image.shape)
  
      # Padding next. Note that this padding is done on the whole image.
      # Padding the tiles would lose critical context, cause seams, etc.
      image = numpy.pad(
          image,
          [[0, 0], [0, 0], [context, context], [context, context]],
          mode="edge",
      )
  
      # Now for tiling.
      # The output tile size is the usable output from an input tile (tile_size).
      # As such, the tiles overlap.
      out_tile_size = tile_size - context2
      for out_y in range(0, image_out.shape[2], out_tile_size):
          for out_x in range(0, image_out.shape[3], out_tile_size):
              # Input is sourced from the same coordinates, but some stuff ought to be
              #  noted here for future reference:
              # + out_x/y's equivalent position w/ the padding is out_x + context.
              # + The output, however, is without context. Input needs context.
              # + Therefore, the input rectangle is expanded on all sides by context.
              # + Therefore, the input position has the context subtracted again.
              # + Therefore:
              in_y = out_y
              in_x = out_x
              # not shown: in_w/in_h = tile_size (as opposed to out_tile_size)
              # Extract tile.
              # Note that numpy will auto-crop this at the bottom-right.
              # This will never be a problem, as tiles are specifically chosen within the padded section.
              tile = image[
                  :, :, in_y : in_y + tile_size, in_x : in_x + tile_size
              ]
              # Extracted tile dimensions -> output dimensions
              # This is important because of said cropping, otherwise it'd be interior tile size.
              out_h = tile.shape[2] - context2
              out_w = tile.shape[3] - context2
              # Process tile.
              tile_t = Tensor(tile)
              tile_fwd_t = self.forward(tile_t)
              # Replace tile.
              image_out[
                  :, :, out_y : out_y + out_h, out_x : out_x + out_w
              ] = tile_fwd_t.numpy()
  
      return image_out
  
file_path: tinygrad/examples/vgg7_helpers/waifu2x.py
imports: import numpy
  from tinygrad.tensor import Tensor
  from PIL import Image
  from tinygrad.helpers import fetch
label_desc: Use image node_id 6 for calling the Vgg7 obj's underlying member method code with example usage: obj.forward_tiled(image, tile_size) and returns: image_out