o
    Vh8,                     @   s  d dl Z d dlmZmZ d dlZd dlZd dlmZmZ d dlm	Z	 d dl
mZ d dlmZ d dlmZmZ dd	lmZ d
dlmZmZ dd Zdd Zdd Zedddd Zejj			d$dedeeee f dee dedededefd d!ZG d"d# d#ej Z!dS )%    N)ListUnion)nnTensor)is_compile_supported)BroadcastingList2)_pair)_assert_has_ops_has_ops   )_log_api_usage_once   )check_roi_boxes_shapeconvert_boxes_to_roi_formatc                     s    fdd}|S )zkLazily wrap a function with torch.compile on the first call

    This avoids eagerly importing dynamo.
    c                    s   t   fdd}|S )Nc                     s6   t jfi  }t|t j< || i |S N)torchcompile	functoolswrapsglobals__name__)argskwargscompiled_fn)compile_kwargsfn M/var/www/vscode/kcb/lib/python3.10/site-packages/torchvision/ops/roi_align.pycompile_hook   s   z7lazy_compile.<locals>.decorate_fn.<locals>.compile_hook)r   r   )r   r   r   )r   r   decorate_fn   s   z!lazy_compile.<locals>.decorate_fnr   )r   r    r   r   r   lazy_compile   s   	r!   c                    s    \} }}|jdd}|jdd}| }	| }
t|	|d k|d |	d }t|	|d k|d |	}	t|	|d k|j|}t|
|d k|d |
d }t|
|d k|d |
}
t|
|d k|j|}||	 }||
 }d| }d| } fdd}||	|
}||	|}|||
}|||}dd }|||}|||}|||}|||}|| ||  ||  ||  }|S )	Nr   minr         ?c                    s   d ur*d us
J t d d d d d f | d} t d d d d d f |d}d d d d d d d f t j jdd d d d d d d f | d d d d d d d d d f |d d d d d d d d d f f S )Nr   device)r   wherearanger&   yxchannelsinputroi_batch_indxmaskymaskr   r   masked_indexB   s     "z+_bilinear_interpolate.<locals>.masked_indexc              	   S   s@   | d d d d d d d d d f |d d d d d d d d d f  S r   r   r)   r   r   r   
outer_prodW   s   @z)_bilinear_interpolate.<locals>.outer_prod)sizeclampintr   r'   todtype)r.   r/   r*   r+   r1   r0   _heightwidthy_lowx_lowy_highx_highlylxhyhxr2   v1v2v3v4r3   w1w2w3w4valr   r,   r   _bilinear_interpolate#   s6   







 rM   c                 C   s&   t  r| jr| jt jkr|  S | S r   )r   is_autocast_enabledis_cudar8   doublefloat)tensorr   r   r   
maybe_caste   s   rS   T)dynamicc           $   
   C   s6  | j }t| } t|}|  \}}}	}
