Ë
    ëÓ^j8  ã                   ó  — d Z ddlmZ ddlmZmZ ddlZddlZddlmZ de	de	de	fd	„Z
d
eee	      dee	   fd„Z G d„ d«      Z	 ddee   de	dz  defd„Zej                  j                   	 ddee   de	dz  defd„«       Z	 	 ddej                  dej                  dededej                  f
d„Z	 ddeeedf      de	dz  deedf   fd„Zdeeedf      deedf   fd„Z	 dde	dz  deeeedf      geedf   f   fd„Zy)z8Tensor utilities: NestedTensor, collate_fn, and helpers.é    )Úpartial)ÚAnyÚCallableN)ÚTensorÚvalueÚmultipleÚreturnc                 ój   — | dk  rt        d| › �«      ‚|dk  rt        d|› �«      ‚| |z   dz
  |z  |z  S )an  Round *value* up to the next multiple of *multiple*.

    Args:
        value: Non-negative integer to round.
        multiple: Positive integer divisor.

    Returns:
        The smallest integer greater than or equal to *value* that is an exact multiple of *multiple*.

    Raises:
        ValueError: If ``value`` is negative or ``multiple`` is not positive.
    r   z value must be non-negative, got z)multiple must be a positive integer, got é   )Ú
ValueError)r   r   s     úc/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/rfdetr/utilities/tensors.pyÚ_round_up_to_multipler      sR   € ð ˆq‚yÜÐ;¸E¸7ÐCÓDÐDØ�1‚}ÜÐDÀXÀJÐOÓPÐPØ�XÑ Ñ! hÑ.°(Ñ:Ð:ó    Úthe_listc                 ón   — | d   }| dd D ]'  }t        |«      D ]  \  }}t        ||   |«      ||<   Œ Œ) |S )z¶Return element-wise maximums of a list of lists.

    Args:
        the_list: List of integer lists, all of the same length.

    Returns:
        List of per-position maximums.
    r   r   N)Ú	enumerateÚmax)r   ÚmaxesÚsublistÚindexÚitems        r   Ú_max_by_axisr   +   sU   € ð �Q‰K€EØ˜A˜B�<ò 3ˆÜ$ WÓ-ò 	3‰KˆE�4Ü˜u U™|¨TÓ2ˆE�%ŠLñ	3ð3ð €Lr   c                   ó‚   — e Zd ZdZdededz  ddfd„Zdej                  dedd fd	„Z	dd
„Z
deeedz  f   fd„Zdefd„Zy)ÚNestedTensorzŸBatch of tensors with variable spatial sizes, padded to a common size.

    Stores both the padded tensor and a boolean mask indicating padding positions.
    ÚtensorsÚmaskNr	   c                 ó    — || _         || _        y ©N©r   r   )Úselfr   r   s      r   Ú__init__zNestedTensor.__init__A   s   € ØˆŒØˆ�	r   ÚdeviceÚkwargsc                 ó¤   —  | j                   j                  |fi |¤Ž}| j                  }|�|€J ‚ |j                  |fi |¤Ž}nd}t        ||«      S )zÔMove tensors and mask to *device*.

        Args:
            device: Target device. **kwargs: Additional arguments forwarded to ``Tensor.to``.

        Returns:
            New NestedTensor on *device*.
        N)r   Útor   r   )r    r"   r#   Úcast_tensorr   Ú	cast_masks         r   r%   zNestedTensor.toE   s_   € ð &�d—l‘l—o‘o fÑ7°Ñ7ˆØ�y‰yˆØÐØÐ#Ð#Ð#Ø˜Ÿ™ Ñ1¨&Ñ1‰IàˆIÜ˜K¨Ó3Ð3r   c                 óž   — t        | j                  j                  «       | j                  �| j                  j                  «       «      S d«      S )u…   Pin tensor and mask memory for faster CPUâ†’GPU transfer.

        Returns:
            New NestedTensor with pinned memory.
        N)r   r   Ú
pin_memoryr   ©r    s    r   r)   zNestedTensor.pin_memoryW   sG   € ô Ø�L‰L×#Ñ#Ó%Ø&*§i¡iÐ&;ˆD�I‰I× Ñ Ó"ó
ð 	
àAEó
ð 	
r   c                 ó2   — | j                   | j                  fS )zyReturn ``(tensors, mask)`` tuple.

        Returns:
            Tuple of the padded tensor and the boolean mask.
        r   r*   s    r   Ú	decomposezNestedTensor.decomposeb   s   € ð �|‰|˜TŸY™YÐ&Ð&r   c                 ó,   — t        | j                  «      S r   )Ústrr   r*   s    r   Ú__repr__zNestedTensor.__repr__j   s   € Ü�4—<‘<Ó Ð r   )r	   r   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r!   Útorchr"   r   r%   r)   Útupler,   r.   r/   © r   r   r   r   ;   sn   „ ñð
 ð ¨f°t©mð Àó ð4˜Ÿ™ð 4°ð 4¸ó 4ó$	
