code: def upsampling(
      data,
      scale_h,
      scale_w,
      layout="NCHW",
      method="nearest_neighbor",
      align_corners=False,
      output_shape=None,
  ):
      """Perform upsampling on the data.
         Nearest neighbor and bilinear upsampling are supported.
  
      Parameters
      ----------
      inputs : tvm.te.Tensor
          inputs is a 4-D tensor with shape
          [batch, channel, in_height, in_width]
          or  [batch, in_height, in_width, channel]
  
      scale_h : float
          Scaling factor for height
  
      scale_w : float
          Scaling factor for width
  
      layout : string, optional
          either "NCHW" or "NHWC"
  
      method : {"bilinear", "nearest_neighbor", "bicubic"}
          Method to be used for upsampling.
  
      output_shape: tvm.tir.container.Array, optional
          Shape to return. If left None will be inferred
          (If shape is determined dynamically, pass out_dtype.shape as output_shape)
  
      Returns
      -------
      output : tvm.te.Tensor
          4-D with shape [batch, channel, in_height*scale_h, in_width*scale_w]
          or [batch, in_height*scale, in_width*scale, channel]
      """
      base_layout = layout[0:4]
      if base_layout == "NCHW":
          if not output_shape:  # static case
              scaled_h = data.shape[2] * scale_h
              scaled_w = data.shape[3] * scale_w
              reshape_size = (
                  simplify(
                      topi.cast(te.round(scaled_h), data.shape[2].dtype)
                  ),
                  simplify(
                      topi.cast(te.round(scaled_w), data.shape[3].dtype)
                  ),
              )
          else:  # dynamic case -- we don't need to scale; already done in shape func
              reshape_size = (
                  simplify(
                      topi.cast(
                          te.round(output_shape[2]),
                          output_shape[2].dtype,
                      )
                  ),
                  simplify(
                      topi.cast(
                          te.round(output_shape[3]),
                          output_shape[3].dtype,
                      )
                  ),
              )
      elif layout == "NHWC":
          if not output_shape:  # static case
              scaled_h = data.shape[1] * scale_h
              scaled_w = data.shape[2] * scale_w
              reshape_size = (
                  simplify(
                      topi.cast(te.round(scaled_h), data.shape[1].dtype)
                  ),
                  simplify(
                      topi.cast(te.round(scaled_w), data.shape[2].dtype)
                  ),
              )
          else:  # dynamic case
              reshape_size = (
                  simplify(
                      topi.cast(
                          te.round(output_shape[1]),
                          output_shape[1].dtype,
                      )
                  ),
                  simplify(
                      topi.cast(
                          te.round(output_shape[2]),
                          output_shape[2].dtype,
                      )
                  ),
              )
  
      else:
          raise ValueError(f"not support this layout {layout} yet")
      coord_trans = "align_corners" if align_corners else "asymmetric"
      if method[0:2] == "bi":
          method = method[2:]
      return topi.image.resize2d(
          data,
          [0.0] * 4,
          reshape_size,
          layout=layout,
          method=method,
          coordinate_transformation_mode=coord_trans,
          output_shape=output_shape,
      )
  
imports: from tvm import topi
  from tvm import te
  from ..utils import simplify
label_desc: Use image node_id 1 for calling a global function with example usage: upsampling(data, scale_h, scale_w, layout, method, align_corners, output_shape) and returns: topi