
    ^jsy                     Z   d Z ddlmZ ddlmZmZmZmZmZm	Z	 ddl
Z
ddl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 ddlmZ ddlmZ ddlmZ  e       ZdZerddl m!Z! de"fdZ# G d de
jH                  jJ                  jL                        Z'de(de(fdZ) G d de      Z*y)zALightningDataModule for RF-DETR dataset construction and loaders.    )Path)TYPE_CHECKINGAnyListLiteralOptionalTupleN)LightningDataModule)
DataLoader)_namespace_from_configs)ModelConfigTrainConfig)build_dataset)
AUG_CONFIG)box_xyxy_to_cxcywh)
get_logger)make_collate_fn   )Figurereturnc                  B    ddl m}  t        |       j                  d      S )zReturn ``True`` when the runtime has a CUDA accelerator available.

    Uses the fork-safe global ``DEVICE`` constant instead of direct ``torch.cuda.is_available()`` calls to avoid
    creating a CUDA context in fork-based notebook/DDP workflows.
    r   DEVICEcuda)rfdetr.configr   str
startswithr   s    f/var/www/ramen.bs-engineer-server.com/venv/lib/python3.12/site-packages/rfdetr/training/module_data.py_has_cuda_devicer       s     %v;!!&))    c            	           e Zd ZdZ	 ddej
                  j                  j                  dededdfdZ	defdZ
d	edefd
Zy)GradAccumAlignedDatasetu  Dataset wrapper that pads length to a multiple of ``effective_batch_size * world_size``.

    Workaround for https://github.com/Lightning-AI/pytorch-lightning/issues/19987: PTL fires the optimizer on partial
    accumulation windows at the tail of the dataset, causing the last optimizer step to be under-scaled.  Padding the
    dataset to a multiple of ``effective_batch_size * world_size`` ensures that ``drop_last=True`` on the DataLoader
    becomes a true no-op — every accumulation window is always complete.

    Padding indices are drawn randomly from the original dataset.  Because RF-DETR uses online augmentation, each padded
    sample receives a fresh random augmentation at ``__getitem__`` time, so it behaves like a new training example
    rather than a true duplicate.

    This wrapper can be removed once the upstream PTL issue is resolved.

    Args:
        dataset: The underlying dataset to wrap.
        effective_batch_size: ``batch_size * grad_accum_steps``.
        world_size: Number of DDP processes (default 1 for single-GPU/CPU).
            The alignment unit is ``effective_batch_size * world_size`` so that after PTL's ``DistributedSampler``
            splits samples across ranks each rank still receives an exact multiple of ``effective_batch_size``.
    dataseteffective_batch_size
world_sizer   Nc                    |dk  rt        d|       |dk  rt        d|       || _        t        |      | _        ||z  }| j                  |z  }||z
  |z  }t	        j
                         }|j                  d       |dkD  r2t	        j                  d| j                  |f|      j                         ng | _	        | j                  |z   | _
        y )N   z'effective_batch_size must be >= 1, got zworld_size must be >= 1, got r   )	generator)
ValueError_datasetlen_dataset_lengthtorch	Generatormanual_seedrandinttolist_pad_indices_length)selfr#   r$   r%   pad_unit	remainder	pad_countpad_index_generators           r   __init__z GradAccumAlignedDataset.__init__A   s      !#FG[F\]^^><ZLIJJ"7|'*4((83		)X5	#oo/''* 1} MM$$-	
 fh 	 ++i7r    c                     | j                   S )zKReturn the padded dataset length (always a multiple of the alignment unit).)r3   r4   s    r   __len__zGradAccumAlignedDataset.__len___   s    ||r    idxc                 z    || j                   k  r|n| j                  || j                   z
     }| j                  |   S )z1Return the item at the (possibly remapped) index.)r,   r2   r*   )r4   r=   dataset_idxs      r   __getitem__z#GradAccumAlignedDataset.__getitem__c   s>     !4#7#77cT=N=NsUYUiUiOi=j}}[))r    )r'   )__name__
