code: def warp_perspective(
      src: Tensor,
      M: Tensor,
      dsize: tuple[int, int],
      mode: str = "bilinear",
      padding_mode: str = "zeros",
      align_corners: bool = True,
      fill_value: Tensor = zeros(3),  # needed for jit
  ) -> Tensor:
      r"""Apply a perspective transformation to an image.
  
      The function warp_perspective transforms the source image using
      the specified matrix:
  
      .. math::
          \text{dst} (x, y) = \text{src} \left(
          \frac{M^{-1}_{11} x + M^{-1}_{12} y + M^{-1}_{13}}{M^{-1}_{31} x + M^{-1}_{32} y + M^{-1}_{33}} ,
          \frac{M^{-1}_{21} x + M^{-1}_{22} y + M^{-1}_{23}}{M^{-1}_{31} x + M^{-1}_{32} y + M^{-1}_{33}}
          \right )
  
      Args:
          src: input image with shape :math:`(B, C, H, W)`.
          M: transformation matrix with shape :math:`(B, 3, 3)`.
          dsize: size of the output image (height, width).
          mode: interpolation mode to calculate output values ``'bilinear'`` | ``'nearest'``.
          padding_mode: padding mode for outside grid values ``'zeros'`` | ``'border'`` | ``'reflection'`` | ``'fill'``.
          align_corners: interpolation flag.
          fill_value: tensor of shape :math:`(3)` that fills the padding area. Only supported for RGB.
  
      Returns:
          the warped input image :math:`(B, C, H, W)`.
  
      Example:
         >>> img = torch.rand(1, 4, 5, 6)
         >>> H = torch.eye(3)[None]
         >>> out = warp_perspective(img, H, (4, 2), align_corners=True)
         >>> print(out.shape)
         torch.Size([1, 4, 4, 2])
  
      .. note::
          This function is often used in conjunction with :func:`get_perspective_transform`.
  
      .. note::
          See a working example `here <https://kornia.github.io/tutorials/nbs/warp_perspective.html>`_.
      """
      if not isinstance(src, Tensor):
          raise TypeError(
              f"Input src type is not a Tensor. Got {type(src)}"
          )
  
      if not isinstance(M, Tensor):
          raise TypeError(
              f"Input M type is not a Tensor. Got {type(M)}"
          )
  
      if not len(src.shape) == 4:
          raise ValueError(
              f"Input src must be a BxCxHxW tensor. Got {src.shape}"
          )
  
      if not (len(M.shape) == 3 and M.shape[-2:] == (3, 3)):
          raise ValueError(
              f"Input M must be a Bx3x3 tensor. Got {M.shape}"
          )
  
      # fill padding is only supported for 3 channels because we can't set fill_value default
      # to None as this gives jit issues.
      if padding_mode == "fill" and fill_value.shape != torch.Size([3]):
          raise ValueError(
              f"Padding_tensor only supported for 3 channels. Got {fill_value.shape}"
          )
  
      B, _, H, W = src.size()
      h_out, w_out = dsize
  
      # we normalize the 3x3 transformation matrix and convert to 3x4
      dst_norm_trans_src_norm: Tensor = normalize_homography(
          M, (H, W), (h_out, w_out)
      )  # Bx3x3
  
      src_norm_trans_dst_norm = _torch_inverse_cast(
          dst_norm_trans_src_norm
      )  # Bx3x3
  
      # this piece of code substitutes F.affine_grid since it does not support 3x3
      grid = (
          create_meshgrid(
              h_out,
              w_out,
              normalized_coordinates=True,
              device=src.device,
          )
          .to(src.dtype)
          .expand(B, h_out, w_out, 2)
      )
      grid = transform_points(
          src_norm_trans_dst_norm[:, None, None], grid
      )
  
      if padding_mode == "fill":
          return _fill_and_warp(
              src,
              grid,
              align_corners=align_corners,
              mode=mode,
              fill_value=fill_value,
          )
      return F.grid_sample(
          src,
          grid,
          align_corners=align_corners,
          mode=mode,
          padding_mode=padding_mode,
      )
  
imports: from __future__ import annotations
  from typing import Optional
  import torch
  import torch.nn.functional
  from kornia.core import Tensor, concatenate, ones, ones_like, stack, tan, tensor, zeros
  from kornia.core.check import KORNIA_CHECK, KORNIA_CHECK_SHAPE
  from kornia.geometry.conversions import angle_to_rotation_matrix, axis_angle_to_rotation_matrix, convert_affinematrix_to_homography, convert_affinematrix_to_homography3d, deg2rad, normalize_homography, normalize_homography3d, normalize_pixel_coordinates
  from kornia.geometry.linalg import transform_points
  from kornia.utils import create_meshgrid, create_meshgrid3d, eye_like
  from kornia.utils.helpers import _torch_inverse_cast, _torch_solve_cast
label_desc: Use image node_id 1 for calling a global function with example usage: warp_perspective(src, M, dsize, mode, padding_mode, align_corners, fill_value) and returns: F, _fill_and_warp