§
    Ó˜ºh‹m  ã                   ó  — d dl Z d dlmZ d dlmZmZmZ d dlZd dlm	Z	m
Z
 d dlmZmZmZmZmZmZmZmZmZmZ g d¢Z edd¦  «        Z G d	„ d
ej        ¦  «        Z	 ddej        dedefd„Z G d„ de¦  «        Z G d„ de¦  «        ZdS )é    N)Ú
namedtuple)ÚAnyÚCallableÚOptional)Ú)sparse_semi_structured_from_dense_cutlassÚ'sparse_semi_structured_to_dense_cutlass)
Úfallback_dispatcherÚsemi_sparse_addmmÚsemi_sparse_detachÚsemi_sparse_indicesÚsemi_sparse_linearÚsemi_sparse_mmÚsemi_sparse_scaled_mmÚsemi_sparse_tÚsemi_sparse_valuesÚsemi_sparse_view)ÚSparseSemiStructuredTensorÚ!SparseSemiStructuredTensorCUTLASSÚ$SparseSemiStructuredTensorCUSPARSELTÚto_sparse_semi_structuredÚ_SEMI_STRUCTURED_SPARSE_CONFIGz=sparse_min_rows sparse_min_cols dense_min_rows dense_min_colsc                   óÆ  — e Zd ZU dZdZeed<   eej	        e
f         ed<   dZeed<   dZeed<   dZeed<   eed	<   eeef         ed
<   eej                 ed<   eej                 ed<   eej                 ed<   eej                 ed<   eej                 ed<   eed<   eed<   g d¢Ze	 	 	 d(dej        deej                 deej                 deej                 deej                 deej                 dededefd„¦   «         Zdefd„Zdeee         eej        eeef         f         fd„Zedeej        eeef         dej        fd„¦   «         Zej        j        Zede fd„¦   «         Z!ed)d*d„¦   «         Z"edej        ddfd„¦   «         Z#ed ej        dej        fd!„¦   «         Z$d"„ Z%edej        dd fd#„¦   «         Z&dd$œd%ej        d&eej                 dej        fd'„Z'dS )+r   a¼  
    This class implements semi-structured sparsity as a Tensor subclass.

    Semi-structured sparsity describes a sparsity pattern where n in every 2n elements are sparse,
    depending on the datatype. It is also referred to as 2:4 sparsity or fine-grained
    structured sparsity.

    There are two backends available for semi_structred sparsity, either cuSPARSELt or CUTLASS.
    This class is meant to serve as a base class for both implementations. SparseSemiStructuredCUTLASS
    and SparseSemiStructuredCUSPARSELT both inherit from this class and define three backend-specific items.
    Note that as such, this class cannot be instantiated directly.

    -`_DTYPE_SHAPE_CONSTRAINTS` - A dictionary holding backend specific dense/sparse min shape constraints
    - `def from_dense()` - backend specific compression routines
    - `def _mm()` - backend specific mm op (either torch._cslt_sparse_mm or torch._sparse_semi_structured_(mm|addmm))
    r   Ú_DEFAULT_ALG_IDÚ_DTYPE_SHAPE_CONSTRAINTSFÚ_FORCE_CUTLASSÚ_FUSE_TRANSPOSEÚ_PROTOTYPE_WARNING_SHOWNÚBACKENDÚSPARSE_DISPATCHÚpackedÚmetaÚpacked_tÚmeta_tÚcompressed_swizzled_bitmaskÚfuse_transpose_cusparseltÚalg_id_cusparselt)r    r!   r"   r#   r$   ÚshapeÚrequires_gradc
                 ó¸  — | j         sTt          j        dt          ¦  «         d| _         |                      ¦   «          t
          j                             | ¦  «         |�|}
n|�|}
nt          d¦  «        ‚t
          j	         
                    | ||
j        |
j        |
j        |	¬¦  «        }||_        ||_        ||_        ||_        ||_        ||_        ||_        |S )a0  
        Create a new instance of the tensor subclass from the compressed sparse representation.

        We have the option to create the subclass with the compressed representations of both X and X', for training.
        For inference, we only need a single representation (either X or X'), while the corresponding other set will be None.

        Depending on the backend selected, certain fields will be set to None. (CUSPARSELT vs CUTLASS)

        Args:
            shape: The shape of the original dense tensor
            packed: The compressed representation of the original dense tensor
            meta: The metadata of the original dense tensor, if it is stored separately
            packed_t: The compressed representation of the transposed original dense tensor
            meta_t: The metadata of the transposed original dense tensor, if it is stored separately
            compressed_swizzled_bitmask: The masks used by the CUTLASS backend to determine which threads should
                                         participate in the computation. Used for pointwise ops.
            fuse_transpose_cusparselt: When running with cuSPARSELt, we have the option to fuse a transposition
                                       with a matmul, which is useful in the case of 2:4 sparse training.
            alg_id_cusparselt: The algorithm id to use when using cuSPARSELT, will have effect on performance

        Returns:
            torch.Tensor: A torch.Tensor wrapper subclass.

        Raises:
            ValueError: If all of the tensor arguments are None.
        zøThe PyTorch API of SparseSemiStructuredTensor is in prototype stage and will change in the near future. Please open a Github issue for features requests and see our documentation on the torch.sparse module for further information about the project.TNz3At least one of packed or packed_t must be provided)ÚdeviceÚdtypeÚlayoutr(   )r   ÚwarningsÚwarnÚUserWarningÚ_load_dispatch_tableÚtorchÚ_dynamoÚallow_in_graphÚ