__module____qualname____doc__r-   utilsdataDatasetintr9   r<   r   r@    r    r   r"   r"   +   sf    2 	8!!))8 "8 	8
 
8< *s *s *r    r"   backendc                 P    | dk7  r| S t               sy	 ddl}y# t        $ r Y yw xY w)a  Resolve ``"auto"`` to ``"cpu"`` or ``"gpu"`` based on runtime availability.

    For ``"cpu"`` and ``"gpu"`` the value is returned unchanged.  For ``"auto"`` the function checks CUDA and kornia
    availability and returns ``"gpu"`` only when both are present; otherwise ``"cpu"``.

    Called before dataset construction so that ``gpu_postprocess`` in the dataset builders always matches what the
    DataModule will actually do in ``on_after_batch_transfer``.

    Args:
        backend: Value of ``TrainConfig.augmentation_backend``.

    Returns:
        Resolved backend string, either ``"cpu"`` or ``"gpu"``.

    Examples:
        >>> _resolve_augmentation_backend("cpu")
        'cpu'
        >>> _resolve_augmentation_backend("gpu")
        'gpu'
    autocpur   Ngpu)r   kornia.augmentationImportError)rJ   kornias     r   _resolve_augmentation_backendrR   k   s7    * &" s    	%%c                       e Zd ZdZdededdf fdZdeddfdZde	fd	Z
de	fd
Zde	fdZde	fdZ	 d$ddddeded   dedeeef   dz  ddf
dZed%dededefd       Zded   dej,                  j.                  j0                  dz  fdZedej,                  j.                  j0                  dededz  fd       Zd&dZdededefd Zede e!e      fd!       Z"ded"ejF                  dedefd#Z$ xZ%S )'RFDETRDataModulea  LightningDataModule wrapping RF-DETR dataset construction and data loading.

    Args:
        model_config: Architecture configuration (used for resolution, patch_size, etc.).
        train_config: Training hyperparameter configuration (used for dataset params).
    model_configtrain_configr   Nc           	         t         |           || _        || _        |j                  |j
                  z  }|dk  r)t        d| d|j                   d|j
                   d      t        |      | _        d | _	        d | _
        d | _        d | _        d | _        d| _        | j                  j                  | _        ddlm} t'        | j                  j(                        j+                         }|d	v }| j                  j,                  	|d
