Ë
    S²jì�  ã            	       óN  — d dl Z d dlmZ d dlmZ d dl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mZmZmZ g d¢Z edd	«      Z G d
„ dej6                  «      Zdej:                  fdej6                  dededefd„Z  G d„ de«      Z! G d„ de«      Z"da#d„ Z$da%d„ Z&y)é    N)Ú
namedtuple)ÚCallable)ÚAny)Ú)sparse_semi_structured_from_dense_cutlassÚ'sparse_semi_structured_to_dense_cutlass)Úfallback_dispatcherÚsemi_sparse_addmmÚsemi_sparse_cloneÚsemi_sparse_detachÚsemi_sparse_indicesÚsemi_sparse_linearÚsemi_sparse_mmÚsemi_sparse_scaled_mmÚsemi_sparse_tÚsemi_sparse_toÚsemi_sparse_to_copyÚ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j"                  dz  ed<   ej"                  dz  ed<   ej"                  dz  ed<   ej"                  dz  ed<   ej"                  dz  ed<   eed<   eed<   g d¢Ze	 	 	 d'dej(                  dej"                  dz  dej"                  dz  dej"                  dz  dej"                  dz  dej"                  dz  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j8                  j:                  Zedefd„«       Z ed(d)d„«       Z!edej"                  ddfd„«       Z"d „ Z#eefdej"                  d!edd fd"„«       Z$dd#œd$ej"                  d%ej"                  dz  dej"                  fd&„Z%y)*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
                 óÔ  — | j                   sRt        j                  dt        d¬«       d| _         | j	                  «        t
        j                  j                  | «       |�|}
n|�|}
nt        d«      ‚t
        j                  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.é   ©Ú
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/   r0   r1   r"   r#   r$   r%   r&   r'   r(   )Úclsr)   r"   r#   r$   r%   r&   r'   r(   r*   Úprevious_tensorÚtensors               ú[/var/www/html/ia-enhanced/venv/lib/python3.12/site-packages/torch/sparse/semi_structured.pyÚ__new__z"SparseSemiStructuredTensor.__new__O   sî   € ðN ×+Ò+Ü�M‰MðHô
 Øõ	ð ,0ˆCÔ(ð
 ×$Ñ$Ô&ô �M‰M×(Ñ(¨Ô-àÐØ$‰OØÐ!Ø&‰OäÐRÓSÐSä—‘×4Ñ4ØØØ"×)Ñ)Ø!×'Ñ'Ø"×)Ñ)Ø'ð 5ó 
ˆð ˆŒØˆŒØ"ˆŒØˆŒØ-HˆÔ*Ø+DˆÔ(Ø#4ˆÔ Øˆó    Úreturnc                 ó|   — t        | d«      st        d«      ‚| j                  j                  › d| j                  › d�S )Nr)   ztensor has no shape attributez(shape=ú))ÚhasattrÚAssertionErrorÚ	__class__Ú__name__r)   )Úselfs    r?   Ú__repr__z#SparseSemiStructuredTensor.__repr__¤   s:   € Ü�t˜WÔ%Ü Ð!@ÓAÐAØ—.‘.×)Ñ)Ð*¨'°$·*±*°¸QÐ?Ð?rA   c                 ó¬   ‡ — t        t        ˆ fd„‰ j                  «      «      }‰ j                  ‰ j                  ‰ j
                  ‰ j                  f}||fS )Nc                 ó    •— t        ‰| «      d uS ©N)Úgetattr)ÚxrI   s    €r?   ú<lambda>z?SparseSemiStructuredTensor.__tensor_flatten__.<locals>.<lambda>­   s   ø€ œW T¨1Ó-°TÐ9€ rA   )ÚlistÚfilterÚ	__slots__r)   r'   r(   r*   )rI   Úinner_tensorsÚtensor_metas   `  r?   Ú__tensor_flatten__z-SparseSemiStructuredTensor.__tensor_flatten__©   sV   ø€ ô ÜÓ9¸4¿>¹>ÓJó
