+
    "Ý³jó  ã                   ó‚   € ^ RI t ^ RIHt ^ RIt^ RIHt ^ RIHtHt ^ RIH	t	H
t
 ^ RIHt ^RIHt R.t ! R	 R]4      tR# )
é    N)ÚOptional)Únn)ÚBaseSparsifierÚget_arg_info_from_tensor_fqn)ÚQConfigÚdefault_placeholder_observer)Ú_remove_qconfig)ÚPerChannelNormObserverÚWandaSparsifierc                   óŒ   a a€ ] tR t^t oRtRV3R lV 3R llltV3R lV 3R lltV3R lR ltRV3R lV 3R	 llltR
t	Vt
V ;t# )r   aß  Wanda sparsifier

Wanda (Pruning by Weights and activations), proposed in https://arxiv.org/abs/2306.11695
is an activation aware pruning method. The sparsifier removes weights based on the product
of the input activation norm and the weight magnitude.

This sparsifier is controlled by three variables:
1. `sparsity_level` defines the number of *sparse blocks* that are zeroed-out;

Args:
    sparsity_level: The target level of sparsity;
    model: The model to be sparsified;
c                ó6   <€ V ^8„  d   QhRS[ RS[S[,          /# )é   Úsparsity_levelÚsemi_structured_block_size)Úfloatr   Úint)ÚformatÚ__classdict__s   "€ÚW/home/luca/screen-checking/.venv/lib/python3.14/site-packages/torchao/sparsity/wanda.pyÚ__annotate__ÚWandaSparsifier.__annotate__#   s#   ø€ ÷ ,ñ ,áð,ñ %-©S¥Mñ,ó    c           	     óŽ   <€ R VRV/pVe*   Tp\         P                  ! RV RV^,           RV R24       \        SV `  VR7       R# )r   r   Nz.WandaSparsifier got semi_structured_bock_size=z, sparsity_level fixed to 50% (Ú:z
) sparsity)Údefaults)ÚwarningsÚwarnÚsuperÚ__init__)Úselfr   r   r   ÚmÚ	__class__s   &&&  €r   r   ÚWandaSparsifier.__init__#   sg   ø€ ð ˜nØ(Ð*Dð
ˆð &Ò1Ø*ˆAÜ�MŠMØ@ÀÀÐCbÐcdÐhiÕciÐbjÐjkÐlmÐknÐnxÐyôô 	‰Ñ (ÐÖ+r   c                óN   <€ V ^8„  d   QhRS[ P                  RS[S[,          RR/# )r   ÚmodelÚconfigÚreturnN)r   ÚModuleÚlistÚdict)r   r   s   "€r   r   r   3   s*   ø€ ÷ 'ñ '™RŸY™Yð '±±Tµ
ð '¸tñ 'r   c                óv  <€ Vf   \        \        \        R7      Vn        M^V FX  pVP	                  RR 4      pVf   \        R4      h\        W4      pVR,          pVf   K>  \        \        \        R7      Vn        KZ  	  \        P                  P                  P                  VRR7       \        SV `)  W4       R # )N)Ú
activationÚweightÚ
tensor_fqnz(Each config must contain a 'tensor_fqn'.ÚmoduleT)Úinplace)r   r
   r   ÚqconfigÚgetÚ
ValueErrorr   ÚtorchÚaoÚquantizationÚpreparer   )r    r%   r&   Úmodule_configr.   Úinfo_from_tensor_fqnr/   r"   s   &&&    €r   r7   ÚWandaSparsifier.prepare3   s«   ø€ ð Š>ä#Ü1Ô:VôˆE�Mó "(�Ø*×.Ñ.¨|¸TÓB�
ØÒ%Ü$Ð%OÓPÐPô (DÀEÓ'VÐ$Ø-¨hÕ7�ð Ô%Ü%,Ü#9Ü;ô&�F–Nñ "(ô 	�‰×Ñ×%Ñ% e°TÐ%Ô:ô 	‰‰˜Ö&r   c                óD   <€ V ^8„  d   QhRS[ P                  RS[RS[RR/# )r   r/   Útensor_namer   r'   N)r   r(   Ústrr   )r   r   s   "€r   r   r   P   s1   ø€ ÷ $
ñ $
Ù—i‘ið$
Ù.1ð$
ÙCHð$
à	ñ$
r   c           	     óz  € \        VP                  V4      ^ ,          P                  p\        VP                  V4      P                  pVP                  P
                  p\        P                  ! V4      V,          pVP                  4       p	\        W“,          4      p
VP                  RR4      e   VR,          p	V	^,          p
VP                  RV	4      P                  ^R7      RRV
13,          pVP                  P                  RV	4      P                  ^V\        P                  ! WµP                   R7      4       R# )zùPruning function for WandaSparsifier

The activation statistics is retrieved first in the `act_per_input` variable.
Then the Wanda pruning metric is computed. The weight matrix is then pruned
by comparing this metric across the whole current layer.
r   N)Údim:NNN)Údtypeéÿÿÿÿ)ÚgetattrÚparametrizationsÚmaskÚoriginalÚactivation_post_processÚnormr4   ÚabsÚnumelr   r2   ÚviewÚargsortÚdataÚscatter_Ú
zeros_liker@   )r    r/   r<   r   ÚkwargsrD   ÚtensorÚactivation_norm_per_channelÚpruning_metricÚ
block_sizeÚnum_specifiedÚpruning_indss   &&&&,       r   Úupdate_maskÚWandaSparsifier.update_maskP   s  € ô �v×.Ñ.°Ó<¸QÕ?×DÑDˆÜ˜×0Ñ0°+Ó>×GÑGˆØ&,×&DÑ&D×&IÑ&IÐ#ô Ÿš 6Ó*Ð-HÕHˆð $×)Ñ)Ó+ˆ
ô ˜JÕ7Ó8ˆà�:‰:Ð2°DÓ9ÒEØÐ <Õ=ˆJØ&¨!�OˆMð &×*Ñ*¨2¨zÓ:×BÑBÀqÐBÓIØˆ~�ˆ~Ðõ
ˆð
 	�	‰	�‰�r˜:Ó&×/Ñ/Øˆ|œU×-Ò-¨lÇ*Á*ÔMö	
r   c          	      ó„   <€ V ^8„  d   QhRS[ S[S[R3,          ,          RS[ S[S[S[S[R3,          3,          ,          /# )r   Úparams_to_keep.Úparams_to_keep_per_layer)r   Útupler=   r*   )r   r   s   "€r   r   r   v   sC   ø€ ÷ 
ñ 
á ¡¡s¨C x¥Õ1ð
ñ #+©4±±U¹3À¸8µ_Ð0DÕ+EÕ"Fñ
r   c                óx   <€ V P                    F  pVR ,          p\        V4       K  	  \        SV `  VVR7       R# )r/   )rY   rZ   N)Úgroupsr	   r   Úsquash_mask)r    rY   rZ   ÚargsrO   r&   r/   r"   s   &&&*,  €r   r^   ÚWandaSparsifier.squash_maskv   s?   ø€ ð —k”kˆFØ˜HÕ%ˆFÜ˜FÖ#ñ "ô
 	‰ÑØ)Ø%=ð 	ö 	
r   © )g      à?N)NN)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   r7   rV   r^   Ú__static_attributes__Ú__classdictcell__Ú__classcell__)r"   r   s   @@r   r   r      s8   ù‡ € ñ÷,õ ,÷ 'ó '÷:$
ð $
÷L
÷ 
õ 
r   )r   Útypingr   r4   r   Útorch.ao.pruningr   r   Útorch.ao.quantizationr   r   Útorch.ao.quantization.quantizer	   Úutilsr
   Ú__all__r   ra   r   r   Ú<module>rp      s5   ðó Ý ã Ý ß Iß GÝ :å )àÐ
€ôr
�nö r
r   