o
    iz                  
   @   s6  d dl Z d dlmZ d dlmZm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mZ d dlmZmZ d d	lmZ d
d ZeG dd de
ZeZeedejjdefddZG dd de
ZeZeedejjdedejjfddZ	ddejjde
deeejjege f  dejjfddZ!dS )    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                 K   sn   | dt}g }|  D ]\}}|||r|d| di qtdddd}|| | |  |  dS )	zO
    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
sparsifier r"   O/home/ubuntu/.local/lib/python3.10/site-packages/torchao/sparsity/sparse_api.pyapply_fake_sparsity   s   
r$   c                   @   s"   e Zd ZU dZeed< dd ZdS )BlockSparseWeightConfig@   	blocksizec                 C      t jd d S )Nz(torchao.sparsity.BlockSparseWeightConfigtorch_C_log_api_usage_onceselfr"   r"   r#   __post_init__5      z%BlockSparseWeightConfig.__post_init__N)__name__
__module____qualname__r'   int__annotations__r/   r"   r"   r"   r#   r%   1   s   
 r%   moduleconfigc                 C   s8   |j }t| j|}tjj|dd| _tt	| | _
| S NF)requires_grad)r'   r   
from_denseweightr*   nn	Parametertypes
MethodTyper	   
extra_repr)r6   r7   r'   
new_weightr"   r"   r#   _block_sparse_weight_transform=   s
   rB   c                   @   s   e Zd ZdZdd ZdS )SemiSparseWeightConfigze
    Configuration for converting the weight of linear modules to semi-structured (2:4) sparsity
    c                 C   r(   )Nz'torchao.sparsity.SemiSparseWeightConfigr)   r-   r"   r"   r#   r/   N   r0   z$SemiSparseWeightConfig.__post_init__N)r1   r2   r3   __doc__r/   r"   r"   r"   r#   rC   I   s    rC   returnc                 C   s.   t | j}tjj|dd| _tt| | _| S r8   )	r   r;   r*   r<   r=   r>   r?   r	   r@   )r6   r7   rA   r"   r"   r#   _semi_sparse_weight_transformV   s   
rF   r   r   c                 C   s:   t jd tt| }t| ||du rtn||fd dS )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`

    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+   r,   r   typer
   r   )r   r7   r   handlerr"   r"   r#   	sparsify_a   s   $
rJ   )N)"r>   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_weightr<   ModulerB   rC   semi_sparse_weightrF   strboolrJ   r"   r"   r"   r#   <module>   sP   
