Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions torchvision/ops/boxes.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from torch import Tensor
from torchvision.extension import _assert_has_ops

from ..utils import _log_api_usage_once
from ._box_convert import _box_cxcywh_to_xyxy, _box_xyxy_to_cxcywh, _box_xywh_to_xyxy, _box_xyxy_to_xywh


Expand Down Expand Up @@ -33,6 +34,7 @@ def nms(boxes: Tensor, scores: Tensor, iou_threshold: float) -> Tensor:
Tensor: int64 tensor with the indices of the elements that have been kept
by NMS, sorted in decreasing order of scores
"""
_log_api_usage_once("torchvision.ops.nms")
_assert_has_ops()
return torch.ops.torchvision.nms(boxes, scores, iou_threshold)

Expand Down Expand Up @@ -61,6 +63,7 @@ def batched_nms(
Tensor: int64 tensor with the indices of the elements that have been kept by NMS, sorted
in decreasing order of scores
"""
_log_api_usage_once("torchvision.ops.batched_nms")
# Benchmarks that drove the following thresholds are at
# https://github.com/pytorch/vision/issues/1311#issuecomment-781329339
# Ideally for GPU we'd use a higher threshold
Expand Down Expand Up @@ -120,6 +123,7 @@ def remove_small_boxes(boxes: Tensor, min_size: float) -> Tensor:
Tensor[K]: indices of the boxes that have both sides
larger than min_size
"""
_log_api_usage_once("torchvision.ops.remove_small_boxes")
ws, hs = boxes[:, 2] - boxes[:, 0], boxes[:, 3] - boxes[:, 1]
keep = (ws >= min_size) & (hs >= min_size)
keep = torch.where(keep)[0]
Expand All @@ -138,6 +142,7 @@ def clip_boxes_to_image(boxes: Tensor, size: Tuple[int, int]) -> Tensor:
Returns:
Tensor[N, 4]: clipped boxes
"""
_log_api_usage_once("torchvision.ops.clip_boxes_to_image")
dim = boxes.dim()
boxes_x = boxes[..., 0::2]
boxes_y = boxes[..., 1::2]
Expand Down Expand Up @@ -178,6 +183,7 @@ def box_convert(boxes: Tensor, in_fmt: str, out_fmt: str) -> Tensor:
Tensor[N, 4]: Boxes into converted format.
"""

_log_api_usage_once("torchvision.ops.box_convert")
allowed_fmts = ("xyxy", "xywh", "cxcywh")
if in_fmt not in allowed_fmts or out_fmt not in allowed_fmts:
raise ValueError("Unsupported Bounding Box Conversions for given in_fmt and out_fmt")
Expand Down Expand Up @@ -227,6 +233,7 @@ def box_area(boxes: Tensor) -> Tensor:
Returns:
Tensor[N]: the area for each box
"""
_log_api_usage_once("torchvision.ops.box_area")
boxes = _upcast(boxes)
return (boxes[:, 2] - boxes[:, 0]) * (boxes[:, 3] - boxes[:, 1])

Expand Down Expand Up @@ -262,6 +269,7 @@ def box_iou(boxes1: Tensor, boxes2: Tensor) -> Tensor:
Returns:
Tensor[N, M]: the NxM matrix containing the pairwise IoU values for every element in boxes1 and boxes2
"""
_log_api_usage_once("torchvision.ops.box_iou")
inter, union = _box_inter_union(boxes1, boxes2)
iou = inter / union
return iou
Expand All @@ -284,6 +292,7 @@ def generalized_box_iou(boxes1: Tensor, boxes2: Tensor) -> Tensor:
for every element in boxes1 and boxes2
"""

