
    ^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     qy;E7CDD1}DXJOPPX!h.(::    the_listc                 n    | d   }| dd D ]'  }t        |      D ]  \  }}t        ||   |      ||<    ) |S )zReturn 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     QKEAB< 3$W- 	3KE4uU|T2E%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)NestedTensorzBatch 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 )zMove 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_     &dlloof77yy###1&1I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     LL##%&*ii&;DII  "
 	
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     ||TYY&&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    
 ftm  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 HScii HI!/ZHHQK/ZHHQK;'(83 
1aA$$Q&&[fEzz1a)5::fE";= 	6OC!NciilNNciilNNciilNBCII#N05An		!nn		!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>%%'( $YYu{{K+PSCIIaL+PQTTUZUbUbcdgghmhshst

#$ __Zu{{; b(1,3r9 b(1,3r9XH KL 8+.xsyy9I+JKRBGKKXX((,,S1gaj!WQZQRT[\]T^2_`
:&SV599SZZHhh))--a!WQZGAJ1OQ[]^_KNN5::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6q9@@XWYZ{{1c"''
Hk: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!}}UDzdq}rr..''7 8D D 	 o*/++'J&%"jjmTZZ]K 6lQ519-16lQ6A:.26lQ%'!+c16lQ&(1,s2
((*//
C
((*//
C
'C
'C 		


,
6
6q
9C		


,
6
6q
9C
..
C
)C
)Cxii519%ii6A:&ii519%ii6A:&cEk*cEk*cFl+cFl+ii519%ii6A:&ii519%ii6A:& ==DWU\\ W W W W #s
C
#s
C
#s
C
#s
CwUU]--a00UU]--a00UU]--a00UU]--a009s?S3Y_,sSy3>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-eAh:NE!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     $Ed;;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	? tCy  0! 0!j ")&f)&d
)& )&\  "++f++d
++ ++ ++b  	\Q<<\Q
,,\Q \Q 	\Q
 \\\QB "c3h d
 38_,<d5c?+ <c3h <" "Dd
DtE#s(O$%uS#X67Dr   