class_docstr: Standard anchor generator for 2D anchor-based detectors.
  
  Args:
      strides (list[int] | list[tuple[int, int]]): Strides of anchors
          in multiple feature levels in order (w, h).
      ratios (list[float]): The list of ratios between the height and width
          of anchors in a single level.
      scales (list[int] | None): Anchor scales for anchors in a single level.
          It cannot be set at the same time if `octave_base_scale` and
          `scales_per_octave` are set.
      base_sizes (list[int] | None): The basic sizes
          of anchors in multiple levels.
          If None is given, strides will be used as base_sizes.
          (If strides are non square, the shortest stride is taken.)
      scale_major (bool): Whether to multiply scales first when generating
          base anchors. If true, the anchors in the same row will have the
          same scales. By default it is True in V2.0
      octave_base_scale (int): The base scale of octave.
      scales_per_octave (int): Number of scales for each octave.
          `octave_base_scale` and `scales_per_octave` are usually used in
          retinanet and the `scales` should be None when they are set.
      centers (list[tuple[float, float]] | None): The centers of the anchor
          relative to the feature grid center in multiple feature levels.
          By default it is set to be None and not used. If a list of tuple of
          float is given, they will be used to shift the centers of anchors.
      center_offset (float): The offset of center in proportion to anchors'
          width and height. By default it is 0 in V2.0.
  
  Examples:
      >>> from mmdet.core import AnchorGenerator
      >>> self = AnchorGenerator([16], [1.], [1.], [9])
      >>> all_anchors = self.grid_anchors([(2, 2)], device='cpu')
      >>> print(all_anchors)
      [tensor([[-4.5000, -4.5000,  4.5000,  4.5000],
              [11.5000, -4.5000, 20.5000,  4.5000],
              [-4.5000, 11.5000,  4.5000, 20.5000],
              [11.5000, 11.5000, 20.5000, 20.5000]])]
      >>> self = AnchorGenerator([16, 32], [1.], [1.], [9, 18])
      >>> all_anchors = self.grid_anchors([(2, 2), (1, 1)], device='cpu')
      >>> print(all_anchors)
      [tensor([[-4.5000, -4.5000,  4.5000,  4.5000],
              [11.5000, -4.5000, 20.5000,  4.5000],
              [-4.5000, 11.5000,  4.5000, 20.5000],
              [11.5000, 11.5000, 20.5000, 20.5000]]),         tensor([[-9., -9., 9., 9.]])]
docstr: Generate grid anchors of a single level.
  
  Note:
      This function is usually called by method ``self.grid_anchors``.
  
  Args:
      base_anchors (torch.Tensor): The base anchors of a feature grid.
      featmap_size (tuple[int]): Size of the feature maps.
      stride (tuple[int], optional): Stride of the feature map in order
          (w, h). Defaults to (16, 16).
      device (str, optional): Device the tensor will be put on.
          Defaults to 'cuda'.
  
  Returns:
      torch.Tensor: Anchors in the overall feature maps.
code: def single_level_grid_anchors(
      self, base_anchors, featmap_size, stride=(16, 16), device="cuda"
  ):
      """Generate grid anchors of a single level.
  
      Note:
          This function is usually called by method ``self.grid_anchors``.
  
      Args:
          base_anchors (torch.Tensor): The base anchors of a feature grid.
          featmap_size (tuple[int]): Size of the feature maps.
          stride (tuple[int], optional): Stride of the feature map in order
              (w, h). Defaults to (16, 16).
          device (str, optional): Device the tensor will be put on.
              Defaults to 'cuda'.
  
      Returns:
          torch.Tensor: Anchors in the overall feature maps.
      """
      feat_h, feat_w = featmap_size
      # convert Tensor to int, so that we can covert to ONNX correctlly
      feat_h = int(feat_h)
      feat_w = int(feat_w)
      shift_x = torch.arange(0, feat_w, device=device) * stride[0]
      shift_y = torch.arange(0, feat_h, device=device) * stride[1]
  
      shift_xx, shift_yy = self._meshgrid(shift_x, shift_y)
      shifts = torch.stack(
          [shift_xx, shift_yy, shift_xx, shift_yy], dim=-1
      )
      shifts = shifts.type_as(base_anchors)
      # first feat_w elements correspond to the first row of shifts
      # add A anchors (1, A, 4) to K shifts (K, 1, 4) to get
      # shifted anchors (K, A, 4), reshape to (K*A, 4)
  
      all_anchors = base_anchors[None, :, :] + shifts[:, None, :]
      all_anchors = all_anchors.view(-1, 4)
      # first A rows correspond to A anchors of (0, 0) in feature map,
      # then (0, 1), (0, 2), ...
      return all_anchors
  
imports: import mmcv
  import numpy
  import torch
  from torch.nn.modules.utils import _pair
  from .builder import ANCHOR_GENERATORS
label_desc: Use image node_id 8 for calling the AnchorGenerator obj's underlying member method code with example usage: obj.single_level_grid_anchors(base_anchors, featmap_size, stride, device) and returns: all_anchors