_log_api_usage_once("torchvision.ops.generalized_box_iou")
# degenerate boxes gives inf / nan results
# so do an early check
assert (boxes1[:, 2:] >= boxes1[:, :2]).all()
Expand Down Expand Up @@ -315,6 +324,7 @@ def masks_to_boxes(masks: torch.Tensor) -> torch.Tensor:
Returns:
Tensor[N, 4]: bounding boxes
"""
_log_api_usage_once("torchvision.ops.masks_to_boxes")
if masks.numel() == 0:
return torch.zeros((0, 4), device=masks.device, dtype=torch.float)

Expand Down
3 changes: 3 additions & 0 deletions torchvision/ops/deform_conv.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@
from torch.nn.parameter import Parameter
from torchvision.extension import _assert_has_ops

from ..utils import _log_api_usage_once


def deform_conv2d(
input: Tensor,
Expand Down Expand Up @@ -59,6 +61,7 @@ def deform_conv2d(
>>> torch.Size([4, 5, 8, 8])
"""

_log_api_usage_once("torchvision.ops.deform_conv2d")
_assert_has_ops()
out_channels = weight.shape[0]

Expand Down
3 changes: 3 additions & 0 deletions torchvision/ops/feature_pyramid_network.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
import torch.nn.functional as F
from torch import nn, Tensor

from ..utils import _log_api_usage_once


class ExtraFPNBlock(nn.Module):
"""
Expand Down Expand Up @@ -75,6 +77,7 @@ def __init__(
extra_blocks: Optional[ExtraFPNBlock] = None,
):
super().__init__()
_log_api_usage_once(self)
self.inner_blocks = nn.ModuleList()
self.layer_blocks = nn.ModuleList()
for in_channels in in_channels_list:
Expand Down
3 changes: 3 additions & 0 deletions torchvision/ops/focal_loss.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import torch
import torch.nn.functional as F

from ..utils import _log_api_usage_once


def sigmoid_focal_loss(
inputs: torch.Tensor,
Expand Down Expand Up @@ -30,6 +32,7 @@ def sigmoid_focal_loss(
Returns:
Loss tensor with the reduction option applied.
"""
_log_api_usage_once("torchvision.ops.sigmoid_focal_loss")
p = torch.sigmoid(inputs)
ce_loss = F.binary_cross_entropy_with_logits(inputs, targets, reduction="none")
p_t = p * targets + (1 - p) * (1 - targets)
Expand Down
5 changes: 5 additions & 0 deletions torchvision/ops/misc.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@
import torch
from torch import Tensor

from ..utils import _log_api_usage_once