ValueErrorÚTensorÚ_make_wrapper_subclassr*   r+   r,   r    r!   r"   r#   r$   r%   r&   )Úclsr'   r    r!   r"   r#   r$   r%   r&   r(   Úprevious_tensorÚtensors               úd/var/www/html/services/rag-service/venv/lib/python3.11/site-packages/torch/sparse/semi_structured.pyÚ__new__z"SparseSemiStructuredTensor.__new__K   s   € ðN Ô+ð 	.ÝŒMðHõ
 ñô ð ð ,0ˆCÔ(ð
 ×$Ò$Ñ&Ô&Ð&õ ŒM×(Ò(¨Ñ-Ô-Ð-àÐØ$ˆOˆOØÐ!Ø&ˆOˆOåÐRÑSÔSÐSå”×4Ò4ØØØ"Ô)Ø!Ô'Ø"Ô)Ø'ð 5ñ 
ô 
ˆð ˆŒØˆŒØ"ˆŒØˆŒØ-HˆÔ*Ø+DˆÔ(Ø#4ˆÔ Øˆó    Úreturnc                 óT   — t          | d¦  «        sJ ‚| j        j        › d| j        › d�S )Nr'   z(shape=ú))ÚhasattrÚ	__class__Ú__name__r'   )Úselfs    r:   Ú__repr__z#SparseSemiStructuredTensor.__repr__Ÿ   s6   € Ý�t˜WÑ%Ô%Ð%Ð%Ð%Ø”.Ô)Ð?Ð?°$´*Ð?Ð?Ð?Ð?r<   c                 óŠ   ‡ — t          t          ˆ fd„‰ j        ¦  «        ¦  «        }‰ j        ‰ j        ‰ j        ‰ j        f}||fS )Nc                 ó(   •— t          ‰| ¦  «        d uS ©N)Úgetattr)ÚxrC   s    €r:   ú<lambda>z?SparseSemiStructuredTensor.__tensor_flatten__.<locals>.<lambda>§   s   ø€ �W T¨1Ñ-Ô-°TÐ9€ r<   )ÚlistÚfilterÚ	__slots__r'   r%   r&   r(   )rC   Úinner_tensorsÚtensor_metas   `  r:   Ú__tensor_flatten__z-SparseSemiStructuredTensor.__tensor_flatten__£   sZ   ø€ õ ÝÐ9Ð9Ð9Ð9¸4¼>ÑJÔJñ
ô 
ˆð ŒJØÔ*ØÔ"ØÔð	
ˆð ˜kÐ)Ð)r<   rO   c                 ó   — |\  }}}} | ||                      dd ¦  «        |                      dd ¦  «        |                      dd ¦  «        |                      dd ¦  «        |                      dd ¦  «        |||¬¦	  «	        S )Nr    r!   r"   r#   r$   ©	r'   r    r!   r"   r#   r$   r%   r&   r(   )Úget)	r7   rN   rO   Ú
outer_sizeÚouter_strider'   r%   r&   r(   s	            r:   Ú__tensor_unflatten__z/SparseSemiStructuredTensor.__tensor_unflatten__±   s¢   € ð NYÑJˆÐ(Ð*;¸]ØˆsØØ ×$Ò$ X¨tÑ4Ô4Ø×"Ò" 6¨4Ñ0Ô0Ø"×&Ò& z°4Ñ8Ô8Ø ×$Ò$ X¨tÑ4Ô4Ø(5×(9Ò(9Ø-¨tñ)ô )ð '@Ø/Ø'ð
ñ 
ô 
ð 	
r<   c                 ó˜   — |j         | j        vrt          | j        › d|j        › d�¦  «        ‚ | j        |j                  ||||¦  «        S )NzI only supports a specific set of operations, can't perform requested op (r?   )Ú_overloadpacketr   ÚNotImplementedErrorrB   )r7   ÚfuncÚtypesÚargsÚkwargss        r:   Ú__torch_dispatch__z-SparseSemiStructuredTensor.__torch_dispatch__Ê   sp   € àÔ sÔ':Ð:Ð:Ý%Ø”<ð @ð @Ø/3¬}ð@ð @ð @ñô ð ð 9ˆsÔ" 4Ô#7Ô8¸¸uÀdÈFÑSÔSÐSr<   Nc                 ó6  — t          | dd¦  «        �€„t          j        j        j        t
          t          j        j        j        t          t          j        j        j        t          t          j        j        j
        t          t          j        j        j        t          t          j        j        j        t          t          j        j        j        t           t          j        j        j        t$          t          j        j        j        t$          t          j        j        j        t*          t          j        j        j        t.          t          j        j        j        t          t          j        j        j        t4          i| _        |�| j                             |¦  «         dS dS dS )zT
        Loads the op overload sparse dispatch table for the current class.
        r   N)rH   r1   ÚopsÚatenÚvaluesr   Úindicesr   Úis_same_sizer	   Údetach_Údetachr   Útr   Úviewr   Úmmr   ÚmatmulÚaddmmr
   Úlinearr   Ú_to_copyÚ
