ó
    "Eñiq  ã                   ó  • S SK r S SKJr  S SKJr  S SKJr  S SKrS SKJ	r	J
r
  S SKJrJrJrJrJrJrJrJrJrJr  / SQr\" SS	5      r " S
 S\R0                  5      r SS\R0                  S\S\4S jjr " S S\5      r " S S\5      rg)é    N)Ú
namedtuple)ÚCallable)ÚAny)Ú)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                   óF  • \ rS rSr% SrSr\\S'   \\	R                  \4   \S'   Sr\\S'   Sr\\S'   Sr\\S	'   \\S
'   \\\4   \S'   \	R$                  S-  \S'   \	R$                  S-  \S'   \	R$                  S-  \S'   \	R$                  S-  \S'   \	R$                  S-  \S'   \\S'   \\S'   / SQr\   S*S\	R*                  S\	R$                  S-  S\	R$                  S-  S\	R$                  S-  S\	R$                  S-  S\	R$                  S-  S\S\S\4S jj5       rS\4S jrS\\\   \\	R*                  \\\4   4   4S jr\S\\	R*                  \\\4   S\	R$                  4S j5       r\	R:                  R<                  r\S\ 4S j5       r!\S+S,S jj5       r"\S\	R$                  SS4S  j5       r#\S!\	R$                  S\	R$                  4S" j5       r$S# r%\S\	R$                  SS 4S$ j5       r&SS%.S&\	R$                  S'\	R$                  S-  S\	R$                  4S( jjr'S)r(g)-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_DISPATCHNÚpackedÚmetaÚpacked_tÚmeta_tÚcompressed_swizzled_bitmaskÚfuse_transpose_cusparseltÚalg_id_cusparselt)r    r!   r"   r#   r$   ÚshapeÚrequires_gradc
           	      óÊ  • U R                   (       dP  [        R                  " S[        SS9  SU l         U R	                  5         [
        R                  R                  U 5        Ub  Un
OUb  Un
O[        S5      e[
        R                  R                  U UU
R                  U
R                  U
R                  U	S9nX+l        X;l        XKl        X[l        Xkl        X{l        X‹l        U$ )a�  
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.é   ©Ú
stacklevelTz3At 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               ÚY/home/mande/repo/quber/.venv/lib/python3.13/site-packages/torch/sparse/semi_structured.pyÚ__new__Ú"SparseSemiStructuredTensor.__new__L   sà   € ðN ×+×+Ü�MŠMðHô
 Øò	ð ,0ˆCÔ(ð
 ×$Ñ$Ô&ô �M‰M×(Ñ(¨Ô-àÑØ$‰OØÑ!Ø&‰OäÐRÓSÐSä—‘×4Ñ4ØØØ"×)Ñ)Ø!×'Ñ'Ø"×)Ñ)Ø'ð 5ð 
ˆð ŒØŒØ"ŒØŒØ-HÔ*Ø+DÔ(Ø#4Ô Øˆó    Úreturnc                 ó†   • [        U S5      (       d  [        S5      eU R                  R                   SU R                   S3$ )Nr'   ztensor has no shape attributez(shape=Ú))ÚhasattrÚAssertionErrorÚ	__class__Ú__name__r'   )Úselfs    r=   Ú__repr__Ú#SparseSemiStructuredTensor.__repr__¡   s=   € Ü�t˜W×%Ñ%Ü Ð!@ÓAÐAØ—.‘.×)Ñ)Ð*¨'°$·*±*°¸QÐ?Ð?r@   c                 ó¬   ^ • [        [        U 4S jT R                  5      5      nT R                  T R                  T R
                  T R                  4nX4$ )Nc                 ó    >• [        TU 5      S L$ ©N)Úgetattr)ÚxrH   s    €r=   Ú<lambda>Ú?SparseSemiStructuredTensor.__tensor_flatten__.<locals>.<lambda>ª   s   ø€ œW T¨1Ó-°TÑ9r@   )ÚlistÚfilterÚ	__slots__r'   r%   r&   r(   )rH   Úinner_tensorsÚtensor_metas   `  r=   Ú__tensor_flatten__Ú-SparseSemiStructuredTensor.__tensor_flatten__¦   sT   ø€ ô ÜÔ9¸4¿>¹>ÓJó
ˆð �J‰JØ×*Ñ*Ø×"Ñ"Ø×Ñð	
ˆð Ð)Ð)r@   rV   c                 óÈ   • Uu  pVpxU " UUR                  SS 5      UR                  SS 5      UR                  SS 5      UR                  SS 5      UR                  SS 5      UUUS9	$ )Nr    r!   r"   r#   r$   ©	r'   r    r!   r"   r#   r$   r%   r&   r(   )Úget)	r:   rU   rV   Ú
outer_sizeÚouter_strider'   r%   r&   r(   s	            r=   Ú__tensor_unflatten__Ú/SparseSemiStructuredTensor.__tensor_unflatten__´   s€   € ð NYÑJˆÐ*;áØØ ×$Ñ$ X¨tÓ4Ø×"Ñ" 6¨4Ó0Ø"×&Ñ& z°4Ó8Ø ×$Ñ$ X¨tÓ4Ø(5×(9Ñ(9Ø-¨tó)ð '@Ø/Ø'ñ
ð 	
r@   c                 óÀ   • UR                   U R                  ;  a%  [        U R                   SUR                   S35      eU R                  UR                      " XX45      $ )NzI only supports a specific set of operations, can't perform requested op (rC   )Ú_overloadpacketr   ÚNotImplementedErrorrG   )r:   ÚfuncÚtypesÚargsÚkwargss        r=   Ú__torch_dispatch__Ú-SparseSemiStructuredTensor.__torch_dispatch__Î   sb   € à×Ñ s×':Ñ':Ó:Ü%Ø—<‘<�.ð !/Ø/3¯}©}¨o¸Qð@óð ð ×"Ñ" 4×#7Ñ#7Ò8¸ÀdÓSÐSr@   c                 ó€  • [        U SS5      Gc/  [        R                  R                  R                  [
        [        R                  R                  R                  [        [        R                  R                  R                  [        [        R                  R                  R                  [        [        R                  R                  R                  [        [        R                  R                  R                  [        [        R                  R                  R                  [         [        R                  R                  R"                  [$        [        R                  R                  R&                  [$        [        R                  R                  R(                  [*        [        R                  R                  R,                  [.        [        R                  R                  R0                  [        [        R                  R                  R2                  [4        0U l        Ub  U R6                  R9                  U5        ggg)zD
Loads the op overload sparse dispatch table for the current class.
r   N)rN   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   Ú/SparseSemiStructuredTensor._load_dispatch_table×   sF  € ô
 �3Ð)¨4Ó0Ò8ä—	‘	—‘×%Ñ%Ô'9Ü—	‘	—‘×&Ñ&Ô(;Ü—	‘	—‘×+Ñ+Ô-@Ü—	‘	—‘×&Ñ&Ô(;Ü—	‘	—‘×%Ñ%Ô'9Ü—	‘	—‘× Ñ ¤-Ü—	‘	—‘×#Ñ#Ô%5Ü—	‘	—‘×!Ñ!¤>Ü—	‘	—‘×%Ñ%¤~Ü—	‘	—‘×$Ñ$Ô&7Ü—	‘	—‘×%Ñ%Ô'9Ü—	‘	—‘×'Ñ'Ô)<Ü—	‘	—‘×)Ñ)Ô+@ð#ˆCÔð %Ñ0Ø×#Ñ#×*Ñ*Ð+@ÕAð 1ð! 9r@   Úoriginal_tensorc           	      ó„  • UR                   (       d  [        SUR                   S35      eUR                  5       S:w  a  [        SUR                  5        S35      eUR	                  5       (       d  [        S5      eUR
                  U R                  ;  a  [        SUR
                   SU  S	35      eUR                  u  p#U R                  UR
                     R                  nU R                  UR
                     R                  nX$:  d  X$-  (       d  X5:  d	  X5-  (       a  [        S
UR                   SU SU S35      eg)zO
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.r*   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:   r|   ÚmÚnÚmin_rowsÚmin_colss         r=   Ú _validate_device_dim_dtype_shapeÚ;SparseSemiStructuredTensor._validate_device_dim_dtype_shapeï   sk  € ð ×&×&ÜØ0°×1GÑ1GÐ0Hð I=ð =óð ð ×ÑÓ  AÓ%ÜØ.¨×/BÑ/BÓ/DÐ.Eð F;ð ;óð ð ×,Ñ,×.Ñ.ÜðCóð ð × Ñ ¨×(DÑ(DÓDÜØ.¨×/DÑ/DÐ.EÐEcÐdgÐchÐhiÐjóð ð
 ×$Ñ$‰ˆØ×/Ñ/°×0EÑ0EÑF×VÑVˆØ×/Ñ/°×0EÑ0EÑF×VÑVˆØ‹<˜1Ÿ<¨1«<¸1¿<äØ.¨×/DÑ/DÐ.Eð FSØS[ÐR\Ð\^Ð_gÐ^hÐhiðkóð ð <Hr@   Údense_inputc                 óà  • UR                  5       S:w  a  [        SUR                  5        S35      eUR                  u  p#U R                  UR                     R
                  nU R                  UR                     R                  nX$:  d	  X$-  (       a  U* U-  OSnX5:  d	  X4-  (       a  U* U-  OSnU(       d  U(       a.  [        R                  R                  R                  USUSU45      $ U$ )zŠ
Calculates padding for dense tensor and pads tensor if necessary.
If padding is not required, this function returns the original tensor.
r*   zdense_input must be 2D, got ÚDr   )r�   rE   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_inputÚ+SparseSemiStructuredTensor._pad_dense_input  sÕ   € ð �?‰?Ó Ó!Ü Ð#?ÀÇÁÓ@QÐ?RÐRSÐ!TÓUÐUð × Ñ ‰ˆØ×/Ñ/°×0AÑ0AÑB×QÑQˆØ×/Ñ/°×0AÑ0AÑB×QÑQˆð %&£L°A·L�A�2˜’=ÀaˆØ$%£L°A·L�A�2˜’=ÀaˆÞ–xÜ—8‘8×&Ñ&×*Ñ*¨;¸¸HÀaÈÐ8RÓSÐSàÐr@   c           	      óœ   • U R                   S   n[        R                  " U [        R                  " XR                  U R
                  S95      $ )Néÿÿÿÿ)r.   r-   )r'   r4   rs   Úeyer.   r-   )rH   Úcols     r=   Úto_denseÚ#SparseSemiStructuredTensor.to_dense1  s3   € Ø�j‰j˜‰nˆÜ�xŠx˜œeŸiši¨·:±:ÀdÇkÁkÑRÓSÐSr@   c                 ó   • [         erM   ©rb   ©r:   r|   s     r=   Ú
from_denseÚ%SparseSemiStructuredTensor.from_dense5  s   € ä!Ð!r@   ©ÚbiasÚBr£   c                ó   • [         erM   rž   )rH   r¤   r£   rf   s       r=   Ú_mmÚSparseSemiStructuredTensor._mm9  s
   € ô "Ð!r@   © )Fr   FrM   )rA   N))rG   Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   ÚintÚ__annotations__Údictr4   r.   r   r   Úboolr   r   Ústrr   r8   rT   ÚstaticmethodÚSizer>   rI   ÚtuplerR   rW   Úclassmethodr^   Ú_CÚ_disabled_torch_function_implÚ__torch_function__r   rg   r3   r‰   r•   r›   r    r¦   Ú__static_attributes__r¨   r@   r=   r   r   '   sâ  ‡ ñð" €O�SÓØ" 5§;¡;Ð0NÐ#NÑOÓOØ €N�DÓ Ø!€O�TÓ!Ø%*Ð˜dÓ*àƒLØ˜( HÐ,Ñ-Ó-à�L‰L˜4ÑÓØ
�,‰,˜Ñ
ÓØ�l‰l˜TÑ!Ó!Ø�L‰L˜4ÑÓØ!&§¡°Ñ!4Ó4Ø#Ó#ØÓâW€Iàð +0Ø!"Ø#ñRà�z‰zðRð —‘˜tÑ#ðRð �l‰l˜TÑ!ð	Rð
 —,‘, Ñ%ðRð —‘˜tÑ#ðRð &+§\¡\°DÑ%8ðRð $(ðRð ðRð ôRó ðRðh@˜#ô @ð
*à	ˆt�C‰y˜% §
¡
¨D°#°tÐ ;Ñ<Ð<Ñ	=ô*ð ð
ð ˜5Ÿ:™: t¨S°$Ð6Ñ7ð
ð 
�‰ó
ó ð
ð. Ÿ™×?Ñ?ÐàðT¸có Tó ðTð õBó ðBð. ð(¸u¿|¹|ð (ÐPTó (ó ð(ðT ð¨5¯<©<ð ¸E¿L¹Ló ó ðò,Tð ð"¨¯©ð "Ð:Vó "ó ð"ð %)ò	"à�<‰<ð"ð �l‰l˜TÑ!ð	"ð 
�‰÷"ð "r@   r   r|   Ú
transposedrA   c                 óø   • U(       a  [         R                  " S[        SS9  [        R                  (       a  [
        R                  R                  O[
        R                  R                  nUR                  U 5      $ )aj  
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.r*   r+   )
r0   r1   ÚFutureWarningr   r   r4   Úsparser   r   r    )r|   rº   ÚSPARSE_SUBCLASSs      r=   r   r   C  sa   € öb Ü�ŠðRô Øò	
ô &×4×4ô 	�‰×6Ò6ä�\‰\×>Ñ>ð ð ×%Ñ% oÓ6Ð6r@   c                   ó¢  ^ • \ rS rSrSrSr\R                  \" SSSS5      \R                  \" SSSS5      \R                  \" SSSS5      \R                  \" SSS	S	5      0r\S
\R                  SS 4S j5       rU 4S jr\ SS
\R                  SS4S jj5       rSS.S\R                  S\R                  S-  S\R                  4S jjrSrU =r$ )r   i‡  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é   é€   é    é@   é   é   r|   rA   c           
      ó€   • U R                  U5        [        U5      u  nnU " UR                  UUS S S UR                  S9$ )N©r    r!   r"   r#   r$   r(   )r‰   r   r'   r(   )r:   r|   Úsparse_tensor_cutlassÚmeta_tensor_cutlasss       r=   r    Ú,SparseSemiStructuredTensorCUTLASS.from_dense›  sW   € ð 	×,Ñ,¨_Ô=ô 6°oÓFñ	
Ø!Øñ Ø×!Ñ!Ø(Ø$ØØØ(,Ø)×7Ñ7ñ
ð 	
r@   c                 óÞ   >• U R                   b  U R                  c  [        S5      eU R                   R                  S:X  a   [	        U R                  U R                   5      $ [
        TU ]  5       $ )Nz meta and packed must not be Noner*   )r!   r    rE   Úndimr   Úsuperr›   )rH   rF   s    €r=   r›   Ú*SparseSemiStructuredTensorCUTLASS.to_dense¯  sc   ø€ Ø�9‰9Ñ §¡Ñ 3Ü Ð!CÓDÐDð �y‰y�~‰~ Ó"ô	 4Ø—‘Ø—	‘	óð	
ô ‘Ñ!Ó#ð	
r@   r   c           
      ód   • [         R                  " XSS9u  nnnnnU " UR                  UUUUUSS9$ )aF  
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:   r|   rÒ   r    r!   r"   r#   r$   s           r=   Úprune_dense_static_sortÚ9SparseSemiStructuredTensorCUTLASS.prune_dense_static_sort»  sV   € ôz ×.Ò.Ø¸dñ
ñ	
ØØØØØ'ñ Ø×!Ñ!ØØØØØ(CØñ
ð 	
r@   Nr¢   r¤   r£   c                óú  • [        U[        5      (       a  [        S5      eU R                  R                  nU R
                  S:w  d  UR
                  S:w  a  [        SU S35      eU R                  b  U R                  c  [        SU S35      eUc-  [        R                  " U R                  U R                  U5      nO,[        R                  " X R                  U R                  U5      nUS U R                  S    $ )NúZ`SparseSemiStructuredTensor @ SparseSemiStructuredTensor` is not supported by the hardwarer*   Ú`ú)` matmul: Broadcasting is not implementedú$` matmul: operation is not supportedr   )Ú
isinstancer   r7   rF   rG   rÍ   rb   r    r!   r4   Ú_sparse_semi_structured_mmÚ_sparse_semi_structured_addmmr'   )rH   r¤   r£   rf   Úcls_nameÚress         r=   r¦   Ú%SparseSemiStructuredTensorCUTLASS._mm  sê   € ô �aÔ3×4Ñ4ÜØlóð ð —>‘>×*Ñ*ˆØ�9‰9˜‹>˜QŸV™V q›[Ü%Ø�H�:ÐFÐGóð ð �;‰;Ñ $§)¡)Ñ"3Ü%Ø�H�:ÐAÐBóð ð ‰|Ü×6Ò6°t·{±{ÀDÇIÁIÈqÓQ‘ä×9Ò9ØŸ+™+ t§y¡y°!ó�ð �˜Ÿ™ A™Ð'Ð'r@   r¨   ©Ú )rG   r©   rª   r«   r¬   r   r4   Úint8r   Úfloat16Úbfloat16Úfloat32r   rµ   r8   r    r›   rÖ   r¦   r¹   Ú__classcell__)rF   s   @r=   r   r   ‡  s  ø† ñ	ð €Gà�
‰
Ñ2°2°s¸BÀÓCØ�‰Ñ5°b¸"¸aÀÓCØ�‰Ñ6°r¸2¸qÀ!ÓDØ�‰Ñ5°b¸"¸aÀÓCð	 Ðð ð
Ø#Ÿl™lð
à	,ó
ó ð
õ&

ð à68ñI
Ø#Ÿl™lðI
à	%ôI
ó ðI
ðX ?Cò(Ø—‘ð(Ø(-¯©°tÑ(;ð(à	�‰÷(ó (r@   r   c                   óŽ  • \ rS rSrSrSr\R                  \" SSSS5      \R                  \" SSSS5      \R                  \" SSSS5      \R                  \" SSSS5      0r\S\R                  SS 4S	 j5       r\ SS\R                  SS
4S jj5       rSS.S\R                  S\R                  S-  S\R                  4S jjrSrg)r   i!  ab  
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Å   r|   rA   c                 óÈ   • U R                  U5        U " UR                  [        R                  " U5      S S S S [        R
                  [        R                  UR                  S9	$ )NrZ   )r‰   r'   r4   Ú_cslt_compressr   r   r   r(   rŸ   s     r=   r    Ú/SparseSemiStructuredTensorCUSPARSELT.from_dense5  s]   € ð 	×,Ñ,¨_Ô=áØ!×'Ñ'Ü×'Ò'¨Ó8ØØØØ(,Ü&@×&PÑ&PÜ8×HÑHØ)×7Ñ7ñ

ð 
	
r@   r   c           
      óà   • [         R                  " XSS9u  nnnnnUR                  UR                  S   S5      nUR                  UR                  S   S5      nU " UR                  UUUUUSS9$ )am  
This function does the same thing as described in SparseSemiStructuredCUTLASS, but uses the cuSPARSELt 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È   )r4   rÔ   rr   r'   rÕ   s           r=   rÖ   Ú<SparseSemiStructuredTensorCUSPARSELT.prune_dense_static_sortG  sŽ   € ôZ ×.Ò.Ø¸eñ
ñ	
ØØØØØ'ð —‘˜_×2Ñ2°1Ñ5°rÓ:ˆØ—=‘= ×!6Ñ!6°qÑ!9¸2Ó>ˆñ Ø×!Ñ!ØØØØØ(CØñ
ð 	
r@   Nr¢   r¤   r£   c                óà  • [        U[        5      (       a  [        S5      eU R                  S:w  d  UR                  S:w  a#  [	        SU R
                  R                   S35      eUR                  U R                  :w  ai  [	        SU R
                  R                   S[        U R                  5       S[        UR                  5       SU R                   SUR                   S	35      eUbƒ  UR                  U R                  :w  ai  [	        SU R
                  R                   S[        U R                  5       S[        UR                  5       S
U R                   SUR                   S35      eU R                  [        R                  :X  a\  [	        SU R
                  R                   S[        U R                  5       S[        UR                  5       SU R                   S3	5      eU R                  c#  [	        SU R
                  R                   S35      e[        R                  " U R                  UUU R                  U R                  S9nU R                  (       a  UR!                  5       $ U$ )NrÙ   r*   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Í   rb   rF   rG   r.   r´   r'   r4   Úfloat8_e4m3fnr    Ú_cslt_sparse_mmr%   r&   rq   )rH   r¤   r£   rf   rá   s        r=   r¦   Ú(SparseSemiStructuredTensorCUSPARSELT._mmˆ  sN  € ô �aÔ3×4Ñ4ÜØlóð ð �9‰9˜‹>˜QŸV™V q›[Ü%Ø�D—N‘N×+Ñ+Ð,Ð,UÐVóð ð �7‰7�d—j‘jÓ Ü%Ø�D—N‘N×+Ñ+Ð,Ð,FÄuÈTÏZÉZÓGXÐFYÐY^Ô_dÐef×elÑelÓ_mÐ^nð o Ø $§
¡
˜|¨=¸¿¹¸	ð BYðYóð ð
 Ñ §
¡
¨d¯j©jÓ 8Ü%Ø�D—N‘N×+Ñ+Ð,Ð,FÄuÈTÏZÉZÓGXÐFYÐY^Ô_dÐef×elÑelÓ_mÐ^nð o(Ø(,¯
©
 |°=ÀÇÁÀ	ð J\ð\óð ð �:‰:œ×,Ñ,Ó,Ü%Ø�D—N‘N×+Ñ+Ð,Ð,FÄuÈTÏZÉZÓGXÐFYÐY^Ô_dÐef×elÑelÓ_mÐ^nð o(Ø(,¯
©
 |ð 4`ð`óð ð
 �;‰;ÑÜ%Ø�D—N‘N×+Ñ+Ð,Ð,PÐQóð ô ×'Ò'Ø—‘ØØØ!%×!?Ñ!?Ø×-Ñ-ñˆCð #×<×<�3—5‘5“7ÐEÀ#ÐEr@   r¨   rã   )rG   r©   rª   r«   r¬   r   r4   rõ   r   rå   ræ   rç   r   rµ   r8   r    rÖ   r¦   r¹   r¨   r@   r=   r   r   !  sþ   † ñ	ð €Gà×ÑÑ;¸BÀÀBÈÓKØ�
‰
Ñ2°2°r¸2¸rÓBØ�‰Ñ5°b¸"¸aÀÓCØ�‰Ñ6°r¸2¸qÀ!ÓDð	 Ðð ð
Ø#Ÿl™lð
à	/ó
ó ð
ð" à68ñ>
Ø#Ÿl™lð>
à	%ô>
ó ð>
ðB ?Cò*FØ—‘ð*FØ(-¯©°tÑ(;ð*Fà	�‰÷*Fð *Fr@   r   )F)r0   Úcollectionsr   Úcollections.abcr   Útypingr   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ó"Ð ôY" §¡ô Y"ð| ñA7Ø—\‘\ðA7àðA7ð  õA7ôHW(Ð(Bô W(ôtQFÐ+Eõ QFr@   