ð'˜5 ¨°$©Ð!6Ñ7ó 'ð!˜#ô !r   r   Útensor_listÚ
block_sizec                 ó0  — | d   j                   dk(  �rht        j                  «       rt        | |¬«      S t	        | D �cg c]  }t        |j                  «      ‘Œ c}«      }|�$t        |d   |«      |d<   t        |d   |«      |d<   t        | «      g|z   }|\  }}}}| d   j                  }	| d   j                  }
t        j                  ||	|
¬«      }t        j                  |||ft        j                  |
¬«      }t        | ||«      D ]o  \  }}}|d|j                  d   …d|j                  d   …d|j                  d   …f   j!                  |«       d|d|j                  d   …d|j                  d   …f<   Œq nt#        d	«      ‚t%        ||«      S c c}w )
a°  Pad a list of variable-size tensors into a single NestedTensor.

    Args:
        tensor_list: List of 3-D tensors (C, H, W) with possibly different H, W.
        block_size: When set, round the padded ``H`` and ``W`` up to the next
            multiple of *block_size* before allocating the batch tensor.  Used to satisfy backbone divisibility
            requirements (e.g. windowed-attention backbones require ``H % (patch_size * num_windows) == 0``).  The
            rounded-up strip is explicitly tracked in the ``mask`` as padding.

    Returns:
        NestedTensor with all images padded to the maximum spatial dimensions (rounded up to *block_size* when
        provided).
    r   é   ©r8   Nr   é   ©Údtyper"   Fznot supported)ÚndimÚtorchvisionÚ_is_tracingÚ$_onnx_nested_tensor_from_tensor_listr   ÚlistÚshaper   Úlenr>   r"   r4   ÚzerosÚonesÚboolÚzipÚcopy_r   r   )r7   r8   ÚimgÚmax_sizeÚbatch_shapeÚbÚcÚhÚwr>   r"   Útensorr   Úpad_imgÚms                  r   Únested_tensor_from_tensor_listrU   n   s�  € ð$ �1�~×Ñ˜aÓÜ×"Ñ"Ô$ô 8¸ÐPZÔ[Ð[ô  ¸KÖ H°S¤ c§i¡i¥Ò HÓIˆØÐ!Ü/°¸±¸ZÓHˆH�Q‰KÜ/°¸±¸ZÓHˆH�Q‰Kä˜;Ó'Ð(¨8Ñ3ˆØ ‰
ˆˆ1ˆa�Ø˜A‘×$Ñ$ˆØ˜Q‘×&Ñ&ˆÜ—‘˜[°¸fÔEˆÜ�z‰z˜1˜a ˜)¬5¯:©:¸fÔEˆÜ" ;°¸Ó=ò 	6‰OˆC�˜!Ø�N�c—i‘i ‘l�N N c§i¡i°¡l N°N°c·i±iÀ±l°NÐBÑC×IÑIÈ#ÔNØ05ˆAˆn�—	‘	˜!‘ˆn˜n §	¡	¨!¡˜nÐ,Ò-ñ	6ô ˜Ó)Ð)Ü˜ Ó%Ð%ùò! !Is   ¾Fc                 óà  — g }t        | d   j                  «       «      D ]�  }t        j                  t        j                  | D �cg c]  }|j
                  |   ‘Œ c}«      j                  t        j                  «      «      j                  t        j                  «      }|j                  |«       Œ’ |�Mt        j                  |t        j                  ¬«      }|d   |z   dz
  |z  |z  |d<   |d   |z   dz
  |z  |z  |d<   t        |«      }g }g }| D �]  }t        |t        |j
                  «      «      D �	�
cg c]
  \  }	}
|	|
z
  ‘Œ }}	}
