Ë
    ëÓ^júQ  ã            	      ó’  — U d Z ddlmZ ddlmZ ddlmZ ddlZddlmZ ddl	m
Z
 ddlmZ  e«       Zd	d
giZdZdZdZded<   d#d„Zd$d„Zd%d„Zd&d„Zd&d„Zd&d„Zd&d„Zd&d„Zd&d„Zd&d„Zd&d„ZeeeeeeeedœZded<   	 	 d'	 	 	 	 	 	 	 	 	 d(d„Zeef	 	 	 	 	 d)d„Z 	 	 	 	 	 	 d*d „Z!	 	 	 	 	 	 	 	 	 	 	 	 d+d!„Z"	 d,	 	 	 	 	 	 	 	 	 	 	 	 	 d-d"„Z#y).ab  Kornia-based GPU augmentation pipeline for RF-DETR training.

This module provides GPU-side augmentation as an alternative to the CPU-based Albumentations pipeline.  All transforms
run on the device where the batch already resides (typically CUDA), avoiding a CPU-GPU round-trip per sample.

Supports detection (boxes only) and segmentation (boxes + instance masks).

Usage::

    from rfdetr.datasets.kornia_transforms import (
        build_kornia_pipeline,
        build_normalize,
        collate_boxes,
        collate_masks,
        unpack_boxes,
    )

    # Detection:
    pipeline = build_kornia_pipeline(aug_config, resolution=560)
    normalize = build_normalize()
    boxes_padded, valid = collate_boxes(targets, device)
    img_aug, boxes_aug = pipeline(img, boxes_padded)
    img_aug = normalize(img_aug)
    targets = unpack_boxes(boxes_aug, valid, targets, H, W)

    # Segmentation (Phase 2):
    pipeline = build_kornia_pipeline(aug_config, resolution=560, with_masks=True)
    normalize = build_normalize()
    boxes_padded, valid = collate_boxes(targets, device)
    masks_padded = collate_masks(targets, device, n_max=valid.shape[1], image_height=H, image_width=W)
    img_aug, boxes_aug, masks_aug = pipeline(img, boxes_padded, masks_padded)
    img_aug = normalize(img_aug)
    targets = unpack_boxes(boxes_aug, valid, targets, H, W, masks_aug=masks_aug)
é    )Úannotations)ÚCallable)ÚAnyN)ÚTensor)Ú#filter_keypoint_hflip_augmentations)Ú
get_loggerÚbuild_kornia_pipelineÚkornia)g
×£p=
ß?gÉv¾Ÿ/Ý?g–C‹lçûÙ?)gZd;ßOÍ?gyé&1¬Ì?gÍÌÌÌÌÌÌ?ç      à?ÚfloatÚ_MASK_BINARIZE_THRESHOLDc                 óB   — ddl m}  t        | «      j                  d«      S )aÄ  Return ``True`` when the runtime has a CUDA accelerator available.

    Uses the fork-safe global ``DEVICE`` constant from ``rfdetr.config`` so that the CUDA driver context is not created
    in the main process before forking (fork-based DDP and some notebook environments).

    Returns:
        ``True`` if at least one CUDA device is reachable; ``False`` otherwise.

    Examples:
        >>> _has_cuda_device()  # doctest: +SKIP
        False
    r   ©ÚDEVICEÚcuda)Úrfdetr.configr   ÚstrÚ