k(  xr! |nt/        | j                  j,                        | _        | j                  j2                  | j                   dkD  nt/        | j                  j2                        | _        | j                   dkD  r:| j                  j6                  | j                  j6                  | _        y d| _        y d | _        y )Nr   z-Computed collate block_size must be > 0, got z from patch_size=z and num_windows=.)
block_sizeFr   >   rN   rL   r   r      )superr9   rU   rV   
patch_sizenum_windowsr)   r   _collate_fn_dataset_train_dataset_val_dataset_test_kornia_pipeline_kornia_normalize_kornia_setup_donenum_workers_num_workersr   r   r   acceleratorlower
pin_memorybool_pin_memorypersistent_workers_persistent_workersprefetch_factor_prefetch_factor)r4   rU   rV   rY   r   rg   uses_cuda_accelerator	__class__s          r   r9   zRFDETRDataModule.__init__   s   (( ",,|/G/GG
??,/0G0G/H I##/#;#;"<A? 
 +!
 CG@DAE -1-1 ).!%!2!2!>!> 	)$++778>>@ +/F F   ++3 v7"7d''223 	   33; !d''::; 	 
 q 595F5F5V5V5b!!11 !hi ! %)D!r    stagec                 &   | j                   j                  }t        | j                   | j                        }|dk(  rt	        | j                  j
                        }|| j                  j
                  k7  r||_        | j                   j                  r|dk7  rt        d| d      | j                  t        d||      | _        | j                  t        d||      | _
        | j                  s| j                          d| _        yy|d	k(  r | j                  t        d||      | _
        yy|d
k(  r=| j                  0| j                  j                  dk(  rd
nd}t        |||      | _        yy|dk(  r | j                  t        d||      | _
        yyy)u  Build datasets for the requested stage.

        PTL calls this on every process before the corresponding dataloader method.  Datasets are built lazily — a
        dataset is only constructed once even if ``setup`` is called multiple times.

        Args:
            stage: PTL stage identifier — one of ``"fit"``, ``"validate"``,
                ``"test"``, or ``"predict"``.
        fitrM   zGPU augmentation backend 'zi' does not support keypoint transforms. Set augmentation_backend='cpu' when use_grouppose_keypoints=True.NtrainvalTvalidatetestroboflowpredict)rU   
resolutionr   rV   rR   augmentation_backenduse_grouppose_keypointsr)   r_   r   r`   rd   _setup_kornia_pipelinera   dataset_file)r4   rr   r{   nsresolvedsplits         r   setupzRFDETRDataModule.setup   s    &&11
$T%6%68I8IJE> 5T5F5F5[5[\H4,,AAA*2'  88X=N 0
 ;X X  ""*&3GR&L#  ($1%Z$H! **++-*.' + j   ($1%Z$H! )f_!!)"&"3"3"@"@J"NTY%25"j%I" * i  ($1%Z$H! )  r    c                    | j                   }| j                  j                  }|| j                  j                  z  }| j                  }t        |      |t        z  k  rt        j                  dt        |      |t        z         t        j                  j                  j                  |d|t        z        }t        |||| j                  || j                  | j                   | j"                        S | j$                  rt'        | j$                  dd      nd}t)        |||      }t        ||dd| j                  || j                  | j                   | j"                  	      S )a  Return the training DataLoader.

        Uses a replacement sampler when the dataset is too small to fill ``_MIN_TRAIN_BATCHES`` effective batches
        (matching legacy behaviour in ``main.py``).  Otherwise wraps the dataset with :class:`GradAccumAlignedDataset`
        to ensure its length is an exact multiple of ``effective_batch_size * world_size`` (workaround for
        https://github.com/Lightning-AI/pytorch-lightning/issues/19987) and then uses ``shuffle=True, drop_last=True``
        so that PTL can auto-inject ``DistributedSampler`` in DDP mode.

        Returns:
            DataLoader for the training dataset.
        zCTraining with uniform sampler because dataset is too small: %d < %dT)replacementnum_samples)
batch_sizesampler
collate_fnre   ri   rl   rn   r%   r'   )r   shuffle	drop_lastr   re   ri   rl   rn   )r_   rV   r   grad_accum_stepsrf   r+   _MIN_TRAIN_BATCHESloggerinfor-   rE   rF   RandomSamplerr   r^   rk   rm   ro   trainergetattrr"   )r4   r#   r   r$   re   r   r%   s          r   train_dataloaderz!RFDETRDataModule.train_dataloader   sQ    %%&&11
)D,=,=,N,NN''w<.1CCCKKUG$'99
 kk&&44 03EE 5 G
 %++'++#'#;#; $ 5 5	 	 EILL'$,,a@VW
)'3GT!''#''#77 11

 
	
r    c                 ,   t        | j                  | j                  j                  t        j
                  j                  j                  | j                        d| j                  | j                  | j                  | j                  | j                  	      S )zReturn the validation DataLoader.

        Returns:
            DataLoader for the validation dataset with sequential sampling.
        Fr   r   r   r   re   ri   rl   rn   r   r`   rV   r   r-   rE   rF   SequentialSamplerr^   rf   rk   rm   ro   r;   s    r   val_dataloaderzRFDETRDataModule.val_dataloader:  w     ((33KK$$66t7H7HI''))''#77 11

 
	
r    c                 ,   t        | j                  | j                  j                  t        j
                  j                  j                  | j                        d| j                  | j                  | j                  | j                  | j                  	      S )z|Return the test DataLoader.

        Returns:
            DataLoader for the test dataset with sequential sampling.
        Fr   )r   ra   rV   r   r-   rE   rF   r   r^   rf   rk   rm   ro   r;   s    r   test_dataloaderz RFDETRDataModule.test_dataloaderL  sw     ((33KK$$66t7I7IJ''))''#77 11

 
	
