
    kh7                     H    d Z ddlZddlZddlmZmZmZ ddlZ G d d      Zy)aX  Patch-level random erasing augmentation for NaFlex Vision Transformers.

This module implements random erasing specifically designed for patchified images,
operating at the patch granularity rather than pixel level. It supports two modes:
- 'patch': Randomly erases individual patches (speckle-like noise)
- 'region': Erases contiguous rectangular regions of patches (similar to original RandomErasing)

The implementation is coordinate-aware, respecting valid patch boundaries and supporting
variable patch sizes in NaFlex training.

Hacked together by / Copyright 2025, Ross Wightman, Hugging Face
    N)OptionalUnionTuplec                      e Zd ZdZ	 	 	 	 	 	 	 	 	 	 	 	 	 ddedededee   deded	ed
ee   dededededeee	j                  f   ddfdZde	j                  dfdeeedf   e	j                  f   dee	j                     de	j                   deeee	j                  f      de	j                  f
dZde	j                  de	j                  de	j                  dee	j                  e	j                  e	j                  f   fdZe	j                  fde	j                  de	j                  de	j                  de	j                  de	j                   ddfdZe	j                  fde	j                  de	j                  de	j                  de	j                  de	j                   ddfdZ	 d de	j                  de	j                  dee	j                     de	j                  fdZdefdZy)!PatchRandomErasingzRandom erasing for patchified images in NaFlex format.

    Supports two modes:
    1. 'patch': Simple mode that erases randomly selected valid patches
    2. 'region': Erases rectangular regions at patch granularity
    N
erase_probpatch_drop_prob	min_count	max_countmin_areamax_area
min_aspect
max_aspectmodevaluespatial_mode
num_splitsdevicereturnc                    || _         || _        || _        |xs || _        || _        || _        |xs d|z  }t        j                  |      t        j                  |      f| _        || _	        || _
        || _        | j                  dv sJ |	j                         | _        | j                  dv sJ |
| _        d| _        y)a  Initialize PatchRandomErasing.

        Args:
            erase_prob: Probability that the Random Erasing operation will be performed.
            patch_drop_prob: Patch dropout probability. Remove random patches instead of erasing.
            min_count: Minimum number of erasing operations.
            max_count: Maximum number of erasing operations.
            min_area: Minimum percentage of valid patches/area to erase.
            max_area: Maximum percentage of valid patches/area to erase.
            min_aspect: Minimum aspect ratio of erased area (only used in 'region' mode).
            max_aspect: Maximum aspect ratio of erased area (only used in 'region' mode).
            mode: Patch content mode, one of 'const', 'rand', or 'pixel'.
            value: Constant value for 'const' mode.
            spatial_mode: Erasing strategy, one of 'patch' or 'region'.
            num_splits: Number of splits to apply erasing to (0 for all).
            device: Computation device.
           )patchregion)randpixelconstTN)r   r	   r
   r   r   r   mathloglog_aspect_ratior   r   r   lower
erase_modeconst_valueunique_noise_per_patch)selfr   r	   r
   r   r   r   r   r   r   r   r   r   r   s                 [/var/www/teggl/fontify/venv/lib/python3.12/site-packages/timm/data/naflex_random_erasing.py__init__zPatchRandomErasing.__init__   s    B %.""/i    11z>
!%*!5txx
7K L % )  $7777 **,"<<<< &*#    shape.dtypec                    |xs | j                   }| j                  dk(  r&t        j                  |||      j	                         S t        |      dk(  rdd|d   fnd|d   f}| j                  dk(  s|q|xs | j                  }t        |t        t        f      rt        j                  ||||      }|S t        j                  |||      }t        j                  ||      }|S t        j                  |||      j	                         }|S )aL  Generate values for erased patches based on the specified mode.

        Args:
            shape: Shape of patches to erase.
            value: Value to use in const (or rand) mode.
            dtype: Data type to use.
            device: Device to use.

        Returns:
            Tensor with values for erasing patches.
        r   r)   r      r   r   )r   r!   torchemptynormal_lenr"   