startswithr   s    úl/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/rfdetr/datasets/kornia_transforms.pyÚ_has_cuda_devicer   D   s   € õ %äˆv‹;×!Ñ! &Ó)Ð)ó    c                óÀ   — | dk(  ry| dk(  rt        «       sy	 ddl}y| dk(  r t        «       st        d«      ‚t	        «        yt        d| ›d�«      ‚# t        $ r Y yw xY w)	a  Resolve an ``augmentation_backend`` value to a concrete ``"cpu"`` or ``"gpu"``.

    ``"auto"`` resolves to ``"gpu"`` only when both CUDA and Kornia are available; otherwise it falls back to ``"cpu"``.
    Explicit ``"cpu"`` and ``"gpu"`` values pass through unchanged; ``"gpu"`` is validated (CUDA + kornia presence).

    Args:
        backend: One of ``"cpu"``, ``"auto"``, or ``"gpu"``.

    Returns:
        ``"cpu"`` or ``"gpu"``.

    Raises:
        RuntimeError: When *backend* is ``"gpu"`` and no CUDA device is found.
        ImportError: When *backend* is ``"gpu"`` and kornia is not installed.
        ValueError: When *backend* is not one of ``"cpu"``, ``"auto"``, or ``"gpu"``.

    Examples:
        >>> resolve_augmentation_backend("cpu")
        'cpu'
    ÚcpuÚautor   NÚgpuz1augmentation_backend='gpu' requires a CUDA devicezUnknown augmentation_backend z#; expected 'cpu', 'auto', or 'gpu'.)r   Úkornia.augmentationÚImportErrorÚRuntimeErrorÚ_require_korniaÚ
ValueError)Úbackendr
   s     r   Úresolve_augmentation_backendr"   V   sz   € ð* �%ÒØØ�&ÒÜÔ!Øð	Û&ð Ø�%ÒÜÔ!ÜÐRÓSÐSÜÔØÜ
Ð4°W°KÐ?bÐcÓ
dÐdøô ò 	Ùð	ús   ˜A Á	AÁAc                 óH   — 	 ddl } y# t        $ r}t        d«      |‚d}~ww xY w)zžVerify that Kornia is importable, raising a clear error if not.

    Raises:
        ImportError: When ``kornia`` is not installed, with an install hint.
    r   NzLGPU augmentation requires kornia. Install with: pip install 'rfdetr[kornia]')r   r   )r
   Úes     r   r   r   }   s,   € ðqÜ"øÜò qÜÐhÓiÐopÐpûðqús   ‚ ‡	!�œ!c                ó@   — ddl m}  || j                  dd«      ¬«      S )z:Build a ``K.RandomHorizontalFlip`` from aug_config params.r   )ÚRandomHorizontalFlipÚpr   ©r'   )r   r&   Úget)Úparamsr&   s     r   Ú_make_horizontal_flipr+   Ž   s   € å8á &§*¡*¨S°#Ó"6Ô7Ð7r   c                ó@   — ddl m}  || j                  dd«      ¬«      S )z8Build a ``K.RandomVerticalFlip`` from aug_config params.r   )ÚRandomVerticalFlipr'   r   r(   )r   r-   r)   )r*   r-   s     r   Ú_make_vertical_flipr.   •   s   € å6á §
¡
¨3°Ó 4Ô5Ð5r   c                ó  — ddl m} | j                  dd«      }t        |t        t
        f«      rt        |«      n| |f} ||| j                  dd«      ¬«      }t        |dd	«      }t        |t        «      r	d
|vr||d
<   |S )z„Build a ``K.RandomRotation`` from aug_config params.

    The ``limit`` parameter may be a scalar (symmetric range) or a tuple.
    r   )ÚRandomRotationÚlimité   r'   r   )Údegreesr'   ÚflagsNr3   )r   r0   r)   Ú
isinstanceÚlistÚtupleÚgetattrÚdict)r*   r0   r1   r3   Úrotationr4   s         r   Ú_make_rotater;   œ   s|   € õ
 3à�J‰J�w Ó#€EÜ(¨´´u°Ô>Œe�EŒlÀeÀVÈUÀO€GÙ g°·±¸CÀÓ1EÔF€Hô
 �H˜g tÓ,€EÜ�%œÔ 9°EÑ#9Ø"ˆˆiÑà€Or   c           
     ón  — ddl m} | j                  d«      }|�Pt        |t        t
        f«      r7t        |«      dk(  r)t        t        |d   «      t        |d   «      «      }||f}n|}nd} || j                  dd«      || j                  d	«      | j                  d