_scaled_mmr   r   Úupdate)r7   Úcustom_dispatch_tables     r:   r0   z/SparseSemiStructuredTensor._load_dispatch_tableÓ   sý   € õ
 �3Ð)¨4Ñ0Ô0Ñ8å”	”Ô%Õ'9Ý”	”Ô&Õ(;Ý”	”Ô+Õ-@Ý”	”Ô&Õ(;Ý”	”Ô%Õ'9Ý”	”Ô ¥-Ý”	”Ô#Õ%5Ý”	”Ô!¥>Ý”	”Ô%¥~Ý”	”Ô$Õ&7Ý”	”Ô%Õ'9Ý”	”Ô'Õ)<Ý”	”Ô)Õ+@ð#ˆCÔð %Ð0ØÔ#×*Ò*Ð+@ÑAÔAÐAÐAÐAð# 9Ð8ð  1Ð0r<   Úoriginal_tensorc           	      ó.  — |j         st          d|j        › d�¦  «        ‚|                     ¦   «         dk    r%t          d|                     ¦   «         › d�¦  «        ‚|                     ¦   «         st          d¦  «        ‚|j        | j        vrt          d|j        › d| › d	�¦  «        ‚|j        \  }}| j        |j                 j        }| j        |j                 j	        }||k     s||z  s||k     s||z  rt          d
|j        › d|› d|› d�¦  «        ‚dS )z_
        Assert that the given tensor is valid for semi-structured sparse compression.
        zError original_tensor.device= z= is not supported! Only CUDA tensors are currently supported.é   zError original_tensor.dim = z; is not supported! Only 2d tensors are currently supported.zXError original_tensor is not contiguous!Only contiguous tensors are currently supported.zError original_tensor.dtype z is not a supported dtype for ú!zError original_tensor.shape zS is not supported! Both dimensions must be larger or equal than and a multiple of (z, r?   N)
Úis_cudaÚRuntimeErrorr*   ÚdimÚis_contiguousr+   r   r'   Úsparse_min_rowsÚsparse_min_cols)r7   rq   ÚmÚnÚmin_rowsÚmin_colss         r:   Ú _validate_device_dim_dtype_shapez;SparseSemiStructuredTensor._validate_device_dim_dtype_shapeë   s�  € ð Ô&ð 	Ýð=°Ô1Gð =ð =ð =ñô ð ð ×ÒÑ Ô  AÒ%Ð%Ýð;¨×/BÒ/BÑ/DÔ/Dð ;ð ;ð ;ñô ð ð ×,Ò,Ñ.Ô.ð 	ÝðCñô ð ð Ô ¨Ô(DÐDÐDÝØj¨Ô/DÐjÐjÐdgÐjÐjÐjñô ð ð
 Ô$‰ˆˆ1ØÔ/°Ô0EÔFÔVˆØÔ/°Ô0EÔFÔVˆØˆxŠ<ˆ<˜1˜x™<ˆ<¨1¨xª<¨<¸1¸x¹<¨<åðk¨Ô/Dð kð kØS[ðkð kØ_gðkð kð kñô ð ð ,8¨<r<   Údense_inputc                 óP  — |                      ¦   «         dk    sJ ‚|j        \  }}| j        |j                 j        }| j        |j                 j        }||k     s||z  r| |z  nd}||k     s||z  r| |z  nd}|s|r)t          j        j         	                    |d|d|f¦  «        S |S )z¢
        Calculates padding for dense tensor and pads tensor if necessary.
        If padding is not required, this function returns the original tensor.
        rs   r   )