class Conv2d(torch.nn.Conv2d):
def __init__(self, *args, **kwargs):
Expand Down Expand Up @@ -66,6 +68,7 @@ def __init__(
warnings.warn("`n` argument is deprecated and has been renamed `num_features`", DeprecationWarning)
num_features = n
super().__init__()
_log_api_usage_once(self)
self.eps = eps
self.register_buffer("weight", torch.ones(num_features))
self.register_buffer("bias", torch.zeros(num_features))
Expand Down Expand Up @@ -138,6 +141,7 @@ def __init__(
if activation_layer is not None:
layers.append(activation_layer(inplace=inplace))
super().__init__(*layers)
_log_api_usage_once(self)
self.out_channels = out_channels


Expand All @@ -150,6 +154,7 @@ def __init__(
scale_activation: Callable[..., torch.nn.Module] = torch.nn.Sigmoid,
) -> None:
super().__init__()
_log_api_usage_once(self)
self.avgpool = torch.nn.AdaptiveAvgPool2d(1)
self.fc1 = torch.nn.Conv2d(input_channels, squeeze_channels, 1)
self.fc2 = torch.nn.Conv2d(squeeze_channels, input_channels, 1)
Expand Down
2 changes: 2 additions & 0 deletions torchvision/ops/poolers.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
from torch import nn, Tensor
from torchvision.ops.boxes import box_area

from ..utils import _log_api_usage_once
from .roi_align import roi_align


Expand Down Expand Up @@ -130,6 +131,7 @@ def __init__(
canonical_level: int = 4,
):
super().__init__()
_log_api_usage_once(self)
if isinstance(output_size, int):
output_size = (output_size, output_size)
self.featmap_names = featmap_names
Expand Down
2 changes: 2 additions & 0 deletions torchvision/ops/ps_roi_align.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from torch.nn.modules.utils import _pair
from torchvision.extension import _assert_has_ops

from ..utils import _log_api_usage_once
from ._utils import convert_boxes_to_roi_format, check_roi_boxes_shape


Expand Down Expand Up @@ -42,6 +43,7 @@ def ps_roi_align(
Returns:
Tensor[K, C / (output_size[0] * output_size[1]), output_size[0], output_size[1]]: The pooled RoIs
"""
_log_api_usage_once("torchvision.ops.ps_roi_align")
_assert_has_ops()
check_roi_boxes_shape(boxes)
rois = boxes
Expand Down
2 changes: 2 additions & 0 deletions torchvision/ops/ps_roi_pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from torch.nn.modules.utils import _pair
from torchvision.extension import _assert_has_ops

from ..utils import _log_api_usage_once
from ._utils import convert_boxes_to_roi_format, check_roi_boxes_shape


Expand Down Expand Up @@ -36,6 +37,7 @@ def ps_roi_pool(
Returns:
Tensor[K, C / (output_size[0] * output_size[1]), output_size[0], output_size[1]]: The pooled RoIs.
"""
_log_api_usage_once("torchvision.ops.ps_roi_pool")
_assert_has_ops()
check_roi_boxes_shape(boxes)
rois = boxes
Expand Down
2 changes: 2 additions & 0 deletions torchvision/ops/roi_align.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from torch.nn.modules.utils import _pair
from torchvision.extension import _assert_has_ops

from ..utils import _log_api_usage_once
from ._utils import convert_boxes_to_roi_format, check_roi_boxes_shape


Expand Down Expand Up @@ -49,6 +50,7 @@ def roi_align(
Returns:
Tensor[K, C, output_size[0], output_size[1]]: The pooled RoIs.
"""
_log_api_usage_once("torchvision.ops.roi_align")
_assert_has_ops()
check_roi_boxes_shape(boxes)
rois = boxes
Expand Down
2 changes: 2 additions & 0 deletions torchvision/ops/roi_pool.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from torch.nn.modules.utils import _pair
from torchvision.extension import _assert_has_ops

from ..utils import _log_api_usage_once
from ._utils import convert_boxes_to_roi_format, check_roi_boxes_shape


Expand Down Expand Up @@ -38,6 +39,7 @@ def roi_pool(
Returns:
Tensor[K, C, output_size[0], output_size[1]]: The pooled RoIs.
"""
_log_api_usage_once("torchvision.ops.roi_pool")
_assert_has_ops()
check_roi_boxes_shape(boxes)
rois = boxes
Expand Down
3 changes: 3 additions & 0 deletions torchvision/ops/stochastic_depth.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
import torch.fx
from torch import nn, Tensor

from ..utils import _log_api_usage_once


def stochastic_depth(input: Tensor, p: float, mode: str, training: bool = True) -> Tensor:
"""
Expand All @@ -21,6 +23,7 @@ def stochastic_depth(input: Tensor, p: float, mode: str, training: bool = True)
Returns:
Tensor[N, ...]: The randomly zeroed tensor.
"""
_log_api_usage_once("torchvision.ops.stochastic_depth")
if p < 0.0 or p > 1.0:
raise ValueError(f"drop probability has to be between 0 and 1, but got {p}")
if mode not in ["batch", "row"]:
Expand Down
14 changes: 11 additions & 3 deletions torchvision/utils.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import math
import pathlib
import warnings
from typing import Union, Optional, List, Tuple, BinaryIO
from typing import Union, Optional, List, Tuple, BinaryIO, no_type_check

import numpy as np
import torch
Expand Down Expand Up @@ -305,5 +305,13 @@ def _generate_color_palette(num_masks: int):
return [tuple((i * palette) % 255) for i in range(num_masks)]


def _log_api_usage_once(obj: object) -> None:
torch._C._log_api_usage_once(f"{obj.__module__}.{obj.__class__.__name__}")
@no_type_check
def _log_api_usage_once(obj: str) -> None: # type: ignore
if torch.jit.is_scripting() or torch.jit.is_tracing():
return
# NOTE: obj can be an object as well, but mocking it here to be
# only a string to appease torchscript
if isinstance(obj, str):
torch._C._log_api_usage_once(obj)
else:
torch._C._log_api_usage_once(f"{obj.__module__}.{obj.__class__.__name__}")