r    c                 ,   t        | j                  | j                  j                  t        j
                  j                  j                  | j                        d| j                  | j                  | j                  | j                  | j                  	      S )zReturn the predict DataLoader (reuses the validation dataset, no augmentation).

        Returns:
            DataLoader for the validation dataset with sequential sampling.
        Fr   r   r;   s    r   predict_dataloaderz#RFDETRDataModule.predict_dataloader^  r   r       )columnsfigure_sizecountr   )ru   rv   rx   r   r   r   c                   	 ddl m} ddl}ddl}ddlm} ddlm}
 |dk  rt        d| d      |dk  rt        d| d      |<t        |      dk7  rt        d	| d      |d   dk  s|d
   dk  rt        d| d      | j                  |      }|t        d|d      |j                  g dg d      }t        d
t        |t        |            |z   d
z
  |z        }|j!                  |||xs
 d|z  d|z  f      \  }}|j#                  |t$              j'                  d      }|D ]  }|j)                  d        | j*                  }t-        |t/        t        |t        |                  d      D ]  \  }}||   \  }}| j1                  ||      } ||      }|j3                         j5                         j                         }|j7                  |j9                  |j;                  d
dd      dd      dz  j=                  |j>                              }|jA                  d      }tC        |tD        jF                        rtI        |d         tI        |d
         }}n0tI        |jJ                  d         tI        |jJ                  d         }}|jA                  dtE        jL                  dtD        jN                              }|jA                  dtE        jL                  d tD        jP                              }|jS                         dkD  rtE        jT                  ||||gtD        jN                        } |
|j3                         j5                               |z  } |j3                         j5                         j                         j=                  tH              }!|jA                  d!      }"|"?|"jS                         dkD  r,|"j3                         j5                         j                         nd}#|jW                  | j                         j=                  |jN                        |!|#"      }$|!D %cg c]"  }%||%t        |      k  r||%   n
tY        |%      $ }&}%|#!|j[                         j]                  ||$#      }|j_                  d
$      j]                  ||$#      }|ja                  d%d&      j]                  ||$|&'      }|jA                  d(      }'|'|'jS                         dkD  r|'j3                         j5                         j                         j=                  |jN                        }(|(d)ddf   |j#                  ||g|jN                        z  })|(d*   dkD  }*|jc                  |)|*j=                  |jN                        |j3                         j5                         j                         j=                  tH              |*d+|*i,      }+|je                  d-.      j]                  ||+/      }|jg                  |       ||jh                  n| d0| d1},|jk                  | jm                  |,      d23       |j)                  d        |jo                          |S # t        $ r}	t        d      |	d}	~	ww xY wc c}%w )4a  Build a private diagnostic figure for transformed dataset samples.

        Samples the dataset after RF-DETR dataset transforms, so boxes and
        keypoints match the model input tensors rather than raw annotation JSON.

        Args:
            count: Maximum number of samples to render.
            split: Dataset split to visualize.
            columns: Number of subplot columns.
            figure_size: Optional Matplotlib figure size ``(width, height)`` in
                inches. When omitted, the size is derived from the grid shape.

        Returns:
            Matplotlib figure containing the annotated sample grid. When the
            dataset includes instance masks, they are rendered as coloured
            overlays before bounding boxes and labels.

        Raises:
            ValueError: If ``count`` or ``columns`` is not positive.

        Example:
            >>> # dm = RFDETRDataModule(model_config, train_config)
            >>> # figure = dm._show_samples(3, split="train")
        r   NzwRFDETRDataModule._show_samples() requires visualization dependencies. Install them with `pip install 'rfdetr[visual]'`.)box_cxcywh_to_xyxyzcount must be positive, got rX   zcolumns must be positive, got rZ   z)figure_size must contain two values, got r'   z)figure_size values must be positive, got zCould not build dataset split z for visualization.)g:ܟw g$I$I ggE#)g!:ܟw@gm۶m@grq@)meanstdr   )figsize)dtypeoffF)strictg        g      ?   sizeboxes)r      labels)r   masks)xyxyclass_idmask)scene