isinstanceintfloatfulltensorexpand_copy)r$   r(   r   r)   r   erase_valuevaluess          r%   _get_valueszPatchRandomErasing._get_valuesW   s    $ &4;;??g%;;uE&AIIKK),UqQ59%q%)nE')U->#7t'7'7kC<8"ZZ{%PVWF M	 #(,,{%PV"WK"..{EBF M U%GOOQMr'   patchespatch_coordpatch_validc           	      P   t        j                          | j                  kD  ryt        j                  |d      d   j	                         }|s|||fS t        |      }| j                  rt        dt        |d| j                  z
  z              }t        j                  t        j                  d|| j                        d	      ddd|f   }|j                  d	      d   }|j                  d|j                  d      j                  d
|j                   dd z               }|||fS )a  Patch Dropout.

        Fully drops patches from datastream. Only mode that saves compute BUT requires support
        for non-contiguous patches and associated patch coordinate and valid handling.

        Args:
            patches: Tensor of patches.
            patch_coord: Tensor of patch coordinates.
            patch_valid: Tensor indicating which patches are valid.

        Returns:
            Tuple of (patches, patch_coord, patch_valid) with some patches dropped.
        NTas_tupler   r   g      ?r   r-   )dim)r-   r-      )randomr   r.   nonzerotolistr1   r	   maxr3   argsortrandnr   sortgather	unsqueezeexpandr(   )r$   r;   r<   r=   valid_indices	num_validnum_keepkeep_indicess           r%   _drop_patchesz PatchRandomErasing._drop_patchesz   s   ( ==?T__, kDA!DKKM K44&	1c)rD4H4H/H"IJKH ==Q	$++)V\^_`acldlcl`lmL',,,4Q7LnnQ(>(>r(B(I(I(U\UbUbcdceUfJf(ghG[00r'   patch_shapec           
         t        j                          | j                  kD  ryt        j                  |d      d   }t	        |      }|dk(  ryt        j
                  | j                  | j                        }t        |t        dt        ||z  | j                  z                    }	t        dt        ||z  | j                  z              }
t        j
                  |
|	      }|t        j                  ||j                        d|    }| j                  r| j                   dk(  r|f|z   }n|}| j#                  ||      ||<   y)	a  Apply erasing by selecting individual patches randomly.

        The simplest mode, aligned on patch boundaries. Behaves similarly to speckle or 'sprinkles'
        noise augmentation at patch size.

        Args:
            patches: Tensor of patches to modify in-place.
            patch_coord: Tensor of patch coordinates.
            patch_valid: Tensor indicating which patches are valid.
            patch_shape: Shape of individual patches.
            dtype: Data type for generated values.
        NTr?   r   r   rA   r   r)   )rD   r   r.   rE   r1   randintr
   r   minrG   r3   r   r   randpermr   r#   r!   r:   )r$   r;   r<   r=   rS   r)   rN   rO   count	max_erase	min_erase	num_erase	erase_idx
fill_shapes                 r%   _erase_patchesz!PatchRandomErasing._erase_patches   s   ( ==?T__, kDA!D&	>t~~t~~>	3q#i%.?$--.O*P#QR	3y504==@AB	NN9i8	 "%..7>>"RS]T]"^_	&&4??g+E#3J$J!--j-F	r'   c           
         t        j                          | j                  kD  ry||   }t        |      dk(  ry|dddf   j                         j	                         dz   }|dddf   j                         j	                         dz   }||}
}	|	|
z  }|dddf   |dddf   }}t        j
                  | j                  | j                        }t        |      D ]  }t        d      D ]z  }t        j                  | j                  | j                        |z  }t        j                  t        j                  | j                         }t        t!        t        j"                  ||z                    }t        t!        t        j"                  ||z                    }||	kD  s||
kD  rt        j
                  d|	|z
        }t        j
                  d|