t        j                  j                  j                  |d|d   d|d   d|d   f«      }|j                  |«       t        j                   |d   t        j"                  |j$                  ¬«      }t        j                  j                  j                  |d|d   d|d   fdd«      }|j                  |j                  t        j&                  «      «       �Œ t        j                  |«      }t        j                  |«      }t)        ||¬«      S c c}w c c}
}	w )aq  ONNX-tracing-compatible variant of ``nested_tensor_from_tensor_list``.

    Args:
        tensor_list: List of 3-D tensors (C, H, W).
        block_size: When set, round ``H`` and ``W`` up to the next multiple of
            this value before padding.  See :func:`nested_tensor_from_tensor_list`.

    Returns:
        Padded NestedTensor suitable for ONNX export.
    r   )r>   r   r<   r=   Úconstant)r   )ÚrangeÚdimr4   r   ÚstackrD   r%   Úfloat32Úint64ÚappendÚ	as_tensorr5   rI   ÚnnÚ
functionalÚpadÚ
zeros_likeÚintr"   rH   r   )r7   r8   rL   ÚirK   Ú
max_size_iÚbsÚpadded_imgsÚpadded_masksÚs1Ús2ÚpaddingÚ
padded_imgrT   Úpadded_maskrR   r   s                    r   rB   rB   œ   s  € ð €HÜ�;˜q‘>×%Ñ%Ó'Ó(ò $ˆÜ—Y‘YœuŸ{™{ÀKÖ+P¸S¨C¯I©I°a«LÒ+PÓQ×TÑTÔUZ×UbÑUbÓcÓd×gÑgÔhm×hsÑhsÓtˆ
Ø�‰˜
Õ#ð$ð Ðä�_‰_˜Z¬u¯{©{Ô;ˆØ  ™ bÑ(¨1Ñ,°Ñ3°rÑ9ˆ�‰Ø  ™ bÑ(¨1Ñ,°Ñ3°rÑ9ˆ�‰Ü�X‹€Hð €KØ€LØó 8ˆÜ+.¨x¼¸s¿y¹yÓ9IÓ+J×K¡  R�B˜“GÐKˆÑKÜ—X‘X×(Ñ(×,Ñ,¨S°1°g¸a±jÀ!ÀWÈQÁZÐQRÐT[Ð\]ÑT^Ð2_Ó`ˆ
Ø×Ñ˜:Ô&ä×Ñ˜S ™V¬5¯9©9¸S¿Z¹ZÔHˆÜ—h‘h×)Ñ)×-Ñ-¨a°!°W¸Q±ZÀÀGÈAÁJÐ1OÐQ[Ð]^Ó_ˆØ×Ñ˜KŸN™N¬5¯:©:Ó6Ö7ð8ô �[‰[˜Ó%€FÜ�;‰;�|Ó$€Dä˜ TÔ*Ð*ùò7 ,Qùó  Ls   ÁI%Ä8I*ÚinputÚgridÚpadding_modeÚalign_cornersc                 óà  ‡‡‡‡‡‡ — ddl mc m} | j                  j                  dk7  r|j                  | |d||¬«      S |dvrd|›d�}t        |«      ‚| j                  \  ŠŠ}Š |j                  d	   |j                  d
   cŠŠ|r#|d   d	z   ‰ d	z
  z  d
z  }|d   d	z   |d	z
  z  d
z  }n"|d   d	z   ‰ z  d
z  dz
  }|d   d	z   |z  d
z  dz
  }|j                  «       j                  «       }	|j                  «       j                  «       }
|	d	z   }|
d	z   }||	j                  «       z
  j                  | j                  «      j                  d	«      }||
j                  «       z
  j                  | j                  «      j                  d	«      }|j                  d«      }||z
  }||z
  }|dk(  rU|	j                  d‰ d	z
  «      }	|
j                  d|d	z
  «      }
|j                  d‰ d	z
  «      }|j                  d|d	z
  «      }n€|	dk\  |	‰ k  z  }|dk\  |‰ k  z  }|
dk\  |
|k  z  }|dk\  ||k  z  }|	j                  d‰ d	z
  «      }	|
j                  d|d	z
  «      }
|j                  d‰ d	z
  «      }|j                  d|d	z
  «      }| j!                  d