detections)	thicknessg?)
text_scaletext_padding)r   r   r   	keypoints.).rZ   visible)xykeypoint_confidencer   r   rF   r   )radius)r   
key_points[]
   )fontsize)8matplotlib.pyplotpyplotnumpysupervisiontorchvision.transforms
transformsrP   rfdetr.utilities.box_opsr   r)   r+   _get_dataset_for_visualizationRuntimeError	Normalizemaxminsubplotsasarrayobjectreshapeaxisclass_namesziprange_source_image_pathdetachrM   ascontiguousarrayclip	transposeastypeuint8get
isinstancer-   TensorrH   shapezerosfloat32int64numeltensor
Detectionsr   MaskAnnotatorannotateBoxAnnotatorLabelAnnotator	KeyPointsVertexAnnotatorimshowname	set_title_ellipsize_sample_titletight_layout)-r4   r   r   r   r   pltnpsvTerrr   r#   inv_normalizerowsfigureaxes
axes_arrayr   r   sample_indeximage_tensortarget
image_pathimageimage_arrayr   r   heightwidthr   r   scaler   	class_idsmasks_tensor
mask_arrayr   r   labels_textr   keypoints_arraykeypoint_xykeypoint_visibilityr   titles-                                                r   _show_sampleszRFDETRDataModule._show_samplesp  s-   @		+$. 	@A:;E7!DEEa<=gYaHII";1$ #L[MYZ![\\1~"k!n&9 #L[MYZ![\\55e<?!?yH[\]]A1 $ 
 1s5#g,/'9A='IJ||D';;a1w;XY\`X`Ja|bZZFZ3;;B?
 	DIIe	 &&"%j%E3w<8P2QZ_"` 8	D,#*<#8 L&00,GJ!,/E,,.,,.446K(("''+2G2G1a2PRUWZ*[^a*a)i)ijljrjr)stE::f%D$- #DGc$q'l #L$6$6r$: ;SASASTVAW=XJJwF%--(PQEZZ%++d%++*NOF{{}q eVUF%C5==Y)%,,.*<*<*>?%G"MMO//1779@@E	%zz'2 $/L4F4F4H14L !'')--/557 
  ]]

0C0CBJJ0OZcjt]u
 %.  .9-DTWXcTdIdK)jmnvjww  ),,.77ePZ7[E!4==EV`=a))Sq)IRR)& S  

;/I$):Q)>"+"2"2"4"8"8":"@"@"B"I"I"**"U-c2A2g6UFO[][e[e9ff&5f&=&A#\\"(;(B(B2::(N#]]_00288:AA#F/#%89 * 
 **!*4==EV`=aKK'1'=JOOeWAl^[\C]ENN477>NLIIeq8	t 	y  	D 	vs   Y( 6'Z(	Z1Y==Zr  
max_lengthc                     t        |       |k  r| S |dk  rd|z  S t        d|dz
  dz        }|dz
  |z
  }| d|  d| | d  S )a  Shorten long sample titles so subplot grids do not overflow.

        Args:
            title: Raw title text, usually an image file name.
            max_length: Maximum returned character count including the ellipsis.

        Returns:
            Original title when it already fits, otherwise a middle-ellipsized
            string that preserves the start and file suffix.
        r   rX   r'   rZ   Nz...)r+   r   )r  r  	keep_left
keep_rights       r   r   z(RFDETRDataModule._ellipsize_sample_title  sm     u:#L?##JNq01	!^i/

#$Czkl(;'<==r    c                     |dk(  r| j                  d       | j                  S |dk(  r| j                  d       | j                  S |dk(  r| j                  d       | j                  S t	        d|d      )z7Return a built dataset split for private visualization.ru   rt   rv   rw   rx   zUnsupported split rX   )r   r_   r`   ra   r)   )r4   r   s     r   r   z/RFDETRDataModule._get_dataset_for_visualization  sw    
 GJJu&&&E>JJz"$$$F?JJv%%%-eYa899r    r#   r   c                     t        | dd      }t        | dd      }t        | dd      }|||y||   }|j                  |      d   }t        |      |d   z  S )z:Return a source image path for common COCO-style datasets.rootNidscocor   	file_name)r   loadImgsr   )r#   r   image_folder	image_idsr  image_id