«      | j                  dd«      ¬«      S )aŽ  Build a ``K.RandomAffine`` from aug_config params.

    Albumentations ``translate_percent`` is a ``(min, max)`` signed range (e.g. ``(-0.1, 0.1)``).  Kornia ``translate``
    is a non-negative per-axis max fraction ``(tx, ty)`` where translation is sampled from ``[-tx, tx]``.  The
    conversion takes ``max(|min|, |max|)`` for each axis, producing a symmetric range that matches the intent.
    r   )ÚRandomAffineÚtranslate_percentNé   é   Úrotate)iñÿÿÿr2   ÚscaleÚshearr'   r   )r3   Ú	translaterB   rC   r'   )	r   r=   r)   r5   r6   r7   ÚlenÚmaxÚabs)r*   r=   r>   ÚtrD   s        r   Ú_make_affinerI   ±   s³   € õ 1àŸ
™
Ð#6Ó7ÐØÐ$ÜÐ'¬$´¨Ô7¼CÐ@QÓ<RÐVWÒ<WÜ”CÐ)¨!Ñ,Ó-¬sÐ3DÀQÑ3GÓ/HÓIˆAØ=>À¸F‰Ià)‰Iàˆ	áØ—
‘
˜8 YÓ/ØØ�j‰j˜Ó!Ø�j‰j˜Ó!Ø
�*‰*�S˜#Ó
ôð r   c           
     óÈ   — ddl m}  || j                  dd«      | j                  dd«      | j                  dd«      | j                  dd«      | j                  dd	«      ¬
«      S )zàBuild a ``K.ColorJiggle`` from aug_config ``ColorJitter`` params.

    Note: Kornia >=0.7 uses ``ColorJiggle``; the ``ColorJitter`` alias was
    added in later versions.  We use ``ColorJiggle`` for broad compatibility.
    r   ©ÚColorJiggleÚ
brightnessg        ÚcontrastÚ
saturationÚhuer'   r   )rM   rN   rO   rP   r'   ©r   rL   r)   ©r*   rL   s     r   Ú_make_color_jitterrS   Í   sZ   € õ 0áØ—:‘:˜l¨CÓ0Ø—‘˜J¨Ó,Ø—:‘:˜l¨CÓ0Ø�J‰J�u˜cÓ"Ø
�*‰*�S˜#Ó
ôð r   c                ó„   — ddl m}  || j                  dd«      | j                  dd«      | j                  dd«      ¬«      S )	zCBuild a ``K.ColorJiggle`` from ``RandomBrightnessContrast`` params.r   rK   Úbrightness_limitgš™™™™™É?Úcontrast_limitr'   r   )rM   rN   r'   rQ   rR   s     r   Ú _make_random_brightness_contrastrW   Þ   s>   € å/áØ—:‘:Ð0°#Ó6Ø—‘Ð,¨cÓ2Ø
�*‰*�S˜#Ó
ôð r   c                óž   — ddl m} | j                  dd«      }|dz  dk(  r|dz   }t        d|«      } |||fd| j                  dd	«      ¬
«      S )z…Build a ``K.RandomGaussianBlur`` from aug_config params.

    ``blur_limit`` is rounded up to an odd number for the kernel size.
    r   )ÚRandomGaussianBlurÚ
blur_limité   r?   r@   )gš™™™™™¹?g       @r'   r   )Úkernel_sizeÚsigmar'   )r   rY   r)   rF   )r*   rY   rZ   s      r   Ú_make_gaussian_blurr^   é   s^   € õ
 7à—‘˜L¨!Ó,€Jà�A�~˜ÒØ !‘^ˆ
Ü�Q˜
Ó#€JÙØ Ð,ØØ
�*‰*�S˜#Ó
ôð r   c                ól   — ddl m} | j                  dd«      } ||d   | j                  dd«      ¬«      S )	z°Build a ``K.RandomGaussianNoise`` from aug_config params.

    Kornia takes a single ``std`` value; we use the upper bound of ``std_range`` as an acceptable approximation.
    r   )ÚRandomGaussianNoiseÚ	std_range)g{®Gáz„?gš™™™™™©?r@   r'   r   )Ústdr'   )r   r`   r)   )r*   r`   ra   s      r   Ú_make_gauss_noiserc   ü   s9   € õ
 8à—
