code: def forward(
      self, feature_map, region_masks, original_dtype, return_dtype
  ):
      assert len(feature_map) == len(region_masks)
  
      all_points = []
      all_points_fea = []
      all_points_img_ids = []
      # Sample points and their features
      for img_idx, (
          region_feature_map_i,
          region_masks_list_i,
      ) in enumerate(zip(feature_map, region_masks)):
          if len(region_masks_list_i) != 0:
              # (w, h)
              ori_image_wh = torch.tensor(
                  [
                      region_masks_list_i[0].shape[0],
                      region_masks_list_i[0].shape[1],
                  ],
                  device=region_masks_list_i[0].device,
              )[
                  None,
              ]
              # list of elements of shape [num_sample_point, 2]
              # pdb.set_trace()
              cur_non_zero_pos = [
                  rand_sample_repeat(
                      (m.nonzero() / ori_image_wh), self.num_init_point
                  )
                  for m in region_masks_list_i
              ]
              # list -> [num_mask, num_sample_point, 2]
              cur_non_zero_pos = torch.stack(cur_non_zero_pos)
              # [HxW, C] -> [H, W, C] -> [C, H, W] -> [N, C, H, W]
              h = w = int(math.sqrt(region_feature_map_i.shape[0]))
              c = region_feature_map_i.shape[-1]
              dup_region_feature_map_i = region_feature_map_i.reshape(
                  h, w, c
              ).permute(2, 0, 1)
              dup_region_feature_map_i = (
                  dup_region_feature_map_i.unsqueeze(0).repeat(
                      cur_non_zero_pos.shape[0], 1, 1, 1
                  )
              )
              # [num_mask, C, H, W] x [num_mask, num_sample_point, 2] -> [num_mask, C, num_sample_point] -> [num_mask, num_sample_point, C]
              # F.grid_sample doesn't support BF16. Need to tranform into float32 then transform back.
              dup_region_feature_map_i_ori_type = (
                  dup_region_feature_map_i.to(original_dtype)
              )
              region_feature_i = point_sample(
                  dup_region_feature_map_i_ori_type,
                  cur_non_zero_pos.flip(dims=(2,)).type(original_dtype),
                  return_dtype,
                  align_corners=True,
              )
              # region_feature_i = region_feature_i.to(dup_region_feature_map_i.dtype)
              region_feature_i = region_feature_i.transpose(-2, -1)
  
              cur_img_ids = [img_idx] * len(cur_non_zero_pos)
              # save to global list
              all_points.append(cur_non_zero_pos)
              all_points_fea.append(region_feature_i)
              all_points_img_ids.extend(cur_img_ids)
  
      # pdb.set_trace()
      # No region found, return list of None.
      if len(all_points) == 0:
          return [None] * len(region_masks)
  
      all_points = torch.cat(all_points, dim=0).to(
          return_dtype
      )  # [B*num_mask, num_sample_point, 2]
      all_points_fea = torch.cat(
          all_points_fea, dim=0
      )  # [B*num_mask, num_sample_point, C]
      all_points_img_ids = torch.tensor(
          all_points_img_ids, device=all_points_fea.device
      )
      # pdb.set_trace()
      assert all_points_fea.shape[:-1] == all_points_fea.shape[:-1]
  
      # Processing.
      for stage_i in range(len(self.num_sub_point)):
          cur_num_sub_point = self.num_sub_point[stage_i]
          cur_num_neighbor = self.num_neighbor[stage_i]
  
          all_points = all_points.contiguous()  # xy [btach, points, xy]
          fps_idx = farthest_point_sample(
              all_points, cur_num_sub_point
          ).long()
  
          new_points = index_points(
              all_points, fps_idx
          )  # [B, npoint, 2]
          new_points_fea = index_points(
              all_points_fea, fps_idx
          )  # [B, npoint, d]
  
          idx = knn_point(cur_num_neighbor, all_points, new_points)
          grouped_points = index_points(
              all_points, idx
          )  # [B, npoint, k, 2]
          grouped_points_fea = index_points(
              all_points_fea, idx
          )  # [B, npoint, k, d]
  
          # pdb.set_trace()
          local_points_fea = torch.cat(
              [grouped_points_fea, grouped_points], dim=-1
          )  # [B, npoint, k, d+2]
          anchor_points_fea = torch.cat(
              [new_points_fea, new_points], dim=-1
          ).unsqueeze(-2)
          diff_points_fea = local_points_fea - anchor_points_fea
  
          diff_points_fea = self.diff_projector_list[stage_i](
              diff_points_fea
          )
          gather_points_fea = torch.cat(
              [
                  diff_points_fea,
                  anchor_points_fea.repeat(1, 1, cur_num_neighbor, 1),
              ],
              dim=-1,
          )  # [B, npoint, k, 2(d+2)]
  
          # pdb.set_trace()
          b, n, s, d = gather_points_fea.size()
          gather_points_fea = gather_points_fea.permute(
              0, 1, 3, 2
          )  # [B, npoint, 2(d+2), k]
          gather_points_fea = gather_points_fea.reshape(
              -1, d, s
          )  # [B*npoint, 2(d+2), k]
          gather_points_fea = self.agg_projector_list[stage_i](
              gather_points_fea
          )  # [B*npoint, d, k]
          # pdb.set_trace()
          batch_size, new_dim, _ = gather_points_fea.size()
          gather_points_fea = self.pooler_list[stage_i](
              gather_points_fea
          ).view(
              batch_size, new_dim
          )  # [B*npoint, d]
          # gather_points_fea = F.adaptive_max_pool1d(gather_points_fea, 1).view(batch_size, -1) # [B*npoint, d]
          # pdb.set_trace()
          gather_points_fea = gather_points_fea.reshape(
              b, n, -1
          )  # [B, npoint, d]
          # pdb.set_trace()
  
          all_points = new_points
          all_points_fea = gather_points_fea
  
      # pdb.set_trace()
      x = all_points_fea.flatten(1, -1)  # [B, npoint x d]
      x = self.flatten_projector(x)
      all_region_fea = self.dim_projector(x)  # [B, d]
  
      output_region_fea = []
      for img_idx in range(len(region_masks)):
          cur_mask = all_points_img_ids == img_idx
          # pdb.set_trace()
          if not cur_mask.any():
              output_region_fea.append(None)
          else:
              output_region_fea.append(all_region_fea[cur_mask])
  
      # pdb.set_trace()
      return output_region_fea
  
imports: from abc import ABC, abstractmethod
  import torch
  import torch.nn
  import torch.nn.functional
  import math
  from .multimodal_encoder.builder import build_vision_tower
  import pdb
  from ferret.constants import IGNORE_INDEX, IMAGE_TOKEN_INDEX, DEFAULT_IMAGE_PATCH_TOKEN, DEFAULT_IM_START_TOKEN, DEFAULT_IM_END_TOKEN
label_desc: Use image node_id 3 for calling the GeoRegionSampler obj's underlying member method code with example usage: obj.forward(feature_map, region_masks, original_dtype, return_dtype) and returns: output_region_fea, unknown