|z
        }||z   ||z   }}||k\  ||k  z  ||k\  z  ||k  z  |z  }t        |j%                         j	                               }|s@| j&                  r| j(                  dk(  r|f|z   }n|}| j+                  ||      ||<      y)a  Apply erasing by selecting rectangular regions of patches randomly.

        Closer to the original RandomErasing implementation. Erases
        spatially contiguous rectangular regions of patches (aligned with patches).

        Args:
            patches: Tensor of patches to modify in-place.
            patch_coord: Tensor of patch coordinates.
            patch_valid: Tensor indicating which patches are valid.
            patch_shape: Shape of individual patches.
            dtype: Data type for generated values.
        Nr   r   
   r   rU   )rD   r   r1   rG   itemrV   r
   r   rangeuniformr   r   r   expr   r3   roundsqrtsumr#   r!   r:   )r$   r;   r<   r=   rS   r)   valid_coordmax_ymax_xgrid_hgrid_w
total_areaysxsrY   _attempttarget_areaaspect_ratiohwtopleftbottomrightregion_masknum_selectedr^   s                               r%   _erase_regionz PatchRandomErasing._erase_region   sG   ( ==?T__, "+.{q AqD!%%',,.2AqD!%%',,.2f_
QT"K1$5Bt~~t~~>u %	A 9 #$nnT]]DMMJZW#xx8M8M(NO diil(BCDEdiil(BCDEv:V nnQ
3~~a!4 #a srF{3t%(*U
4#$ 
  #;??#4#9#9#;<#..4??g3M".;!>J!,J'+'7'7
%'7'P$G#%	r'   c                    |j                   dk(  r|j                  \  }}}}n$|j                   dk(  r|j                  \  }}}}	}nJ |j                  dd }
|2t        j                  ||ft        j                  |j
                        }| j                  dkD  r|| j                  z  nd}t        ||      D ]  }| j                  rJ d       | j                  d	k(  r)| j                  ||   ||   ||   |
|j                         N| j                  d
k(  r)| j                  ||   ||   ||   |
|j                         J  |S )aq  Apply random patch erasing.

        Args:
            patches: Tensor of shape [B, N, P*P, C] or [B, N, Ph, Pw, C].
            patch_coord: Tensor of shape [B, N, 2] with (y, x) coordinates.
            patch_valid: Boolean tensor of shape [B, N] indicating which patches are valid.

        Returns:
            Erased patches tensor of same shape as input.
              rC   Nr+   r   r   zWIP, not completedr   r   )ndimr(   r.   onesboolr   r   rc   r	   rR   r   r_   r)   r}   )r$   r;   r<   r=   
batch_sizenum_patches	patch_dimchannelspatch_hpatch_wrS   batch_startis                r%   __call__zPatchRandomErasing.__call__  sS     <<1;B==8JY\\QBI--?JWgx5mmAB' **j+%>ejjY`YgYghK 8<7JjDOO3PQ {J/ 	A##222u ""g-##AJNNMM ""h.""AJNNMM u5	8 r'   c                    | j                   j                  d| j                   d| j                   z   }|d| j                   d| j
                   d| j                   dz  }|d| j                   d| j                   dz  }|S )zReturn string representation of PatchRandomErasing.

        Returns:
            String representation of the object.
        z(p=z, mode=z
, spatial=z, area=(z, z))z	, count=()		__class____name__r   r!   r   r   r   r
   r   )r$   fss     r%   __repr__zPatchRandomErasing.__repr__Y  s     ^^$$T__,=WT__DU'VV

4,,-Xdmm_Bt}}oUWXX
	$..)DNN+;2>>	r'   )g      ?        r   Ng{Gz?gUUUUUU?g333333?Nr   r   r   r   cuda)N)r   
__module____qualname____doc__r4   r3   r   strr   r.   r   r&   float32r   SizeTensorr)   r:   rR   r_   r}   r   r    r'   r%   r   r      s    !$%('+"# #*. (/58+8+ #8+ 	8+
  }8+ 8+ 8+ 8+ !8+ 8+ 8+ 8+ 8+ #u||+,8+ 
8+z -1!&9=!sCx%**45! ELL)! ;;	!
 U3#456! 
!F'1\\'1 '1 	'1
 
u||U\\5<<7	8'1^ "',G\\,G ,G 	,G
 ,G ;;,G 
,Gh "'G\\G G 	G
 G ;;G 
GZ 37	=\\= = "%,,/	=
 
=~	# 	r'   r   )	r   rD   r   typingr   r   r   r.   r   r   r'   r%   <module>r      s'      ) ) M Mr'   