«      Šdt"        j$                  dt"        j$                  dt"        j$                  fˆˆˆˆˆˆ fd„} ||
|	«      } ||
|«      } |||	«      } |||«      }|dk(  r\|z  j                  d	«      z  }||z  j                  d	«      z  }||z  j                  d	«      z  }|||z  j                  d	«      z  }||z  |z  ||z  |z  z   ||z  |z  z   ||z  |z  z   S )u   Bilinear grid sampling compatible with all PyTorch backends including MPS.

    Drop-in replacement for ``F.grid_sample(input, grid, mode='bilinear', ...)``. On MPS, ``F.grid_sample`` backward
    (``grid_sampler_2d_backward``) is not yet implemented and silently falls back to CPU.  This function uses
    gather-based index arithmetic â€” natively supported on every backend â€” for the MPS path, while delegating to
    ``F.grid_sample`` on CUDA/CPU where its fused kernel is faster.  The two paths are numerically identical, so model
    accuracy is unaffected.

    Args:
        input: Feature map of shape ``(N, C, H, W)``.
        grid: Sampling grid of shape ``(N, Hg, Wg, 2)`` with values in ``[-1, 1]``.
        padding_mode: ``"zeros"`` returns 0 for out-of-bounds samples; ``"border"`` clamps to the nearest border pixel.
        align_corners: If ``True``, grid extremes ``Â±1`` map to pixel centres at positions ``0`` and ``H-1``/``W-1``.

    Returns:
        Sampled tensor of shape ``(N, C, Hg, Wg)``.
    r   NÚmpsÚbilinear)Úmoderp   rq   )rF   ÚborderzUnsupported padding_mode=zP for manual grid sampling. Only 'zeros' and 'border' are supported in this path.r   r<   ).r   ).r   g      à?g      ð?rv   Úiy_Úix_r	   c                 óº   •— | ‰z  |z   j                  d«      j                  d«      j                  ‰‰d«      }‰j                  d|«      j	                  ‰‰‰‰«      S )Nr   éÿÿÿÿr<   )ÚflattenÚ	unsqueezeÚexpandÚgatherÚview)	rw   rx   ÚidxÚ