ˆð �J‰JØ×*Ñ*Ø×"Ñ"Ø×Ñð	
ˆð ˜kÐ)Ð)rA   rU   c                 óÒ   — |\  }}}} | ||j                  dd «      |j                  dd «      |j                  dd «      |j                  dd «      |j                  dd «      |||¬«	      S )Nr"   r#   r$   r%   r&   ©	r)   r"   r#   r$   r%   r&   r'   r(   r*   )Úget)	r<   rT   rU   Ú
outer_sizeÚouter_strider)   r'   r(   r*   s	            r?   Ú__tensor_unflatten__z/SparseSemiStructuredTensor.__tensor_unflatten__·   s…   € ð NYÑJˆÐ(Ð*;¸]áØØ ×$Ñ$ X¨tÓ4Ø×"Ñ" 6¨4Ó0Ø"×&Ñ& z°4Ó8Ø ×$Ñ$ X¨tÓ4Ø(5×(9Ñ(9Ø-¨tó)ð '@Ø/Ø'ô
ð 	
rA   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 (rD   )Ú_overloadpacketr!   ÚNotImplementedErrorrH   )r<   ÚfuncÚtypesÚargsÚkwargss        r?   Ú__torch_dispatch__z-SparseSemiStructuredTensor.__torch_dispatch__Ñ   sh   € à×Ñ s×':Ñ':Ñ:Ü%Ø—<‘<�.ð !/Ø/3¯}©}¨o¸Qð@óð ð 9ˆs×"Ñ" 4×#7Ñ#7Ñ8¸¸uÀdÈFÓSÐSrA   c                 ó  — 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                  j0                  t2        t        j                  j                  j4                  t6        t        j                  j                  j8                  t:        t        j                  j                  j<                  t>        i| _         |�| j@                  jC                  |«       yyy)zT
        Loads the op overload sparse dispatch table for the current class.
        r!   N)"rN   r6   ÚopsÚatenÚvaluesr   Úindicesr   Úis_same_sizer   Údetach_Údetachr   Útr   Úviewr   Úmmr   ÚmatmulÚaddmmr	   Úlinearr   Ú_to_copyr   Ú
_scaled_mmr   Úcloner
   Útor   r!   Úupdate)r<   Úcustom_dispatch_tables     r?   r5   z/SparseSemiStructuredTensor._load_dispatch_tableÚ   sm  € ô
 �3Ð)¨4Ó0Ñ8ä—	‘	—‘×%Ñ%Ô'9Ü—	‘	—‘×&Ñ&Ô(;Ü—	‘	—‘×+Ñ+Ô-@Ü—	‘	—‘×&Ñ&Ô(;Ü—	‘	—‘×%Ñ%Ô'9Ü—	‘	—‘× Ñ ¤-Ü—	‘	—‘×#Ñ#Ô%5Ü—	‘	—‘×!Ñ!¤>Ü—	‘	—‘×%Ñ%¤~Ü—	‘	—‘×$Ñ$Ô&7Ü—	‘	—‘×%Ñ%Ô'9Ü—	‘	—‘×'Ñ'Ô)<Ü—	‘	—‘×)Ñ)Ô+@Ü—	‘	—‘×$Ñ$Ô&7Ü—	‘	—‘×!Ñ!¤>ð#ˆCÔð" %Ð0Ø×#Ñ#×*Ñ*Ð+@ÕAð 1ð% 9rA   Úoriginal_tensorc           	      ó\  — |j                   st        d|j                  › d�«      ‚|j                  «       dk7  rt        d|j                  «       › d�«      ‚|j	                  «       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�«      ‚y)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.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, rD   N)
