
    h              
       @   S SK r S SKJr  S SKJrJr  S SKrS SKJr  S SK	J
r
  S SKJr  S SKJrJrJr  S SKJrJr  S S	KJr  S
 r\ " S S\
5      5       r\r\" \5      S\R2                  R4                  S\4S j5       r " S S\
5      r\r\" \5      S\R2                  R4                  S\S\R2                  R4                  4S j5       r SS\R2                  R4                  S\
S\\\R2                  R4                  \/\ 4      S\R2                  R4                  4S jjr!g)    N)	dataclass)CallableOptional)to_sparse_semi_structured)AOBaseConfig)WeightNormSparsifier)
_is_linear_linear_extra_repr)_replace_with_custom_fn_if_matches_filter)_QUANTIZE_CONFIG_HANDLER register_quantize_module_handler)BlockSparseTensorc                 (   UR                  S[        5      n/ nU R                  5        H*  u  pEU" XT5      (       d  M  UR                  SU S305        M,     [	        SSSS9nUR                  X5        UR                  5         UR                  5         g)	zG
This function simulates 2:4 sparsity on all linear layers in a model.
	filter_fn
tensor_fqnz.weightg      ?)         )sparsity_levelsparse_block_shapezeros_per_blockN)popr	   named_modulesappendr   preparestepsquash_mask)modelkwargsr   sparse_confignamemod
sparsifiers          U/home/james-whalen/.local/lib/python3.13/site-packages/torchao/sparsity/sparse_api.pyapply_fake_sparsityr%      s     

;
3IM((*	S  ,4&0@!AB + &vqJ u,OO    c                   *    \ rS rSr% Sr\\S'   S rSrg)BlockSparseWeightConfig1   @   	blocksizec                 B    [         R                  R                  S5        g )Nz(torchao.sparsity.BlockSparseWeightConfigtorch_C_log_api_usage_onceselfs    r$   __post_init__%BlockSparseWeightConfig.__post_init__5   s    $$%OPr&    N)	__name__
__module____qualname____firstlineno__r+   int__annotations__r3   __static_attributes__r5   r&   r$   r(   r(   1   s    IsQr&   r(   moduleconfigc                     UR                   n[        R                  " U R                  U5      n[        R
                  R                  USS9U l        [        R                  " [        U 5      U l
        U $ NF)requires_grad)r+   r   
from_denseweightr.   nn	Parametertypes
MethodTyper
   
extra_repr)r=   r>   r+   
new_weights       r$   _block_sparse_weight_transformrJ   =   s[    
   I"--fmmYGJHH&&z&GFM(();VDFMr&   c                       \ rS rSrSrS rSrg)SemiSparseWeightConfigI   z]
Configuration for converting the weight of linear modules to semi-structured (2:4) sparsity
c                 B    [         R                  R                  S5        g )Nz'torchao.sparsity.SemiSparseWeightConfigr-   r1   s    r$   r3   $SemiSparseWeightConfig.__post_init__N   s    $$%NOr&   r5   N)r6   r7   r8   r9   __doc__r3   r<   r5   r&   r$   rL   rL   I   s    Pr&   rL   returnc                     [        U R                  5      n[        R                  R	                  USS9U l        [
        R                  " [        U 5      U l        U $ r@   )	r   rC   r.   rD   rE   rF   rG   r
   rH   )r=   r>   rI   s      r$   _semi_sparse_weight_transformrS   V   sH    
 +6==9JHH&&z&GFM(();VDFMr&   r   r   c                     [         R                  R                  S5        [        [	        U5         n[        U UUc  [        OUU4S9  g)a  Convert the weight of linear modules in the model with `apply_tensor_subclass`.
This function is essentially the same as quantize, put for sparsity subclasses.

Currently, we support three options for sparsity:
    - semi-structured (2:4) sparsity with `semi_sparse_weight`
    - int8 dynamic quantization + 2:4 sparsity with `layout=SemiSparseLayout`
    - int4 weight-only quantization + 2:4 sparsity with `layout=SparseMarlinLayout`

Args:
    model (torch.nn.Module): input model
    config (AOBaseConfig): a workflow configuration object
    filter_fn (Optional[Callable[[torch.nn.Module, str], bool]]): function that takes a nn.Module instance and fully qualified name of the module, returns True if we want to apply the specified workflow to this module.

**Example:**
::
        import torch
        import torch.nn as nn
        from torchao.sparsity import sparsify_

        def filter_fn(module: nn.Module, fqn: str) -> bool:
            return isinstance(module, nn.Linear)

        m = nn.Sequential(nn.Linear(32, 1024), nn.Linear(1024, 32))

        # for 2:4 sparsity
        from torchao.sparse_api import semi_sparse_weight
        m = sparsify_(m, semi_sparse_weight(), filter_fn)

        # for int8 dynamic quantization + 2:4 sparsity
        from torchao.dtypes import SemiSparseLayout
        m = quantize_(m, Int8DynamicActivationInt8WeightConfig(layout=SemiSparseLayout), filter_fn)
ztorchao.sparsity.sparsify_N)
extra_args)r.   r/   r0   r   typer   r	   )r   r>   r   handlers       r$   	sparsify_rX   a   sC    J 
HH  !=>&tF|4G-'
Y9	r&   )N)"rF   dataclassesr   typingr   r   r.   torch.sparser   torchao.core.configr   <torchao.prototype.sparsity.sparsifier.weight_norm_sparsifierr   torchao.quantization.quant_apir	   r
   r   %torchao.quantization.transform_moduler   r   torchao.sparsity.blocksparser   r%   r(   block_sparse_weightrD   ModulerJ   rL   semi_sparse_weightrS   strboolrX   r5   r&   r$   <module>rf      sE    ! %  2 , 
 ;& Ql Q Q .  ""9:HHOO# ;P\ P ,  ""89HHOO" XX__ : CG,88??,, %((//3!7!=>?, XX__	,r&   