‘
˜;¨Ó5€IÙØ�a‰LØ
�*‰*�S˜#Ó
ôð r   )ÚHorizontalFlipÚVerticalFlipÚRotateÚAffineÚColorJitterÚRandomBrightnessContrastÚGaussianBlurÚ
GaussNoisez*dict[str, Callable[[dict[str, Any]], Any]]Ú	_REGISTRYc           	     óp  — t        «        ddlm} t        | |t        j
                  ¬«      }t        |t        «      sJ ‚g }|j                  «       D ]R  \  }}t        j                  |«      }	|	€t        d|›dt        t        «      › d�«      ‚|j                   |	|«      «       ŒT |rg d¢ndd	g}
 ||d
|
iŽS )aË  Build a Kornia ``AugmentationSequential`` from an aug_config dict.

    Each key in *aug_config* is looked up in ``_REGISTRY`` and instantiated with the corresponding parameter dict.
    Unknown keys raise ``ValueError``.

    Args:
        aug_config: Mapping of augmentation names to parameter dicts, identical
            to the format accepted by the Albumentations path (e.g. ``{"HorizontalFlip": {"p": 0.5}}``).
        resolution: Target image resolution in pixels (currently reserved for
            future resolution-aware augmentations).
        with_masks: When ``True``, include ``"mask"`` in ``data_keys`` so
            instance segmentation masks are augmented in sync with images and boxes.  The pipeline then expects three
            inputs ``(img, boxes, masks)`` and returns three outputs.  Defaults to ``False`` (detection-only, two
            inputs/outputs).
        include_keypoints: When ``True``, keypoint-unsafe horizontal-flip
            transforms are dropped with a warning before the Kornia pipeline is built.

    Returns:
        A ``kornia.augmentation.AugmentationSequential`` instance.

    Raises:
        ValueError: If *aug_config* contains an unsupported augmentation key.

    Examples:
        >>> from rfdetr.datasets.aug_configs import AUG_CONSERVATIVE
        >>> pipeline = build_kornia_pipeline(AUG_CONSERVATIVE, resolution=560)
        >>> pipeline_seg = build_kornia_pipeline(AUG_CONSERVATIVE, resolution=560, with_masks=True)
    r   )ÚAugmentationSequential)Úinclude_keypointsÚwarnzUnknown augmentation key z) for Kornia GPU backend. Supported keys: ú.)ÚinputÚ	bbox_xyxyÚmaskrr   rs   Ú	data_keys)r   r   rn   r   ÚloggerÚwarningr5   r9   Úitemsrl   r)   r    ÚsortedÚappend)Ú