Úis_cudaÚRuntimeErrorr/   ÚdimÚis_contiguousr0   r   r)   Úsparse_min_rowsÚsparse_min_cols)r<   ry   ÚmÚnÚmin_rowsÚmin_colss         r?   Ú _validate_device_dim_dtype_shapez;SparseSemiStructuredTensor._validate_device_dim_dtype_shapeô   sr  € ð ×&Ò&ÜØ0°×1GÑ1GÐ0Hð I=ð =óð ð ×ÑÓ  AÒ%ÜØ.¨×/BÑ/BÓ/DÐ.Eð F;ð ;óð ð ×,Ñ,Ô.ÜðCóð ð × Ñ ¨×(DÑ(DÑDÜØ.¨×/DÑ/DÐ.EÐEcÐdgÐchÐhiÐjóð ð
 ×$Ñ$‰ˆˆ1Ø×/Ñ/°×0EÑ0EÑF×VÑVˆØ×/Ñ/°×0EÑ0EÑF×VÑVˆØˆxŠ<˜1˜xš<¨1¨xª<¸1¸xº<äØ.¨×/DÑ/DÐ.Eð FSØS[ÐR\Ð\^Ð_gÐ^hÐhiðkóð ð <HrA   c                 ó    — | j                   d   }t        j                  | t        j                  || j                  | j
                  ¬«      «      S )Néÿÿÿÿ©r0   r/   )r)   r6   ro   Úeyer0   r/   )rI   Úcols     r?   Úto_densez#SparseSemiStructuredTensor.to_dense  s5   € Ø�j‰j˜‰nˆÜ�x‰x˜œeŸi™i¨°4·:±:ÀdÇkÁkÔRÓSÐSrA   Úalg_idc                 ó   — t         ‚rM   ©r_   ©r<   ry   r�   s      r?   Ú
from_densez%SparseSemiStructuredTensor.from_dense#  s
   € ô "Ð!rA   )ÚbiasÚBr’   c                ó   — t         ‚rM   r�   )rI   r“   r’   rc   s       r?   Ú_mmzSparseSemiStructuredTensor._mm+  s
   € ô "Ð!rA   )Fr   FrM   )rB   N)&rH   Ú
__module__Ú__qualname__Ú__doc__r   ÚintÚ__annotations__Údictr6   r0   r   r   Úboolr   r   Ústrr   r:   rS   ÚstaticmethodÚSizer@   rJ   ÚtuplerQ   rV   Úclassmethodr\   Ú_CÚ_disabled_torch_function_implÚ__torch_function__r   rd   r5   r†   rŒ   r‘   r•   © rA   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ð2 ð(¸u¿|¹|ð (ÐPTò (ó ð(òTTð ð &ñ"àŸ™ð"ð ð"ð 
&ò	"ó ð"ð %)ò	"à�<‰<ð"ð �l‰l˜TÑ!ð	"ð 
�‰ô"rA   r   Fry   Ú
transposedr�   rB   c                 óì   — |rt        j                  dt        d¬«       t        j                  rt
        j                  j                  nt
        j                  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.
        alg_id (int, optional): the algorithm id to use for cuSPARSELt matmul. Defaults to 0.
            Can be obtained via ``torch._cslt_sparse_mm_search``.
    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-   )r�   )
r2   r3   ÚFutureWarningr   r   r6   Úsparser   r   r‘   )ry   r¦   r�   ÚSPARSE_SUBCLASSs       r?   r   r   5  sf   € ñh Ü�‰ðRô Øõ	
ô &×4Ò4ô 	�‰×6Ò6ä�\‰\×>Ñ>ð ð ×%Ñ% o¸fÐ%ÓEÐErA   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ej                  fd	ej                  d
edd fd„«       Zˆ fd„Ze	 dd	ej                  ddfd„«       Zdddœdej                  dej                  dz  de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é   é€   é    é@   é   é   ry   r�   rB   c           	      ó†   — | j                  |«       t        |«      \  }} | |j                  ||d d d |j                  ¬«      S )N©r"   r#   r$   r%   r&   r*   )r†   r   r)   r*   )r<   ry   r�   Úsparse_tensor_cutlassÚmeta_tensor_cutlasss        r?   r‘   z,SparseSemiStructuredTensorCUTLASS.from_dense�  sW   € ð 	×,Ñ,¨_Ô=ô 6°oÓFñ	
Ø!Øñ Ø×!Ñ!Ø(Ø$ØØØ(,Ø)×7Ñ7ô
ð 	
rA   c                 óØ   •— | j                   �| j                  €t        d«      ‚| j                   j                  dk(  r t	        | j                  | j                   «      S t
        ‰| �  «       S )Nz meta and packed must not be Noner,   )r#   r"   rF   Úndimr   ÚsuperrŒ   )rI   rG   s    €r?   rŒ   z*SparseSemiStructuredTensorCUTLASS.to_dense¦  sc   ø€ Ø�9‰9Ð §¡Ð 3Ü Ð!CÓDÐDð �y‰y�~‰~ Ò"ô	 4Ø—‘Ø—	‘	óð	