image_infos          r   r   z#RFDETRDataModule._source_image_path  sr     w5GUD1	w-9#4\*]]8,Q/
L!J{$;;;r    c                 v   | j                   j                  }|dk(  ry|dk(  r&t               st        j	                  d       y	 ddl}n|dk(  rt               st        d      	 ddl}dd
lm	}m
}  || j                   j                  | j                   j                  nt        | j                  j                  | j                  j                        | _         |       | _        t        j%                  d|       y# t        $ r t        j	                  d       Y yw xY w# t        $ r}t        d	      |d}~ww xY w)aX  Resolve augmentation backend and build the Kornia pipeline if applicable.

        Called once during ``setup("fit")``.  When ``augmentation_backend`` is ``"cpu"`` this is a no-op.  For
        ``"auto"`` the method falls back silently when CUDA or Kornia are unavailable.  For ``"gpu"`` missing
        requirements raise hard errors.
        rM   NrL   zFaugmentation_backend='auto': no CUDA, falling back to CPU augmentationr   zIaugmentation_backend='auto': kornia not installed, using CPU augmentationrN   z1augmentation_backend='gpu' requires a CUDA devicezLGPU augmentation requires kornia. Install with: pip install 'rfdetr[kornia]')build_kornia_pipelinebuild_normalize)
with_masksz3Kornia GPU augmentation pipeline built (backend=%s))rV   r|   r   r   warningrO   rP   r   !rfdetr.datasets.kornia_transformsr   r!  
aug_configr   rU   r{   segmentation_headrb   rc   r   )r4   rJ   rQ   r   r   r!  s         r   r~   z'RFDETRDataModule._setup_kornia_pipeline#  s    ##88ef#%gh* #%"#VWW* 	] 5,0,=,=,H,H,TD((Zd((((::!

 "1!2I7S+  jk  !bs*   C: #D :DD	D8'D33D8batchdataloader_idxc                    | j                   "| j                   j                  r| j                  |S ddlm}m}m} ddlm} |\  }}|j                  }	| j                  j                  |	j                         | j                  j                  |	j                          |||	j                        \  }
}| j                  j                  rz|	j                  dd \  }} |||	j                  |j                  d   ||      }| j                  |	|
|      \  }}}| j                  |      } ||||g|j                  dd d|i}n>| j                  |	|
      \  }}| j                  |      } ||||g|j                  dd  }|j                  dd \  }}|D ]A  }|d	   }|j!                         dk(  r|j#                  ||||g      }t%        |      |z  |d	<   C  |||j&                        |f}|S )
a  Apply Kornia GPU augmentation after the batch is transferred to device.

        When ``_kornia_pipeline`` is set and the trainer is in training mode, augmentation and normalization are applied
        on the GPU.  Validation and test batches pass through unchanged.

        Segmentation models use a mask-aware pipeline (``with_masks=True``) so images, boxes, and per-instance masks are
        augmented in sync.

        Args:
            batch: Tuple of ``(NestedTensor, list[dict])`` already on device.
            dataloader_idx: Index of the current dataloader.

        Returns:
            The (possibly augmented) batch.
        Nr   )collate_boxescollate_masksunpack_boxes)NestedTensorr   r'   )n_maximage_heightimage_width	masks_augr   )r   trainingrb   r$  r*  r+  r,  rfdetr.utilities.tensorsr-  tensorstodevicerc   rU   r&  r   r   