batch_sizeÚchannelsÚflatÚgrid_heightÚ
grid_widthÚwidths	      €€€€€€r   Ú_gatherz&_bilinear_grid_sample.<locals>._gather  sY   ø€ Ø�U‰{˜SÑ ×)Ñ)¨!Ó,×6Ñ6°qÓ9×@Ñ@ÀÈXÐWYÓZˆØ�{‰{˜1˜cÓ"×'Ñ'¨
°H¸kÈ:ÓVÐVr   rF   )Útorch.nn.functionalr_   r`   r"   ÚtypeÚgrid_sampler   rD   ÚfloorÚlongÚfloatr%   r>   r|   Ú
new_tensorÚclampr{   r4   r   )!rn   ro   rp   rq   ÚFÚmsgÚheightÚixÚiyÚix0Úiy0Úix1Úiy1Úwx1Úwy1ÚoneÚwx0Úwy0Úin_x0Úin_x1Úin_y0Úin_y1r‡   Úv00Úv10Úv01Úv11r�   r‚   rƒ   r„   r…   r†   s!                              @@@@@@r   Ú_bilinear_grid_sampler¦   Ë   s¹  ý€ ÷. $Ð#à‡|�|×Ñ˜EÒ!Ø�}‰}˜U D¨zÈÐdqˆ}ÓrÐràÐ.Ñ.à'¨Ð'7ð 8Dð Dð 	ô ˜‹oÐà*/¯+©+Ñ'€J�˜& %Ø"Ÿj™j¨™m¨T¯Z©Z¸©]Ð€K�ñ Ø�6‰l˜QÑ 5¨1¡9Ñ-°Ñ1ˆØ�6‰l˜QÑ 6¨A¡:Ñ.°Ñ2‰à�6‰l˜QÑ %Ñ'¨!Ñ+¨cÑ1ˆØ�6‰l˜QÑ &Ñ(¨1Ñ,¨sÑ2ˆà
�(‰(‹*�/‰/Ó
€CØ
�(‰(‹*�/‰/Ó
€CØ
�‰'€CØ
�‰'€Cð �—	‘	“Ñ×
Ñ
 §¡Ó
,×
6Ñ
6°qÓ
9€CØ�—	‘	“Ñ×
Ñ
 §¡Ó
,×
6Ñ
6°qÓ
9€CØ
�.‰.˜Ó
€CØ
�‰)€CØ
�‰)€Cà�xÒØ�i‰i˜˜5 1™9Ó%ˆØ�i‰i˜˜6 A™:Ó&ˆØ�i‰i˜˜5 1™9Ó%ˆØ�i‰i˜˜6 A™:Ó&‰à˜‘˜c E™kÑ*ˆØ˜‘˜c E™kÑ*ˆØ˜‘˜c F™lÑ+ˆØ˜‘˜c F™lÑ+ˆØ�i‰i˜˜5 1™9Ó%ˆØ�i‰i˜˜6 A™:Ó&ˆØ�i‰i˜˜5 1™9Ó%ˆØ�i‰i˜˜6 A™:Ó&ˆð �=‰=˜Ó€DðW”U—\‘\ð W¬¯©ð W¼¿¹÷ Wò Wñ �#�sÓ
€CÙ
�#�sÓ
€CÙ
�#�sÓ
€CÙ
�#�sÓ
€Cà�wÒØ�U˜U‘]×-Ñ-¨aÓ0Ñ0ˆØ�U˜U‘]×-Ñ-¨aÓ0Ñ0ˆØ�U˜U‘]×-Ñ-¨aÓ0Ñ0ˆØ�U˜U‘]×-Ñ-¨aÓ0Ñ0ˆà�‰9�s‰?˜S 3™Y¨™_Ñ,¨s°S©y¸3©Ñ>ÀÀsÁÈSÁÑPÐPr   Úbatch.c                 ó`   — t        t        | Ž «      } t        | d   |¬«      | d<   t        | «      S )a`  Module-level collate helper used as the base for :func:`make_collate_fn`.

    Defined at module scope (rather than as a closure inside :func:`make_collate_fn`) so that the resulting
    :class:`functools.partial` is picklable for multi-process DataLoaders and DDP spawn workers.

    Args:
        batch: List of ``(image, target)`` pairs from a dataset.
        block_size: When set, round batch ``H`` and ``W`` up to the next multiple of this value before padding.  See
            :func:`nested_tensor_from_tensor_list`.

    Returns:
        Tuple of ``(NestedTensor_of_images, tuple_of_targets)``.
    r   r;   )rC   rI   rU   r5   )r§   r8   s     r   Ú_collate_with_block_sizer©   *  s0   € ô" ”�e�Ó€EÜ-¨e°A©hÀ:ÔN€Eˆ!�HÜ�‹<Ðr   c                 ó   — t        | d¬«      S )a  Collate a list of (image, target) pairs into a batched NestedTensor.

    Uses :func:`nested_tensor_from_tensor_list` with no ``block_size`` rounding. For DataLoaders that need
    backbone-aware rounding (e.g. windowed attention requires divisibility by ``patch_size * num_windows``), use
    :func:`make_collate_fn` instead to obtain a parameterised collate callable.

    Args:
        batch: List of ``(image, target)`` pairs from a dataset.

    Returns:
        Tuple of ``(NestedTensor_of_images, tuple_of_targets)``.
    Nr;   )r©   )r§   s    r   Ú
collate_fnr«   @  s   € ô $ E°dÔ;Ð;r   c                 ó$   — t        t        | ¬«      S )a+  Build a collate function that rounds batch ``H``/``W`` up to *block_size*.

    Used by the training DataModule to ensure that batched inputs satisfy the backbone's spatial divisibility
    requirement (``patch_size * num_windows``). Passing ``block_size=None`` produces a callable equivalent to
    :func:`collate_fn`.

    The returned callable is a :class:`functools.partial`, not a closure, so it is picklable and safe to use with
    multi-process DataLoaders (``num_workers > 0``) and DDP spawn workers.

    Args:
        block_size: When set, batch ``H`` and ``W`` are rounded up to the next
            multiple of this value before padding.  The rounded-up strip is marked as padding in the NestedTensor mask.

    Returns:
        A collate callable suitable for ``torch.utils.data.DataLoader``.
    r;   )r   r©   r;   s    r   Úmake_collate_fnr­   P  s   € ô& Ô+¸
ÔCÐCr   r   )rF   F)r3   Ú	functoolsr   Útypingr   r   r4   r@   r   rc   r   rC   r   r   rU   ÚjitÚunusedrB   r.   rH   r¦   r5   r©   r«   r­   r6   r   r   ú<module>r²      sÌ  ðñ ?å ß  ã Û Ý ð; ð ;°ð ;¸ó ;ð(˜4  S¡	™?ð ¨t°C©yó ÷ 0!ñ 0!ðj "ñ)&Ø�f‘ð)&à�d‘
ð)&ð ó)&ð\ ‡�×Ñð "ñ++Ø�f‘ð++à�d‘
ð++ð ò++ó ð++ðb  Øñ	\QØ�<‰<ð\Qà
�,‰,ð\Qð ð\Qð ð	\Qð
 ‡\�\ó\QðB "ñØ��c˜3�h‘Ñ ðà�d‘
ðð ˆ3�ˆ8�_óð,<�d˜5  c ™?Ñ+ð <°°c¸3°h±ó <ð" "ñDØ�d‘
ðDàˆt�E˜#˜s˜(‘OÑ$Ð% u¨S°#¨X¡Ð6Ñ7ôDr   