ô ‘Ñ!Ó#ð	
rA   r   c           	      óp   — 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´   )r6   Ú_sparse_semi_structured_tiler)   ©r<   ry   r¼   r"   r#   r$   r%   r&   s           r?   Úprune_dense_static_sortz9SparseSemiStructuredTensorCUTLASS.prune_dense_static_sort²  sX   € ôz ×.Ñ.Ø y¸dô
ñ	
ØØØØØ'ñ Ø×!Ñ!ØØØØØ(CØô
ð 	
rA   NF©r’   Úshould_transpose_denser“   r’   rÂ   c          
      ó  — t        |t        «      rt        d«      ‚| j                  j                  }| j
                  dk7  s|j
                  dk7  rt        d|› d�«      ‚| j                  �| j                  €t        d|› d�«      ‚t        «        | j                  |j                     }t        j                  j                  j                  || j                  | j                  || j                   d   |j"                  |j$                  |«      S )NúZ`SparseSemiStructuredTensor @ SparseSemiStructuredTensor` is not supported by the hardwarer,   ú`ú)` matmul: Broadcasting is not implementedú$` matmul: operation is not supportedr   )Ú
isinstancer   r9   rG   rH   r¸   r_   r"   r#   Ú_ensure_cutlass_mm_registeredr   r0   r6   rf   Úsemi_structuredÚ
cutlass_mmr)   Údense_min_rowsÚdense_min_cols)rI   r“   r’   rÂ   rc   Úcls_nameÚconstraintss          r?   r•   z%SparseSemiStructuredTensorCUTLASS._mmþ  sû   € ô �aÔ3Ô4ÜØlóð ð —>‘>×*Ñ*ˆØ�9‰9˜Š>˜QŸV™V qš[Ü%Ø�H�:ÐFÐGóð ð �;‰;Ð $§)¡)Ð"3Ü%Ø�H�:ÐAÐBóð ô *Ô+Ø×7Ñ7¸¿¹Ñ@ˆKÜ—9‘9×,Ñ,×7Ñ7ØØ—‘Ø—	‘	ØØ—
‘
˜1‘Ø×*Ñ*Ø×*Ñ*Ø&ó	ð 	rA   ©Ú )rH   r–   r—   r˜   r    r6   Úint8r   Úfloat16Úbfloat16Úfloat32r   r¡   r   r   r:   r™   r‘   rŒ   rÀ   rœ   r•   Ú__classcell__)rG   s   @r?   r   r   |  s#  ø„ ñ	ð €Gà�
‰
Ñ2°2°s¸BÀÓCØ�‰Ñ5°b¸"¸aÀÓCØ�‰Ñ6°r¸2¸qÀ!ÓDØ�‰Ñ5°b¸"¸aÀÓCð	 Ðð ð 1×@Ñ@ñ
àŸ™ð
ð ð
ð 
-ò	
ó ð
ô*

ð à68ñI
Ø#Ÿl™lðI
à	%òI
ó ðI
ð^ %)Ø',ò!à�<‰<ð!ð �l‰l˜TÑ!ð	!ð
 !%ð!ð 