tj|| jd}tj|| jd}|d d df  }|r1dnd}|d d df | | }|d d df | | }|d d df | | }|d d df | | }|| }|| }|s{tj|d	d
}tj|d	d
}|| }|| }|dk}|r|nt|| }|r|nt|| }	 |rt	|| d}tj|| jd}tj|| jd}d }d }n9tj|| dd
}tj|	| jd}tj|
| jd}|d d d f |d d d f k }|d d d f |d d d f k }dd }|||d d d d f ||  |d d d d f d 
| j |||   } |||d d d d f ||  |d d d d f d 
| j |||   }!t| || |!||}"|swt|d d d d d d d d f |"d}"t|d d d d d d d d f |"d}"|"d}#t|tjr|#|d d d d d f  }#n|#| }#|#
|}#|#S )Nr%   r   g      ?g        r   r         r$   r"   c                 S   s   | d d d d f S r   r   )tr   r   r   from_K   s   z_roi_align.<locals>.from_K))r8   rS   r4   r   r(   r&   r6   r5   ceilmaxr7   rM   r'   sum
isinstancer   )$r.   roisspatial_scalepooled_heightpooled_widthsampling_ratioaligned
orig_dtyper9   r:   r;   phpwr/   offsetroi_start_wroi_start_h	roi_end_w	roi_end_h	roi_width
roi_height
bin_size_h
bin_size_wexact_samplingroi_bin_grid_hroi_bin_grid_wcountiyixr1   r0   rX   r*   r+   rL   outputr   r   r   
_roi_alignr   sr     ((&&

rx   r$   rY   Fr.   boxesoutput_sizer`   rc   rd   returnc              	   C   s   t j st j stt t| |}t|}t|t j	s"t
|}t j sKt r7t  rK| js7| js7| jrKt| jjrKt| |||d |d ||S t  t jj| |||d |d ||S )aj  
    Performs Region of Interest (RoI) Align operator with average pooling, as described in Mask R-CNN.

    Args:
        input (Tensor[N, C, H, W]): The input tensor, i.e. a batch with ``N`` elements. Each element
            contains ``C`` feature maps of dimensions ``H x W``.
            If the tensor is quantized, we expect a batch size of ``N == 1``.
        boxes (Tensor[K, 5] or List[Tensor[L, 4]]): the box coordinates in (x1, y1, x2, y2)
            format where the regions will be taken from.
            The coordinate must satisfy ``0 <= x1 < x2`` and ``0 <= y1 < y2``.
            If a single Tensor is passed, then the first column should
            contain the index of the corresponding element in the batch, i.e. a number in ``[0, N - 1]``.
            If a list of Tensors is passed, then each Tensor will correspond to the boxes for an element i
            in the batch.
        output_size (int or Tuple[int, int]): the size of the output (in bins or pixels) after the pooling
            is performed, as (height, width).
        spatial_scale (float): a scaling factor that maps the box coordinates to
            the input coordinates. For example, if your boxes are defined on the scale
            of a 224x224 image and your input is a 112x112 feature map (resulting from a 0.5x scaling of
            the original image), you'll want to set this to 0.5. Default: 1.0
        sampling_ratio (int): number of sampling points in the interpolation grid
            used to compute the output value of each pooled output bin. If > 0,
            then exactly ``sampling_ratio x sampling_ratio`` sampling points per bin are used. If
            <= 0, then an adaptive number of grid points are used (computed as
            ``ceil(roi_width / output_width)``, and likewise for height). Default: -1
        aligned (bool): If False, use the legacy implementation.
            If True, pixel shift the box coordinates it by -0.5 for a better alignment with the two
            neighboring pixel indices. This version is used in Detectron2

    Returns:
        Tensor[K, C, output_size[0], output_size[1]]: The pooled RoIs.
    r   r   )r   jitis_scripting
is_tracingr   	roi_alignr   r   r^   r   r   r
   $are_deterministic_algorithms_enabledrO   is_mpsis_xpur   r&   typerx   r	   opstorchvision)r.   ry   rz   r`   rc   rd   r_   r   r   r   r      s2   )

r   c                	       sj   e Zd ZdZ	ddee dededef fddZd	e	d
e
e	ee	 f de	fddZdefddZ  ZS )RoIAlignz 
    See :func:`roi_align`.
    Frz   r`   rc   rd   c                    s.   t    t|  || _|| _|| _|| _d S r   )super__init__r   rz   r`   rc   rd   )selfrz   r`   rc   rd   	__class__r   r   r     s   

zRoIAlign.__init__r.   r_   r{   c                 C   s   t ||| j| j| j| jS r   )r   rz   r`   rc   rd   )r   r.   r_   r   r   r   forward  s   zRoIAlign.forwardc              
   C   s2   | j j d| j d| j d| j d| j d
}|S )Nz(output_size=z, spatial_scale=z, sampling_ratio=z
, aligned=))r   r   rz   r`   rc   rd   )r   sr   r   r   __repr__  s   
zRoIAlign.__repr__)F)r   
__module____qualname____doc__r   r6   rQ   boolr   r   r   r   r   strr   __classcell__r   r   r   r   r     s    	"r   )r$   rY   F)"r   typingr   r   r   torch.fxr   r   torch._dynamo.utilsr   torch.jit.annotationsr   torch.nn.modules.utilsr   torchvision.extensionr	   r
   utilsr   _utilsr   r   r!   rM   rS   rx   fxwrapr6   rQ   r   r   Moduler   r   r   r   r   <module>   sH    B
X;