aug_configÚ
resolutionÚ
with_masksro   rn   Úfiltered_aug_configÚ
transformsÚnamer*   Úfactoryru   s              r   r	   r	     sÓ   € ôD ÔÝ:ä=ØØ+Ü�^‰^ôÐô
 Ð)¬4Ô0Ð0Ð0à€JØ+×1Ñ1Ó3ò +‰ˆˆfÜ—-‘- Ó%ˆØˆ?ÜØ+¨D¨8Ð3\Ô]cÔdmÓ]nÐ\oÐopÐqóð ð 	×Ñ™' &›/Õ*ð+ñ 3=Ó.À7ÈKÐBX€IÙ!Ø	ðàñð r   c                ó6   — t        «        ddlm}  || |¬«      S )aA  Build a Kornia ``Normalize`` transform for GPU-side normalization.

    Args:
        mean: Per-channel mean values.  Defaults to ImageNet statistics.
        std: Per-channel standard deviation values.  Defaults to ImageNet
            statistics.

    Returns:
        A ``kornia.augmentation.Normalize`` instance.
    r   )Ú	Normalize)Úmeanrb   )r   r   rƒ   )r„   rb   rƒ   s      r   Úbuild_normalizer…   W  s    € ô ÔÝ-áØØôð r   c                ó¬  — t        | «      dk(  r@t        j                  ddd|¬«      t        j                  ddt        j                  |¬«      fS | D �cg c]  }|d   j                  d   ‘Œ }}|rt        |«      nd}t        | «      }|dk(  r@t        j                  |dd|¬«      t        j                  |dt        j                  |¬«      fS t        j                  ||d|¬«      }t        j                  ||t        j                  |¬«      }t        | «      D ]2  \  }}|d   j                  d   }	|	dkD  sŒ|d   ||d|	…f<   d||d|	…f<   Œ4 ||fS c c}w )u  Pack variable-length xyxy boxes into a padded tensor and valid mask.

    Kornia ``AugmentationSequential`` expects boxes as ``[B, N_max, 4]``. This function zero-pads each image's boxes to
    the maximum count in the batch and returns a boolean mask indicating which entries are real.

    Args:
        targets: List of target dicts (one per image), each containing a
            ``"boxes"`` key with an ``[N_i, 4]`` tensor in xyxy format.
        device: Device on which to allocate the output tensors.

    Returns:
        Tuple of:
            - ``boxes_padded`` â€” ``[B, N_max, 4]`` float tensor (zero-padded).
            - ``valid_mask``   â€” ``[B, N_max]`` bool tensor (``True`` = real box).

        When ``B == 0`` or all images have zero boxes, both tensors have ``N_max == 0``.
    r   é   )Údevice©Údtyperˆ   ÚboxesNT)rE   ÚtorchÚzerosÚboolÚshaperF   Ú	enumerate)
Útargetsrˆ   rH   Ú
box_countsÚn_maxÚ
batch_sizeÚboxes_paddedÚ
valid_maskÚiÚns
             r   Úcollate_boxesr™   s  sP  € ô* ˆ7ƒ|�qÒä�K‰K˜˜1˜a¨Ô/Ü�K‰K˜˜1¤E§J¡J°vÔ>ð
ð 	
ð
 07Ö7¨!�!�G‘*×"Ñ" 1Ó%Ð7€JÐ7Ù)ŒC�
ŒO¨q€EÜ�W“€Jà�‚zä�K‰K˜
 A q°Ô8Ü�K‰K˜
 A¬U¯Z©ZÀÔGð
ð 	
ô
 —;‘;˜z¨5°!¸FÔC€LÜ—‘˜Z¨´e·j±jÈÔP€Jä˜'Ó"ò %‰ˆˆ1Øˆg‰J×Ñ˜QÑˆØˆq‹5Ø"# G¡*ˆL˜˜B˜Q˜B˜ÑØ $ˆJ�q˜"˜1˜"�uÒð	%ð ˜Ð#Ð#ùò' 8s   ÁEc                óF  — t        | «      }t        j                  ||||t        j                  |¬«      }t	        | «      D ]^  \  }}d|vs|dk(  rŒ|d   j                  t        j                  |¬«      }	t        |	j                  d   |«      }
|
dkD  sŒS|	d|
 ||d|