�‰÷!rA   r   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ej                  fdej                  dedd fd	„«       Ze	 ddej                  dd
fd„«       Zdddœdej                  dej                  dz  dedej                  fd„Zy)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±   ry   r�   rB   c                 ó°   — | j                  |«        | |j                  t        j                  |«      d d d d t        j
                  ||j                  ¬«	      S )NrX   )r†   r)   r6   Ú_cslt_compressr   r   r*   r�   s      r?   r‘   z/SparseSemiStructuredTensorCUSPARSELT.from_dense6  sW   € ð 	×,Ñ,¨_Ô=áØ!×'Ñ'Ü×'Ñ'¨Ó8ØØØØ(,Ü&@×&PÑ&PØ$Ø)×7Ñ7ô

ð 
	
rA   r   c           	      óì   — t        j                  ||d¬«      \  }}}}}|j                  |j                  d   d«      }|j                  |j                  d   d«      } | |j                  |||||d¬«      S )a=  
        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´   )r6   r¾   rn   r)   r¿   s           r?   rÀ   z<SparseSemiStructuredTensorCUSPARSELT.prune_dense_static_sortJ  s�   € ôZ ×.Ñ.Ø y¸eô
ñ	
ØØØØØ'ð —‘˜_×2Ñ2°1Ñ5°rÓ:ˆØ—=‘= ×!6Ñ!6°qÑ!9¸2Ó>ˆñ Ø×!Ñ!ØØØØØ(CØô
ð 	
rA   NFrÁ   r“   r’   rÂ   c                ó<  — t        |t        «      rt        d«      ‚| j                  dk7  s|j                  dk7  r#t	        d| j
                  j                  › d�«      ‚|j                  | j                  k7  rit	        d| j
                  j                  › dt        | j                  «      › dt        |j                  «      › d| j                  › d|j                  › d	�«      ‚|�‚|j                  | j                  k7  rit	        d| j
                  j                  › dt        | j                  «      › dt        |j                  «      › d
| j                  › d|j                  › d�«      ‚| j                  t        j                  k(  r\t	        d| j
                  j                  › dt        | j                  «      › dt        |j                  «      › d| j                  › d�	«      ‚| j                  €#t	        d| j
                  j                  › d�«      ‚t        «        | j                  |j                     }t        j                  j                   j#                  || j                  || j                  d   |j$                  |j&                  | j(                  | j*                  |«	      S )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   )rÈ   r   r9   r¸   r_   rG   rH   r0   r    r)   r6   Úfloat8_e4m3fnr"   Ú _ensure_cusparselt_mm_registeredr   rf   rÊ   Úcusparselt_mmrÌ   rÍ   r'   r(   )rI   r“   r’   rÂ   rc   rÏ   s         r?   r•   z(SparseSemiStructuredTensorCUSPARSELT._mm‹  sw  € ô �aÔ3Ô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óð ô -Ô.Ø×7Ñ7¸¿¹Ñ@ˆKÜ—9‘9×,Ñ,×:Ñ:ØØ—‘ØØ—
‘
˜1‘Ø×*Ñ*Ø×*Ñ*Ø×.Ñ.Ø×&Ñ&Ø&ó
ð 
rA   rÐ   )rH   r–   r—   r˜   r    r6   rÞ   r   rÒ   rÓ   rÔ   r   r¡   r   r   r:   r™   r‘   rÀ   rœ   r•   r¥   rA   r?   r   r   "  s  „ ñ	ð €Gà×ÑÑ;¸BÀÀBÈÓKØ�
‰
Ñ2°2°r¸2¸rÓBØ�‰Ñ5°b¸"¸aÀÓCØ�‰Ñ6°r¸2¸qÀ!ÓDð	 Ðð ð 1×@Ñ@ñ
àŸ™ð
ð ð
ð 
0ò	
ó ð
ð& à68ñ>
Ø#Ÿl™lð>
à	%ò>
ó ð>
ðH %)Ø',ò4à�<‰<ð4ð �l‰l˜TÑ!ð	4ð
 !%ð4ð 
