docs: def project_masks_on_boxes(segmentation_masks, proposals, discretization_size):
      """
      Given segmentation masks and the bounding boxes corresponding
      to the location of the masks in the image, this function
      crops and resizes the masks in the position defined by the
      boxes. This prepares the masks for them to be fed to the
      loss computation as the targets.
  
      Arguments:
          segmentation_masks: an instance of SegmentationMask
          proposals: an instance of BoxList
      """
      masks = []
      M = discretization_size
      device = proposals.bbox.device
      proposals = proposals.convert("xyxy")
      assert segmentation_masks.size == proposals.size, "{}, {}".format(
          segmentation_masks, proposals
      )
      # TODO put the proposals on the CPU, as the representation for the
      # masks is not efficient GPU-wise (possibly several small tensors for
      # representing a single instance mask)
      proposals = proposals.bbox.to(torch.device("cpu"))
      for segmentation_mask, proposal in zip(segmentation_masks, proposals):
          # crop the masks, resize them to the desired resolution and
          # then convert them to the tensor representation,
          # instead of the list representation that was used
          cropped_mask = segmentation_mask.crop(proposal)
          scaled_mask = cropped_mask.resize((M, M))
          mask = scaled_mask.convert(mode="mask")
          masks.append(mask)
      if len(masks) == 0:
          return torch.empty(0, dtype=torch.float32, device=device)
      return torch.stack(masks, dim=0).to(device, dtype=torch.float32)