…f<   Œ` |S )uà  Pack variable-length instance masks into a zero-padded ``[B, N_max, H, W]`` tensor.

    Kornia ``AugmentationSequential`` expects masks as ``[B, N_max, H, W]`` when ``data_keys`` includes ``"mask"``.
    This function zero-pads each image's masks to *n_max* channels (matching the padding used by :func:`collate_boxes`)
    and converts boolean masks to ``float32`` for Kornia compatibility.

    Args:
        targets: List of target dicts (one per image).  Each dict may optionally
            contain a ``"masks"`` key with an ``[N_i, H, W]`` boolean tensor. Dicts without the key are treated as
            having zero instances.
        device: Device on which to allocate the output tensor.
        n_max: Maximum instance count across the batch â€” must equal
            ``collate_boxes(targets, device)[1].shape[1]`` to keep box/mask indices in sync.
        image_height: Spatial height ``H`` of each mask (pixels).
        image_width: Spatial width ``W`` of each mask (pixels).

    Returns:
        Float32 tensor of shape ``[B, N_max, H, W]``, zero-padded where ``N_i < N_max``.  Boolean input masks are cast
        to ``float32`` (``True â†’ 1.0``, ``False â†’ 0.0``).

    Examples:
        >>> import torch
        >>> targets = [{"masks": torch.ones(2, 8, 8, dtype=torch.bool)}]
        >>> out = collate_masks(targets, torch.device("cpu"), n_max=2, image_height=8, image_width=8)
        >>> out.shape
        torch.Size([1, 2, 8, 8])
        >>> out.dtype
        torch.float32
    r‰   Úmasksr   N)rE   rŒ   r�   Úfloat32r�   ÚtoÚminr�   )r‘   rˆ   r“   Úimage_heightÚimage_widthr”   Úmasks_paddedr—   rH   Úmasks_ir˜   s              r   Úcollate_masksr£   ¤  s­   € ôH �W“€JÜ—;‘;˜z¨5°,ÀÔSX×S`ÑS`ÐioÔp€LÜ˜'Ó"ò .‰ˆˆ1Ø˜!Ñ˜u¨šzØØ�G‘*—-‘-¤e§m¡m¸F�-ÓCˆÜ�—‘˜aÑ  %Ó(ˆØˆq‹5Ø")¨"¨1 +ˆL˜˜B˜Q˜B˜Òð.ð Ðr   c                óø  — |�S|j                   dd |j                   k(  s7J dt        |j                   dd «      › dt        |j                   «      › d�«       ‚g }t        |«      D �]“  \  }}|j                  «       }|d   j                   d   }	|	dk(  s|j                   d   dk(  r|j	                  |«       ŒR||d|	…f   }
| |d|	…f   }|j                  «       }|dd…df   j                  d|¬	«       |dd…df   j                  d|¬	«       |dd…df   j                  d|¬	«       |dd…d
f   j                  d|¬	«       |dd…df   |dd…df   z
  }|dd…d
f   |dd…df   z
  }|
|dkD  z  |dkD  z  }||   |d<   d|v r|d   |   |d<   d|v r/|d   }|dd…df   |dd…df   z
  |dd…d
f   |dd…df   z
  z  |d<   d|v r|d   |   |d<   |�||d|	…f   }||   t        kD  |d<   |j	                  |«       �Œ– |S )ue  Unpack augmented boxes (and optionally masks), clamp to image bounds, remove zero-area boxes.

    After Kornia augmentation the padded ``[B, N_max, 4]`` tensor is unpacked back into per-image target dicts.  Boxes
    are clamped to ``[0, W] x [0, H]`` and any that collapse to zero area are removed along with their corresponding
    ``labels``, ``area``, ``iscrowd``, and (if provided) ``masks`` entries.

    Args:
        boxes_aug: Augmented boxes tensor ``[B, N_max, 4]`` in xyxy format.
        valid: Boolean mask ``[B, N_max]`` from :func:`collate_boxes`.
        targets: Original target dicts; each dict is shallow-copied before
            modification â€” the input list itself is not mutated.
        image_height: Image height in pixels (for clamping).
        image_width: Image width in pixels (for clamping).
        masks_aug: Optional augmented masks tensor ``[B, N_max, H, W]``
            (float32) from Kornia.  When provided, masks are filtered by the same ``keep`` mask as boxes, thresholded at
            ``> 0.5`` to bool, and stored under ``"masks"`` in each output target dict.  When ``None``, any existing
            ``"masks"`` entry in the target dict is preserved unchanged.

    Returns:
        A new list of target dicts with updated ``boxes``, ``labels``, ``area``, ``iscrowd``, and (when *masks_aug* is
        given) ``masks`` entries.
    Nr?   zmasks_aug batch/n_max dims z must match valid shape zM; ensure collate_masks is called with n_max=valid.shape[1] from collate_boxesr‹   r   r@   )rž   rF   r[   ÚlabelsÚareaÚiscrowdr›   )r�   r7   r�   Úcopyrz   ÚcloneÚclamp_r   )Ú	boxes_augÚvalidr‘   rŸ   r    Ú	masks_augÚnew_targetsr—   rH   Ún_origÚvÚboxes_iÚwidthsÚheightsÚkeepÚ
kept_boxesr¢   s                    r   Úunpack_boxesr¶   Ô  sŠ  € ð< ÐØ�‰˜r Ð" e§k¡kÒ1ð 	
Ø)¬%°	·±ÀÀÐ0CÓ*DÐ)Eð FÜ  §¡Ó-Ð.ð /6ð6ó	
Ð1ð
 )+€KÜ˜'Ó"ó (‰ˆˆ1Ø�F‰F‹HˆØ�7‘×!Ñ! !Ñ$ˆà�QŠ;˜%Ÿ+™+ a™.¨AÒ-Ø×Ñ˜qÔ!Øð �!�W�f�W�*ÑˆØ˜A˜w ˜w˜JÑ'ˆð —-‘-“/ˆØ’�1�‰×Ñ ¨ÐÔ4Ø’�1�‰×Ñ ¨ÐÔ5Ø’�1�‰×Ñ ¨ÐÔ4Ø’�1�‰×Ñ ¨ÐÔ5ð š˜A˜‘ ª¨A¨¡Ñ.ˆØš!˜Q˜$‘- 'ª!¨Q¨$¡-Ñ/ˆØ�F˜Q‘JÑ 7¨Q¡;Ñ/ˆà˜T‘]ˆˆ'‰
Ø�q‰=Ø˜H™+ dÑ+ˆAˆh‰KØ�Q‰;à˜7™ˆJØ#¢A q DÑ)¨J²q¸!°tÑ,<Ñ<ÀÊAÈqÈDÑAQÐT^Ò_`ÐbcÐ_cÑTdÑAdÑeˆAˆf‰IØ˜‰>Ø˜Y™<¨Ñ-ˆAˆi‰LØÐ Ø  7 F 7 
Ñ+ˆGØ  ™Ô)AÑAˆAˆg‰Jð
 	×Ñ˜1ÖðQ(ðT Ðr   )ÚreturnrŽ   )r!   r   r·   r   )r·   ÚNone)r*   zdict[str, Any]r·   r   )FF)