�‰ô4rA   r   c                  ó  — t         ryda ddlm}   | dd¬«      dt        j                  d	t        j                  d
t        j                  dt        j                  dz  dt
        dt
        dt
        dt        dt        j                  fd„«       }|j                  dt        j                  d	t        j                  d
t        j                  dt        j                  dz  dt
        dt
        dt
        dt        dt        j                  fd„«       }y)zÄLazily register the cutlass_mm custom op.

    Registration is deferred to avoid importing torch.library at module load
    time, since torch.sparse is imported early during ``import torch``.
    NTr   ©Ú	custom_opzsemi_structured::cutlass_mmr¥   ©Úmutates_argsÚdenser"   r#   r’   Úout_featuresr„   r…   rÂ   rB   c                 óØ  — | j                   \  }}	| |z  }
|	 |z  }|
dk7  xs |dk7  }| }|r.t        j                  j                  j	                  | d|d|
f«      }|r|j                  «       n|}|€t        j                  |||«      }nt        j                  ||||«      }|r:|r|n|	}|d | j                  dd|«      j                  t        j                  ¬«      S |j                  «       S )Nr   rÜ   ©Úmemory_format)r)   r6   ÚnnÚ
functionalÚpadrm   Ú_sparse_semi_structured_mmÚ_sparse_semi_structured_addmmÚnarrowru   Úcontiguous_formatÚ
contiguous)ræ   r"   r#   r’   rç   r„   r…   rÂ   r‚   rƒ   Úto_pad_mÚto_pad_nÚneed_padÚdense_paddedÚmm_inputÚresÚout_colss                    r?   rË   z1_ensure_cutlass_mm_registered.<locals>.cutlass_mmÒ  sï   € ð �{‰{‰ˆˆ1Ø�B˜(‘?ˆØ�B˜(‘?ˆØ˜q‘=Ò1 H°¡MˆØˆÙÜ Ÿ8™8×.Ñ.×2Ñ2°5¸1¸hÈÈ8Ð:TÓUˆLÙ'=�<—>‘>Ô#À<ˆØˆ<Ü×2Ñ2°6¸4ÀÓJ‰Cä×5Ñ5°d¸FÀDÈ(ÓSˆCÙÙ2‘q¸ˆHà�M�\Ð"ß‘˜˜1˜hÓ'ß‘¤U×%<Ñ%<�Ó=ðð
 �~‰~ÓÐrA   Útranspose_densec                 óœ   — |r| j                   d   n| j                   d   }t        j                  ||| j                  | j                  ¬«      S ©Nr   rÜ   r‰   ©r)   r6   Úemptyr0   r/   )	ræ   r"   r#   r’   rç   r„   r…   rú   rù   s	            r?   Ú_cutlass_mm_fakez7_ensure_cutlass_mm_registered.<locals>._cutlass_mm_fakeò  sB   € ñ &5�5—;‘;˜q’>¸%¿+¹+Àa¹.ˆÜ�{‰{ØØØ—+‘+Ø—<‘<ô	
ð 	
rA   )Ú_cutlass_mm_registeredÚtorch.libraryrã   r6   r:   r™   rœ   Úregister_fake)rã   rË   rÿ   s      r?   rÉ   rÉ   Å  s%  € õ ØØ!Ðå'áÐ,¸2Ô>ð Ü�|‰|ð ä—‘ð ô �l‰lð ô �l‰l˜TÑ!ð	 ô
 ð ô ð ô ð ô !%ð ô 
�‰ò ó ?ð ð> ×Ñð
Ü�|‰|ð
ä—‘ð
ô �l‰lð
ô �l‰l˜TÑ!ð	
ô
 ð
ô ð
ô ð
ô ð
ô 
�‰ò
ó ñ
rA   c                  ó
  — t         ryda ddlm}   | dd¬«      	 ddt        j                  d	t        j                  d
