code: def rotate90(img, axes, k, lazy, transform_info):
      """
      Functional implementation of rotate90.
      This function operates eagerly or lazily according to
      ``lazy`` (default ``False``).
  
      Args:
          img: data to be changed, assuming `img` is channel-first.
          axes: 2 int numbers, defines the plane to rotate with 2 spatial axes.
              If axis is negative it counts from the last to the first axis.
          k: number of times to rotate by 90 degrees.
          lazy: a flag that indicates whether the operation should be performed lazily or not
          transform_info: a dictionary with the relevant information pertaining to an applied transform.
      """
      extra_info = {"axes": [d - 1 for d in axes], "k": k}
      ori_shape = (
          img.peek_pending_shape()
          if isinstance(img, MetaTensor)
          else img.shape[1:]
      )
      sp_shape = list(ori_shape)
      if k in (1, 3):
          a_0, a_1 = axes[0] - 1, axes[1] - 1
          sp_shape[a_0], sp_shape[a_1] = ori_shape[a_1], ori_shape[a_0]
      rank = (
          img.peek_pending_rank()
          if isinstance(img, MetaTensor)
          else torch.tensor(3.0, dtype=torch.double)
      )
      r, sp_r = int(rank), len(ori_shape)
      xform = to_affine_nd(
          r,
          create_translate(sp_r, [-float(d - 1) / 2 for d in sp_shape]),
      )
      s = -1.0 if int(axes[0]) - int(axes[1]) in (-1, 2) else 1.0
      if sp_r == 2:
          rot90 = to_affine_nd(r, create_rotate(sp_r, [s * np.pi / 2]))
      else:
          idx = {1, 2, 3} - set(axes)
          angle: list[float] = [0, 0, 0]
          angle[idx.pop() - 1] = s * np.pi / 2
          rot90 = to_affine_nd(r, create_rotate(sp_r, angle))
      for _ in range(k):
          xform = rot90 @ xform
      xform = (
          to_affine_nd(
              r,
              create_translate(
                  sp_r, [float(d - 1) / 2 for d in ori_shape]
              ),
          )
          @ xform
      )
      meta_info = TraceableTransform.track_transform_meta(
          img,
          sp_size=sp_shape,
          affine=xform,
          extra_info=extra_info,
          orig_size=ori_shape,
          transform_info=transform_info,
          lazy=lazy,
      )
      out = _maybe_new_metatensor(img)
      if lazy:
          return (
              out.copy_meta_from(meta_info)
              if isinstance(out, MetaTensor)
              else meta_info
          )
      out = torch.rot90(out, k, axes)
      return (
          out.copy_meta_from(meta_info)
          if isinstance(out, MetaTensor)
          else out
      )
  
imports: from __future__ import annotations
  import math
  import warnings
  from enum import Enum
  import numpy
  import torch
  import monai
  from monai.config import USE_COMPILED
  from monai.config.type_definitions import NdarrayOrTensor
  from monai.data.meta_obj import get_track_meta
  from monai.data.meta_tensor import MetaTensor
  from monai.data.utils import AFFINE_TOL, compute_shape_offset, to_affine_nd
  from monai.networks.layers import AffineTransform
  from monai.transforms.croppad.array import ResizeWithPadOrCrop
  from monai.transforms.intensity.array import GaussianSmooth
  from monai.transforms.inverse import TraceableTransform
  from monai.transforms.utils import create_rotate, create_translate, resolves_modes, scale_affine
  from monai.transforms.utils_pytorch_numpy_unification import allclose
  from monai.utils import LazyAttr, TraceKeys, convert_to_dst_type, convert_to_numpy, convert_to_tensor, ensure_tuple, ensure_tuple_rep, fall_back_tuple, optional_import
label_desc: Use image node_id 8 for calling a global function with example usage: rotate90(img, axes, k, lazy, transform_info) and returns: unknown, unknown