r{   zdict[str, dict[str, Any]]r|   Úintr}   rŽ   ro   rŽ   r·   r   )r„   útuple[float, ...]rb   rº   r·   r   )r‘   úlist[dict[str, Any]]rˆ   útorch.devicer·   ztuple[Tensor, Tensor])r‘   r»   rˆ   r¼   r“   r¹   rŸ   r¹   r    r¹   r·   r   )N)r«   r   r¬   r   r‘   r»   rŸ   r¹   r    r¹   r­   zTensor | Noner·   r»   )$Ú__doc__Ú
__future__r   Úcollections.abcr   Útypingr   rŒ   r   Úrfdetr.datasets._aug_utilsr   Úrfdetr.utilities.loggerr   rv   Ú__doctest_requires__ÚIMAGENET_MEANÚIMAGENET_STDr   Ú__annotations__r   r"   r   r+   r.   r;   rI   rS   rW   r^   rc   rl   r	   r…   r™   r£   r¶   © r   r   ú<module>rÈ      sÇ  ðò!õF #å $Ý ã Ý å JÝ .á	‹€à/°(°Ð<Ð ð &€à$€ð #&Ð ˜%Ó %ó*ó$$eóN	qó"8ó6óó*ó8ó"óó&ð ,Ø'ØØØ%Ø @Ø'Ø#ñ	9€	Ð5ó 	ð( Ø#ð	9Ø)ð9àð9ð ð9ð ð	9ð
 	ó9ðz ,Ø)ðØ
ðà	ðð 	óð8.$Ø!ð.$àð.$ð ó.$ðb-Ø!ð-àð-ð ð-ð ð	-ð
 ð-ð ó-ðl  $ðOØðOàðOð "ðOð ð	Oð
 ðOð ðOð ôOr   