t        j                  dz  dt
        dt
        dt
        dt        dt
        dt        dt        j                  fd„«       }|j                  dt        j                  d	t        j                  d
t        j                  dz  dt
        dt
        dt
        dt        dt
        dt        dt        j                  fd„«       }y)z,Lazily register the cusparselt_mm custom op.NTr   râ   zsemi_structured::cusparselt_mmr¥   rä   ræ   r"   r’   rç   r„   r…   Úfuse_transposer�   rÂ   rB   c	                 óÆ  — | j                   \  }	}
|	 |z  }|
 |z  }|dk7  xs |dk7  }| }|r.t        j                  j                  j	                  | d|d|f«      }|r|j                  «       n|}t        j                  |||||¬«      }|r|j                  «       }|r7|r|	n|
}|j                  dd|«      j                  t        j                  ¬«      S |j                  «       S )Nr   )r’   Útranspose_resultr�   rÜ   ré   )r)   r6   rë   rì   rí   rm   Ú_cslt_sparse_mmrð   ru   rñ   rò   )ræ   r"   r’   rç   r„   r…   r  r�   rÂ   r‚   rƒ   ró   rô   rõ   rö   r÷   rø   rù   s                     r?   rà   z7_ensure_cusparselt_mm_registered.<locals>.cusparselt_mm  sî   € ð �{‰{‰ˆˆ1Ø�B˜(‘?ˆØ�B˜(‘?ˆØ˜q‘=Ò1 H°¡MˆØˆÙÜ Ÿ8™8×.Ñ.×2Ñ2°5¸1¸hÈÈ8Ð:TÓUˆLÙ'=�<—>‘>Ô#À<ˆÜ×#Ñ#ØØØØ+Øô
ˆñ Ø—%‘%“'ˆCÙÙ2‘q¸ˆHØ—:‘:˜a  HÓ-×3Ñ3Ü#×5Ñ5ð 4ó ð ð �~‰~ÓÐrA   c	                 óœ   — |r| j                   d   n| j                   d   }	t        j                  ||	| j                  | j                  ¬«      S rü   rý   )
ræ   r"   r’   rç   r„   r…   r  r�   rÂ   rù   s
             r?   Ú_cusparselt_mm_fakez=_ensure_cusparselt_mm_registered.<locals>._cusparselt_mm_fake6  sB   € ñ &<�5—;‘;˜q’>ÀÇÁÈQÁˆÜ�{‰{ØØØ—+‘+Ø—<‘<ô	
ð 	
rA   )F)Ú_cusparselt_mm_registeredr  rã   r6   r:   r™   rœ   r  )rã   rà   r	  s      r?   rß   rß   	  s8  € õ !ØØ $Ðå'áÐ/¸bÔAð (-ñ! Ü�|‰|ð! ä—‘ð! ô �l‰l˜TÑ!ð! ô ð	! ô
 ð! ô ð! ô ð! ô ð! ô !%ð! ô 
�‰ò! ó Bð! ðF × Ñ ð
Ü�|‰|ð
ä—‘ð
ô �l‰l˜TÑ!ð
ô ð	
ô
 ð
ô ð
ô ð
ô ð
ô !%ð
ô 
�‰ò
ó !ñ
rA   )'r2   Úcollectionsr   Úcollections.abcr   Útypingr   r6   Ú)torch.sparse._semi_structured_conversionsr   r   Ú!torch.sparse._semi_structured_opsr   r	   r
   r   r   r   r   r   r   r   r   r   r   Ú__all__r   r:   r   r   rœ   r™   r   r   r   r   rÉ   r
  rß   r¥   rA   r?   ú<module>r     sÛ   ðã Ý "Ý $Ý ã ÷÷÷ ÷ õ ò"€ñ ",Ø$ØCó"Ð ôH" §¡ô H"ðZ Ø,×<Ñ<ñDFØ—\‘\ðDFàðDFð ðDFð  ó	DFôNcÐ(Bô côL]Ð+Eô ]ð@ Ð ò>
ðB "Ð ó?
rA   