rw   r'   r   r+   Údense_min_rowsÚdense_min_colsr1   ÚnnÚ
functionalÚpad)r7   r€   r{   r|   r}   r~   Úto_pad_mÚto_pad_ns           r:   Ú_pad_dense_inputz+SparseSemiStructuredTensor._pad_dense_input  sÌ   € ð �ŠÑ Ô  AÒ%Ð%Ð%Ð%ð Ô ‰ˆˆ1ØÔ/°Ô0AÔBÔQˆØÔ/°Ô0AÔBÔQˆð %&¨¢L L°A¸±L L�A�2˜‘=�=ÀaˆØ$%¨¢L L°A¸±L L�A�2˜‘=�=ÀaˆØð 	�xð 	Ý”8Ô&×*Ò*¨;¸¸HÀaÈÐ8RÑSÔSÐSàÐr<   c                 ó„   — | j         d         }t          j        | t          j        || j        | j        ¬¦  «        ¦  «        S )Néÿÿÿÿ)r+   r*   )r'   r1   ri   Úeyer+   r*   )rC   Úcols     r:   Úto_densez#SparseSemiStructuredTensor.to_dense,  s4   € ØŒj˜ŒnˆÝŒx˜�eœi¨°4´:ÀdÄkÐRÑRÔRÑSÔSÐSr<   c                 ó   — t           ‚rG   ©rY   ©r7   rq   s     r:   Ú
from_densez%SparseSemiStructuredTensor.from_dense0  s   € å!Ð!r<   ©ÚbiasÚBr”   c                ó   — t           ‚rG   r�   )rC   r•   r”   r]   s       r:   Ú_mmzSparseSemiStructuredTensor._mm4  s
   € õ "Ð!r<   )Fr   FrG   )r=   N)(rB   Ú
