§
    Ë²Åj&p  ã                   ó"  — d dl Z d dlmZ d dlmZmZmZ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ÚDictÚListÚOptionalÚTuple)Ú)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 implementes 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 insantiated directly.

    -`_DTYPE_SHAPE_CONSTRAINTS` - A dictionary holding backend specific dense/sparse min shape constraints
    - `def from_dense()` - backend specific compression routines
    - `def _mm()` - backend specifc 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¦  «        ‚|
j	        |
j
        |
j        |	dœ}t          j        j        | |fi |¤Ž}||_        ||_        ||_        ||_        ||_        ||_        ||_        |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Ú
ValueErrorr-   r.   r/   ÚTensorÚ_make_wrapper_subclassr#   r$   r%   r&   r'   r(   r)   )Úclsr*   r#   r$   r%   r&   r'   r(   r)   r+   Úprevious_tensorÚkwargsÚtensors                úMC:\Projects\Historical\venv\Lib\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°S¸%ÐJÐJÀ6ÐJÐJˆàˆŒØˆŒØ"ˆŒØˆŒØ-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)ÚxrG   s    €r>   ú<lambda>z?SparseSemiStructuredTensor.__tensor_flatten__.<locals>.<lambda>¦   s   ø€ �W T¨1Ñ-Ô-°TÐ9€ r@   )ÚlistÚfilterÚ	__slots__r*   r(   r)   r+   )rG   Úinner_tensorsÚtensor_metas   `  r>   Ú__tensor_flatten__z-SparseSemiStructuredTensor.__tensor_flatten__¢   sZ   ø€ õ ÝÐ9Ð9Ð9Ð9¸4¼>ÑJÔJñ
ô 
ˆð ŒJØÔ*ØÔ"ØÔð	
ˆð ˜kÐ)Ð)r@   rS   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)	r:   rR   rS   Ú
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 (rC   )Ú_overloadpacketr"   ÚNotImplementedErrorrF   )r:   ÚfuncÚtypesÚargsr<   s        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)rL   r4   ÚopsÚatenÚvaluesr   Úindicesr   Úis_same_sizer   Údetach_Údetachr   Útr   Úviewr   Úmmr   ÚmatmulÚaddmmr   Úlinearr   Ú_to_copyÚ
_scaled_mmr   r"   Úupdate)r:   Úcustom_dispatch_tables     r>   r3   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, rC   N)
Úis_cudaÚRuntimeErrorr-   ÚdimÚis_contiguousr.   r   r*   Úsparse_min_rowsÚsparse_min_cols)r:   rt   Ú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.
        rv   r   )
rz   r*   r   r.   Údense_min_rowsÚdense_min_colsr4   ÚnnÚ
functionalÚpad)r:   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*   r4   rl   Úeyer.   r-   )rG   Úcols     r>   Úto_densez#SparseSemiStructuredTensor.to_dense+  s4   € ØŒj˜ŒnˆÝŒx˜�eœi¨°4´:ÀdÄkÐRÑRÔRÑSÔSÐSr@   c                 ó   — t           ‚rK   ©r]   ©r:   rt   s     r>   Ú
from_densez%SparseSemiStructuredTensor.from_dense/  s   € å!Ð!r@   ©ÚbiasÚBr—   c                ó   — t           ‚rK   r“   )rG   r˜   r—   r<   s       r>   Ú_mmzSparseSemiStructuredTensor._mm3  s
   € õ "Ð!r@   )Fr   FrK   )rA   N)(rF   Ú
__module__Ú__qualname__Ú__doc__r   ÚintÚ__annotations__r   r4   r.   r   r   Úboolr   r    Ústrr   r   r8   rQ   ÚstaticmethodÚSizer?   rH   r	   r   rT   ÚclassmethodrZ   Ú_CÚ_disabled_torch_function_implÚ__torch_function__r   ra   r3   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Ø!"Ø#ðPð PàŒzðPð ˜œÔ&ðPð �u”|Ô$ð	Pð
 ˜5œ<Ô(ðPð ˜œÔ&ðPð &.¨e¬lÔ%;ðPð $(ðPð ðPð ðPð Pð Pñ „\ðPðd@˜#ð @ð @ð @ð @ð*à	ˆ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   Frt   Ú
transposedrA   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 mininum 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.rv   )Ú
stacklevel)
r0   r1   ÚFutureWarningr   r   r4   Úsparser   r   r•   )rt   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 seprately,
    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é   é€   é    é@   é   é   rt   rA   c           	      óˆ   — |                       |¦  «         t          |¦  «        \  }} | |j        ||d d d |j        ¬¦  «        S )N©r#   r$   r%   r&   r'   r+   )r‚   r
   r*   r+   )r:   rt   Ú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 )Nrv   )r$   r#   Úndimr   Úsuperr‘   )rG   rE   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¸   ©r4   Ú_sparse_semi_structured_tiler*   ©r:   rt   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 hardwarerv   ú`ú)` matmul: Broadcasting is not implementedú$` matmul: operation is not supportedr   )Ú
isinstancer   r7   rE   rF   r¼   r]   r#   r$   r4   Ú_sparse_semi_structured_mmÚ_sparse_semi_structured_addmmr*   )rG   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¾   )rF   r›   rœ   r�   r!   r4   Úint8r   Úfloat16Úbfloat16Úfloat32r   r¤   r8   r•   r‘   rÆ   r   rš   Ú__classcell__)rE   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µ   rt   rA   c                 ó´   — |                       |¦  «          | |j        t          j        |¦  «        d d d d t          j        t          j        |j        ¬¦	  «	        S )NrV   )r‚   r*   r4   Ú_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_sort1  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È   rv   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   r7   r¼   r]   rE   rF   r.   Útupler*   r4   Úfloat8_e4m3fnr#   Ú_cslt_sparse_mmr(   r)   rj   )rG   r˜   r—   r<   rÐ   s        r>   rš   z(SparseSemiStructuredTensorCUSPARSELT._mmg  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Ñ   )rF   r›   rœ   r�   r!   r4   rà   r   rÒ   rÓ   rÔ   r   r¤   r8   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)!r0   Úcollectionsr   Útypingr   r   r   r   r   r	   r4   Ú)torch.sparse._semi_structured_conversionsr
   r   Ú!torch.sparse._semi_structured_opsr   r   r   r   r   r   r   r   r   r   Ú__all__r   r8   r   r    r   r   r   r¨   r@   r>   ú<module>rç      s  ðà €€€Ø "Ð "Ð "Ð "Ð "Ð "Ø =Ð =Ð =Ð =Ð =Ð =Ð =Ð =Ð =Ð =Ð =Ð =Ð =Ð =Ð =Ð =à €€€ðð ð ð ð ð ð ð ðð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ð ðð ð €ð ", Ø$ØCñ"ô "Ð ðT"ð T"ð T"ð T"ð T" ¤ñ T"ô T"ð T"ðr ð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@   