U
    h,                  
   @   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eeeee f ee eeeed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                     s.   t jf }t|t j< || |S N)torchcompile	functoolswrapsglobals__name__)argskwargsZcompiled_fn)compile_kwargsfn K/var/www/html/venv/lib/python3.8/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 k	rTd k	st 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)AssertionErrorr   wherearanger%   yxZ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+   r0   r/   _heightwidthZy_lowZx_lowZy_highZx_highZlylxhyhxr1   Zv1Zv2Zv3Zv4r2   Zw1Zw2Zw3Zw4valr   r,   r   _bilinear_interpolate#   s6    







 r?   c                 C   s*   t  r"| jr"| jt jkr"|  S | S d S r   )r   Zis_autocast_enabledis_cudar7   doublefloat)Ztensorr   r   r   
maybe_caste   s    rC   T)Zdynamicc           $   
   C   s:  | j }t| } t|}|  \}}}	}
tj|| jd}tj|| jd}|d d df  }|rbdnd}|d d df | | }|d d df | | }|d d df | | }|d d df | | }|| }|| }|stj|d	d
}tj|d	d
}|| }|| }|dk}|r|nt|| }|r0|nt|| }|r|t	|| d}tj|| jd}tj|| jd}d }d }nrt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| || |!||}"|st|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))r7   rC   r3   r   r(   r%   r5   r4   ceilmaxr6   r?   r'   sum
isinstancer   )$r-   roisspatial_scaleZpooled_heightZpooled_widthsampling_ratioalignedZ
orig_dtyper8   r9   r:   phpwr.   offsetZroi_start_wZroi_start_hZ	roi_end_wZ	roi_end_hZ	roi_widthZ
roi_heightZ
bin_size_hZ
bin_size_wZexact_samplingZroi_bin_grid_hZroi_bin_grid_wcountZiyZixr0   r/   rG   r*   r+   r>   outputr   r   r   
_roi_alignr   sp      ((&&

rW   r#   rH   F)r-   boxesoutput_sizerO   rP   rQ   returnc              	   C   s   t j st j stt t| |}t|}t|t j	sDt
|}t j st rht  r| jsh| jrt| jjrt| |||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   ZjitZis_scripting
is_tracingr   	roi_alignr   r   rM   r   r   r
   Z$are_deterministic_algorithms_enabledr@   Zis_mpsr   r%   typerW   r	   ZopsZtorchvision)r-   rX   rY   rO   rP   rQ   rN   r   r   r   r\      s:    )

      r\   c                       s^   e Zd ZdZdee eeed fddZe	e
e	ee	 f e	dddZed	d
dZ  ZS )RoIAlignz 
    See :func:`roi_align`.
    F)rY   rO   rP   rQ   c                    s.   t    t|  || _|| _|| _|| _d S r   )super__init__r   rY   rO   rP   rQ   )selfrY   rO   rP   rQ   	__class__r   r   r`     s    
zRoIAlign.__init__)r-   rN   rZ   c                 C   s   t ||| j| j| j| jS r   )r\   rY   rO   rP   rQ   )ra   r-   rN   r   r   r   forward  s    zRoIAlign.forward)rZ   c              
   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=))rc   r   rY   rO   rP   rQ   )ra   sr   r   r   __repr__  s    ,zRoIAlign.__repr__)F)r   
__module____qualname____doc__r   r5   rB   boolr`   r   r   r   rd   strrg   __classcell__r   r   rb   r   r^     s   	 r^   )r#   rH   F)"r   typingr   r   r   Ztorch.fxr   r   Ztorch._dynamo.utilsr   Ztorch.jit.annotationsr   Ztorch.nn.modules.utilsr   Ztorchvision.extensionr	   r
   utilsr   Z_utilsr   r   r    r?   rC   rW   Zfxwrapr5   rB   rk   r\   Moduler^   r   r   r   r   <module>   s:   B
X   :