__module__Ú__qualname__Ú__doc__r   ÚintÚ__annotations__Údictr1   r+   r   r   Úboolr   r   Ústrr   r   r5   rM   ÚstaticmethodÚSizer;   rD   ÚtuplerK   rP   ÚclassmethodrV   Ú_CÚ_disabled_torch_function_implÚ__torch_function__r   r^   r0   r   r‰   rŽ   r’   r—   © r<   r:   r   r   &   sÉ  € € € € € € ðð ð" €O�SÐÐÑØ" 5¤;Ð0NÐ#NÔOÐOÐOÑOØ €N�DÐ Ð Ñ Ø!€O�TÐ!Ð!Ñ!Ø%*Ð˜dÐ*Ð*Ñ*à€L€L�LØ˜( HÐ,Ô-Ð-Ð-Ñ-à�U”\Ô"Ð"Ð"Ñ"Ø
�5”<Ô
 Ð Ð Ñ Ø�u”|Ô$Ð$Ð$Ñ$Ø�U”\Ô"Ð"Ð"Ñ"Ø!)¨%¬,Ô!7Ð7Ð7Ñ7Ø#Ð#Ð#Ñ#ØÐÐÑàWÐWÐW€Iàð +0Ø!"Ø#ðQð QàŒzðQð ˜œÔ&ðQð �u”|Ô$ð	Qð
 ˜5œ<Ô(ðQð ˜œÔ&ðQð &.¨e¬lÔ%;ðQð $(ðQð ðQð ðQð Qð Qñ „\ðQðf@˜#ð @ð @ð @ð @ð*à	ˆt�CŒy˜% ¤
¨D°#°tÐ ;Ô<Ð<Ô	=ð*ð *ð *ð *ð ð
ð ˜5œ: t¨S°$Ð6Ô7ð
ð 
Œð
ð 
ð 
ñ „[ð
ð, œÔ?ÐàðT¸cð Tð Tð Tñ „[ðTð ðBð Bð Bð Bñ „[ðBð. ð(¸u¼|ð (ÐPTð (ð (ð (ñ „[ð(ðT ð¨5¬<ð ¸E¼Lð ð ð ñ „[ðð*Tð Tð Tð ð"¨¬ð "Ð:Vð "ð "ð "ñ „[ð"ð (,ð	"ð "ð "àŒ<ð"ð �u”|Ô$ð	"ð 
Œð"ð "ð "ð "ð "ð "r<   r   Frq   Ú
transposedr=   c                 óÄ   — |rt          j        dt          d¬¦  «         t          j        rt
          j        j        nt
          j        j        }| 	                    | ¦  «        S )a	  
    This function converts a dense tensor into a sparse semi-structured tensor.
    It will return a SparseSemiStructuredTensor, a subclass of torch.Tensor.

    This function will check to ensure the dense tensor has the right dtype, size, dims, and device.
    We currently only support semi-structured sparse tensors for 2d CUDA tensors.
    Additionally, your tensor must be a positive multiple of the minimum sparse block size, given in
    `_DTYPE_TO_SHAPE_CONSTRAINTS` for each dtype (float32, float16, bfloat16, int8).

    Args:
        original_tensor (Tensor): the dense tensor to convert
        transposed (bool, optional): deprecated arg to be removed in another release. Do not use.
    Returns:
        SparseSemiStructuredTensor: A sparse semi-structured tensor created from the given original_tensor
    Raises:
        None
    Example:
        >>> # xdoctest: +REQUIRES(env:TORCH_DOCTEST_CUDA)
        >>> A = torch.Tensor([0, 0, 1, 1]).tile((128, 32)).half().cuda()
        tensor([[0., 0., 1.,  ..., 0., 1., 1.],
                [0., 0., 1.,  ..., 0., 1., 1.],
                [0., 0., 1.,  ..., 0., 1., 1.],
                ...,
                [0., 0., 1.,  ..., 0., 1., 1.],
                [0., 0., 1.,  ..., 0., 1., 1.],
                [0., 0., 1.,  ..., 0., 1., 1.]], device='cuda:0', dtype=torch.float16)
        >>> A_sparse = to_sparse_semi_structured(A)
        SparseSemiStructuredTensor(shape=torch.Size([128, 128]))
        >>> A_sparse.values()
        tensor([[1., 1., 1.,  ..., 1., 1., 1.],
                [1., 1., 1.,  ..., 1., 1., 1.],
                [1., 1., 1.,  ..., 1., 1., 1.],
                ...,
                [1., 1., 1.,  ..., 1., 1., 1.],
                [1., 1., 1.,  ..., 1., 1., 1.],
                [1., 1., 1.,  ..., 1., 1., 1.]], device='cuda:0', dtype=torch.float16),
        >>> A_sparse.indices()
        tensor([[-4370, -4370, -4370,  ..., -4370, -4370, -4370],
                [-4370, -4370, -4370,  ..., -4370, -4370, -4370],
                [-4370, -4370, -4370,  ..., -4370, -4370, -4370],
                ...,
                [-4370, -4370, -4370,  ..., -4370, -4370, -4370],
                [-4370, -4370, -4370,  ..., -4370, -4370, -4370],
                [-4370, -4370, -4370,  ..., -4370, -4370, -4370]], device='cuda:0', dtype=torch.int16))
    z­Setting transpose from `to_sparse_semi_structured` is deprecated and will be removed in a future release. `SparseSemiStructuredTensor` only support contiguous input tensors.rs   )Ú
stacklevel)
r-   r.   ÚFutureWarningr   r   r1   Úsparser   r   r’   )rq   r¨   ÚSPARSE_SUBCLASSs      r:   r   r   >  sn   € ðb ð 
ÝŒðRõ Øð	
ñ 	
ô 	
ð 	
õ &Ô4ð	?�ŒÔ6Ð6åŒ\Ô>ð ð ×%Ò% oÑ6Ô6Ð6r<   c                   ó^  ‡ — e Zd ZdZdZej         edddd¦  «        ej         edddd¦  «        ej	         edddd¦  «        ej
         edddd¦  «        iZed	ej        d
d fd„¦   «         Zˆ fd„Ze	 dd	ej        d
dfd„¦   «         Zddœdej        deej                 d
ej        fd„Zˆ xZS )r   a¤  
    This class implements semi-structured sparsity for the CUTLASS backend.


    In this implementation, the specified elements and metadata are stored separately,
    in packed and meta respectively.

    When _FORCE_CUTLASS is set, or when cuSPARSELt is not available, this subclass calls into _sparse_semi_structured_(mm|addmm) and
    sparse_semi_structured_from_dense for conversion to the compressed format.
    Úcutlassé   é€   é    é@   é   é   rq   r=   c           	      óˆ   — |                       |¦  «         t          |¦  «        \  }} | |j        ||d d d |j        ¬¦  «        S )N©r    r!   r"   r#   r$   r(   )r   r   r'   r(   )r7   rq   Úsparse_tensor_cutlassÚmeta_tensor_cutlasss       r:   r’   z,SparseSemiStructuredTensorCUTLASS.from_dense–  sd   € ð 	×,Ò,¨_Ñ=Ô=Ð=õ 6°oÑFÔFñ	
Ø!ØàˆsØÔ!Ø(Ø$ØØØ(,Ø)Ô7ð
ñ 
ô 
ð 	
r<   c                 ó¸   •— | j         �| j        €J ‚| j         j        dk    rt          | j        | j         ¦  «        nt	          ¦   «                              ¦   «         S )Nrs   )r!   r    Úndimr   ÚsuperrŽ   )rC   rA   s    €r:   rŽ   z*SparseSemiStructuredTensorCUTLASS.to_dense©  sa   ø€ ØŒyÐ$¨¬Ð)@Ð)@Ð)@ð ŒyŒ~ Ò"Ð"õ	 4Ø”Ø”	ñô ð õ
 ‘”×!Ò!Ñ#Ô#ð	