new_tensorr   r   )r4   r'  r(  r*  r+  r,  r-  samplestargetsimgboxes_paddedvalidr/  r0  masks_paddedimg_aug	boxes_augr1  r  r  r   r   r  s                          r   on_after_batch_transferz(RFDETRDataModule.on_after_batch_transferK  s     <<t||'<'<@U@U@]L``9 oo 	  ,!!#**-+GSZZ@e..(+		"#%L+(5;;q>bmL -1,A,A#|Ua,b)GY	,,W5G"9eWgw}}RS?Qg]fgG!%!6!6sL!IGY,,W5G"9eWRw}}RS?QRGbc* 	@F7OE{{}!$$eVUF%CDE07%?F7O	@ gw||4g>r    c                 &   | j                   | j                  fD ]  }|t        |dd      }|t        |d      s#t        |dd      }|t        |dd      }t	        |t
              ra|r_t        |      }dg|dz   z  }t        |j                               D ]+  \  }}|j                  j                  |      }|$|d   ||<   - |c S t        |j                  j                               D 	cg c]  }	|j                  |	   d    c}	c S  yc c}	w )aa  Class names from the training or validation dataset annotation file.

        Reads category names from the first available COCO-style dataset. Returns ``None`` if no dataset has been set up
        yet or the dataset does not expose COCO-style category information.

        Returns:
            Sorted list of class name strings, or ``None``.
        Nr  cats	label2cat r'   r   )r_   r`   r   hasattrr   dictr   sorteditemsrB  r   keys)
r4   r#   r  rC  	max_labelnameslabelcategory_idcategoryks
             r   r   zRFDETRDataModule.class_names  s    ++T->->? 	PG7FD1DGD&$9#G[$?	$ 'k4 @Ii.9 #IIDIM2E.4Y__5F.G <*{#'99==#=#/+3F+;E%L< !L6<TYY^^=M6NO		!V,OO!	P"  Ps   .Dr6  c                     |\  }}|j                   dk(  }|j                  ||      }|D 	cg c]7  }|j                         D 	ci c]  \  }}	||	j                  ||       c}	}9 }}}}	||fS c c}	}w c c}	}}w )a  Move a ``(NestedTensor, targets)`` batch to *device*.

        PTL's default iterates tuple elements and calls ``.to(device)``; that works for plain tensors but
        ``NestedTensor`` must be moved explicitly.

        Args:
            batch: Tuple of (NestedTensor samples, list of target dicts).
            device: Target device.
            dataloader_idx: Index of the dataloader providing this batch.

        Returns:
            Batch with all tensors on ``device``.
        r   )non_blocking)typer5  rH  )
r4   r'  r6  r(  r8  r9  rQ  trO  vs
             r   transfer_batch_to_devicez)RFDETRDataModule.transfer_batch_to_device  s     !{{f,**V,*?_fggZ[1779U41aAqttFt>>Ugg Vgs   A8A2$A82A8)ru   )0   )r   N)&rA   rB   rC   rD   r   r   r9   r   r   r   r   r   r   r   rH   r   tuplefloatr  staticmethodr   r-   rE   rF   rG   r   r   r   r~   r	   r@  propertyr   r   r   r6  rU  __classcell__)rq   s   @r   rT   rT      s   7)[ 7) 7)PT 7)z-I3 -I4 -I^8
* 8
t

 
$
 
$
J 
* 29A
 26AA -.A
 A 5%<(4/A 
AF >s > >S > >&:-.: 
			!	!D	(:  	<EKK$4$4$<$< 	<C 	<TX[_T_ 	< 	<&TP3U 3C 3E 3r Xd3i0  8 e  U\\  [^  ch  r    rT   )+rD   pathlibr   typingr   r   r   r   r   r	   r-   torch.utils.datapytorch_lightningr
   r   rfdetr._namespacer   r   r   r   rfdetr.datasetsr   rfdetr.datasets.aug_configsr   r   r   rfdetr.utilities.loggerr   r3  r   r   r   matplotlib.figurer   rj   r   rE   rF   rG   r"   r   rR   rT   rI   r    r   <module>re     s    H  E E   1 ' 5 2 ) 2 7 . 4	 (*$ *=*ekk..66 =*@3 3 Bg * g r    