r<   Ú r   c           	      ój   — t          j        ||d¬¦  «        \  }}}}} | |j        |||||d¬¦  «        S )að  
        This function takes in a unpruned dense tensor and runs a (branchless) static sort across a 4x4 tile.

        It greedily picks the largest values in the tile, upholding the 2:4 sparsity constraint across both rows and columns.
        The algorithm used to prune the matrix is implemented in `_sparse_semi_structured_tile`.

        Then it creates the packed and meta tensors for the compressed sparse representation of the pruned dense tensor.
        It also calculates the packed_t and meta_t tensors for the compressed sparse representation of the transposed
        pruned dense tensor.
        Since we cannot transpose the compressed representations, we store both for the fw/bw pass respectively.

        Finally, this function also computes a compressed swizzled bitmask that encodes the sparsity pattern
        This can be used in the backward pass to mask the gradients.

        [9 1 7 4]                       [9 0 7 0]
        [1 2 3 0]                       [0 2 0 0]
        [8 3 5 4] -> prune 4x4 tile  -> [8 0 0 4] -> pack to CUTLASS semi-structured -> packed
        [1 2 6 2]                       [0 0 6 2]                                    -> metadata

                                                  -> pack to transposed CUTLASS      -> packed_t
                                                     semi-structured representation  -> metadata_t

                                                  -> compute swizzled bitmask        -> compressed_swizzled_bitmask


        The equivalent PyTorch code to create the same five outputs from the dense tensor can be found below:
        ```
        from torch.sparse import SparseSemiStructuredTensorCUTLASS
        from torch.sparse._semi_structured_conversions import _sparse_semi_structured_tile, _compute_compressed_swizzled_bitmask

        pruned = _sparse_semi_structured_tile(dense)
        packed_cutlass, meta_cutlass = sparse_semi_structured_from_dense_cutlass(pruned)
        packed_t_cutlass, meta_t_cutlass = sparse_semi_structured_from_dense_cutlass(pruned.t().contiguous())
        bitmask = _compute_compressed_swizzled_bitmask(pruned)

        SparseSemiStructuredTensorCUTLASS(dense.shape, packed_cutlass, meta_cutlass, packed_t_cutlass, meta_t_cutlass, bitmask)
        ```
        T©Ú	algorithmÚuse_cutlassFr·   ©r1   Ú_sparse_semi_structured_tiler'   ©r7   rq   rÀ   r    r!   r"   r#   r$   s           r:   Úprune_dense_static_sortz9SparseSemiStructuredTensorCUTLASS.prune_dense_static_sort´  sh   € õb Ô.Ø y¸dð
ñ 
ô 
ñ	
ØØØØØ'ð
 ˆsØÔ!ØØØØØ(CØð
ñ 
ô 
ð 	
r<   Nr“   r•   r”   c                ó¨  — t          |t          ¦  «        rt          d¦  «        ‚| j        j        }| j        dk    s|j        dk    rt          d|› d�¦  «        ‚| j        �| j        €t          d|› d�¦  «        ‚|€!t          j
        | j        | j        |¦  «        }n!t          j        || j        | j        |¦  «        }|d | j        d         …         S )NúZ`SparseSemiStructuredTensor @ SparseSemiStructuredTensor` is not supported by the hardwarers   ú`ú)` matmul: Broadcasting is not implementedú$` matmul: operation is not supportedr   )Ú
isinstancer   r4   rA   rB   r»   rY   r    r!   r1   Ú_sparse_semi_structured_mmÚ_sparse_semi_structured_addmmr'   )rC   r•   r”   r]   Úcls_nameÚress         r:   r—   z%SparseSemiStructuredTensorCUTLASS._mmó  sõ   € õ �aÕ3Ñ4Ô4ð 	ÝØlñô ð ð ”>Ô*ˆØŒ9˜Š>ˆ>˜QœV qš[˜[Ý%ØG�HÐGÐGÐGñô ð ð Œ;Ð $¤)Ð"3Ý%ØB�HÐBÐBÐBñô ð ð ˆ|ÝÔ6°t´{ÀDÄIÈqÑQÔQ��åÔ9Ø˜$œ+ t¤y°!ñô �ð �˜œ Aœ�Ô'Ð'r<   ©r½   )rB   r˜   r™   rš   r   r1   Úint8r   Úfloat16Úbfloat16Úfloat32r   r£   r5   r’   rŽ   rÅ   r   r—   Ú__classcell__)rA   s   @r:   r   r   ‚  sj  ø€ € € € € ð	ð 	ð €GàŒ
Ð2Ð2°2°s¸BÀÑCÔCØŒÐ5Ð5°b¸"¸aÀÑCÔCØŒÐ6Ð6°r¸2¸qÀ!ÑDÔDØŒÐ5Ð5°b¸"¸aÀÑCÔCð	 Ðð ð
Ø#œlð
à	,ð
ð 
ð 
ñ „[ð
ð$	
ð 	
ð 	
ð 	
ð 	
ð à68ð<
ð <
Ø#œlð<
à	%ð<
ð <
ð <
ñ „[ð<
ð~ BFð(ð (ð (Ø”ð(Ø(0°´Ô(>ð(à	Œð(ð (ð (ð (ð (ð (ð (ð (r<   r   c                   óN  — e Zd ZdZdZej         edddd¦  «        ej         edddd¦  «        ej	         edddd¦  «        ej
         edddd¦  «        iZedej        dd fd„¦   «         Ze	 ddej        dd
fd„¦   «         Zddœdej        deej                 dej        fd„ZdS )r   a‚  
    The cuSPARSELt backend expects the specified elements and the metadata to be stored in a single tensor:
    packed = [ specified elements of original tensor | metadata ]
    For an original tensor of size (m, k) we expect the first m * k // 2 elements to be the kept elements
    The rest of the tensor is metadata. Since there is only one tensor, we only use the packed and packed_t
    attributes respectively.

    cuSPARSELt also supports transposition fusion, which is necessary for performant 2:4 sparse training, as well
    as specifying alg_id, a config that affects the performance of the matmul depending on matmul sizes.
    Ú
cusparseltr²   r°   r´   rq   r=   c                 ó´   — |                       |¦  «          | |j        t          j        |¦  «        d d d d t          j        t          j        |j        ¬¦	  «	        S )NrR   )r   r'   r1   Ú_cslt_compressr   r   r   r(   r‘   s     r:   r’   z/SparseSemiStructuredTensorCUSPARSELT.from_dense!  sc   € ð 	×,Ò,¨_Ñ=Ô=Ð=ØˆsØ!Ô'ÝÔ'¨Ñ8Ô8ØØØØ(,Ý&@Ô&PÝ8ÔHØ)Ô7ð

ñ 

ô 

ð 
	
r<   r½   r   c           	      ój   — t          j        ||d¬¦  «        \  }}}}} | |j        |||||d¬¦  «        S )a  
        This function does the same thing as described in SparseSemiStructuredCUTLASS, but uses the cuSPASRELt metadata
        layout and sparse matmul.

        The only functional difference is that cuSPARSELt stores `metadata` and `packed` together into a single tensor.

        [9 1 7 4]                       [9 0 7 0]
        [1 2 3 0]                       [0 2 0 0]
        [8 3 5 4] -> prune 4x4 tile  -> [8 0 0 4] -> pack to cuSPARSELT semi-structured -> packed
        [1 2 6 2]                       [0 0 6 2]

                                                  -> pack to transposed cuSPARSELt      -> packed_t
                                                     semi-structured representation

                                                  -> compute swizzled bitmask           -> compressed_swizzled_bitmask


        The equivalent PyTorch code to create the same three outputs from the dense tensor can be found below:
        ```
        from torch.sparse import SparseSemiStructuredTensorCUSPARSELT
        from torch.sparse._semi_structured_conversions import _sparse_semi_structured_tile, _compute_compressed_swizzled_bitmask

        pruned = _sparse_semi_structured_tile(dense)
        packed_cusparselt = torch._cslt_compress(pruned)
        packed_t_cusparselt = torch._cslt_compress(pruned.t().contiguous())
        bitmask = _compute_compressed_swizzled_bitmask(pruned)

        SparseSemiStructuredTensorCUSPARSELT(dense.shape, packed_cutlass, None, packed_t_cutlass, None, bitmask)
        ```
        Fr¿   r·   rÂ   rÄ   s           r:   rÅ   z<SparseSemiStructuredTensorCUSPARSELT.prune_dense_static_sort2  sh   € õP Ô.Ø y¸eð
ñ 
ô 
ñ	
ØØØØØ'ð
 ˆsØÔ!ØØØØØ(CØð
ñ 
ô 
ð 	
r<   Nr“   r•   r”   c                óê  — t          |t          ¦  «        rt          d¦  «        ‚| j        dk    s|j        dk    rt	          d| j        j        › d�¦  «        ‚|j        | j        k    rWt	          d| j        j        › dt          | j	        ¦  «        › dt          |j	        ¦  «        › d| j        › d|j        › d	�¦  «        ‚|�g|j        | j        k    rWt	          d| j        j        › dt          | j	        ¦  «        › dt          |j	        ¦  «        › d
| j        › d|j        › d�¦  «        ‚| j        t          j        k    rOt	          d| j        j        › dt          | j	        ¦  «        › dt          |j	        ¦  «        › d| j        › d�	¦  «        ‚| j        €t	          d| j        j        › d�¦  «        ‚t          j        | j        ||| j        | j        ¬¦  «        }| j        r|                     ¦   «         n|S )NrÇ   rs   rÈ   rÉ   z` matmul: trying to do `A=z @ B=z`, with A.dtype=z and B.dtype=zH. This operation is only supported when A and B have the same data type.z + C`, with A.dtype=B.dtype=z and C.dtype=zK. This operation is only supported when A, B and C have the same data type.z`, with A.dtype=B.dtype=zO. mm is not supported for float8_e4m3fn, please use `torch._scaled_mm` instead.rÊ   )r”   Útranspose_resultÚalg_id)rË   r   r4   r»   rY   rA   rB   r+   r¢   r'   r1   Úfloat8_e4m3fnr    Ú_cslt_sparse_mmr%   r&   rg   )rC   r•   r”   r]   rÏ   s        r:   r—   z(SparseSemiStructuredTensorCUSPARSELT._mmh  s�  € õ �aÕ3Ñ4Ô4ð 	ÝØlñô ð ð Œ9˜Š>ˆ>˜QœV qš[˜[Ý%ØV�D”NÔ+ÐVÐVÐVñô ð ð Œ7�d”jÒ Ð Ý%ðY�D”NÔ+ð Yð YÅuÈTÌZÑGXÔGXð Yð YÕ_dÐefÔelÑ_mÔ_mð Yð YØ $¤
ðYð YØ9:¼ðYð Yð Yñô ð ð
 Ð ¤
¨d¬jÒ 8Ð 8Ý%ð\�D”NÔ+ð \ð \ÅuÈTÌZÑGXÔGXð \ð \Õ_dÐefÔelÑ_mÔ_mð \ð \Ø(,¬
ð\ð \ØABÄð\ð \ð \ñô ð ð Œ:�Ô,Ò,Ð,Ý%ð`�D”NÔ+ð `ð `ÅuÈTÌZÑGXÔGXð `ð `Õ_dÐefÔelÑ_mÔ_mð `ð `Ø(,¬
ð`ð `ð `ñô ð ð
 Œ;ÐÝ%ØQ�D”NÔ+ÐQÐQÐQñô ð õ Ô'Ø”ØØØ!%Ô!?ØÔ-ðñ ô ˆCð #Ô<ÐE�3—5’5‘7”7�7À#ÐEr<   rÐ   )rB   r˜   r™   rš   r   r1   rÞ   r   rÑ   rÒ   rÓ   r   r£   r5   r’   rÅ   r   r—   r§   r<   r:   r   r     sR  € € € € € ð	ð 	ð €GàÔÐ;Ð;¸BÀÀBÈÑKÔKØŒ
Ð2Ð2°2°r¸2¸rÑBÔBØŒÐ5Ð5°b¸"¸aÀÑCÔCØŒÐ6Ð6°r¸2¸qÀ!ÑDÔDð	 Ðð ð
Ø#œlð
à	/ð
ð 
ð 
ñ „[ð
ð  à68ð3
ð 3
Ø#œlð3
à	%ð3
ð 3
ð 3
ñ „[ð3
ðl BFð*Fð *Fð *FØ”ð*FØ(0°´Ô(>ð*Fà	Œð*Fð *Fð *Fð *Fð *Fð *Fr<   r   )F)r-   Úcollectionsr   Útypingr   r   r   r1   Ú)torch.sparse._semi_structured_conversionsr   r   Ú!torch.sparse._semi_structured_opsr	   r
   r   r   r   r   r   r   r   r   Ú__all__r   r5   r   rž   r   r   r   r§   r<   r:   ú<module>rå      s  ðà €€€Ø "Ð "Ð "Ð "Ð "Ð "Ø *Ð *Ð *Ð *Ð *Ð *Ð *Ð *Ð *Ð *à €€€ðð ð ð ð ð ð ð ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ðð ð €ð ", Ø$ØCñ"ô "Ð ðU"ð U"ð U"ð U"ð U" ¤ñ U"ô U"ð U"ðt ðA7ð A7Ø”\ðA7àðA7ð  ðA7ð A7ð A7ð A7ðHH(ð H(ð H(ð H(ð H(Ð(Bñ H(ô H(ð H(ðVEFð EFð EFð EFð EFÐ+Eñ EFô EFð EFð EFð EFr<   