
    Gj              	       J   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j                  Zdej        fdej        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&dS )    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                   X   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j        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%dS )*r   a  
    This class implements semi-structured sparsity as a Tensor subclass.

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

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

    -`_DTYPE_SHAPE_CONSTRAINTS` - A dictionary holding backend specific dense/sparse min shape constraints
    - `def from_dense()` - backend specific compression routines
    - `def _mm()` - backend specific mm op (either torch._cslt_sparse_mm or torch._sparse_semi_structured_(mm|addmm))
    r   _DEFAULT_ALG_ID_DTYPE_SHAPE_CONSTRAINTSF_FORCE_CUTLASS_FUSE_TRANSPOSE_PROTOTYPE_WARNING_SHOWNBACKENDSPARSE_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         sVt          j        dt          d           d| _         |                                  t
          j                            |            ||}
n||}
nt          d          t
          j	        
                    | ||
j        |
j        |
j        |	          }||_        ||_        ||_        ||_        ||_        ||_        ||_        |S )a0  
        Create a new instance of the tensor subclass from the compressed sparse representation.

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

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

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

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

        Raises:
            ValueError: If all of the tensor arguments are None.
        zThe 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.   
stacklevelTNz3At 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/Carbon-Document/venv/lib/python3.11/site-packages/torch/sparse/semi_structured.py__new__z"SparseSemiStructuredTensor.__new__O   s   N + 	.MH
 	 	 	 	 ,0C(
 $$&&& M((---$OO!&OORSSS44")!'")' 5 
 
 "-H*+D(#4     returnc                 n    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__   sB    tW%% 	B !@AAA.)??$*????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    WT1--T9 rA   )listfilter	__slots__r)   r'   r(   r*   )rI   inner_tensorstensor_metas   `  r?   __tensor_flatten__z-SparseSemiStructuredTensor.__tensor_flatten__   sZ     99994>JJ
 
 J*"	
 k))rA   rU   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<   rT   rU   
outer_sizeouter_strider)   r'   r(   r*   s	            r?   __tensor_unflatten__z/SparseSemiStructuredTensor.__tensor_unflatten__   s     NYJ(*;]s $$Xt44""6400"&&z488 $$Xt4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__   sp    s':::%< @ @/3}@ @ @   9s"4#78udFS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        j        t2          t          j        j        j        t6          t          j        j        j        t:          t          j        j        j        t>          i| _         || j         !                    |           dS dS dS )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   s   
 3)4008	%'9	&(;	+-@	&(;	%'9	 -	#%5	!>	%~	$&7	%'9	')<	)+@	$&7	!>#C" %0#**+@AAAAA' 98$ 10rA   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.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   s    & 	=1G = = =     A%%;/B/B/D/D ; ; ;   ,,.. 	C    (DDDj/Djjdgjjj  
 $1/0EFV/0EFVx<<1x<<1x<<1x<<k/D k kS[k k_gk k k   ,8<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  s4    jnxei4:dkRRRS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         " OS"5;0N#NOOOO ND   !OT!!!%*d***LLL(H,----L4
,
lT!!!!L4!&!4444####WWWI +0!"#R RzR t#R lT!	R
 ,%R t#R &+\D%8R $(R R R R R \Rh@# @ @ @ @
*	tCy%
D#t ;<<	=* * * * 
 5:tS$67
 

 
 
 [
. ?Tc T T T [T B B B B [B2 (u| (PT ( ( ( [(TT T T  &" "" " 
&	" " " [" %)	" " "<" lT!	" 
" " " " " "rA   r   Fry   
transposedr   rB   c                     |rt          j        dt          d           t          j        rt
          j        j        nt
          j        j        }|	                    | |          S )a	  
    This function converts a dense tensor into a sparse semi-structured tensor.
    It will return a SparseSemiStructuredTensor, a subclass of torch.Tensor.

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

    Args:
        original_tensor (Tensor): the dense tensor to convert
        transposed (bool, optional): deprecated arg to be removed in another release. Do not use.
        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))
    zSetting 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  ss    h  
R 	
 	
 	
 	
 &4	?66\>  %%of%EEErA   c                   p    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           	          |                      |           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  sf     	,,_=== 6oFF	
! s!($(,)7
 
 
 	
rA   c                     | j         | j        t          d          | j         j        dk    rt	          | j        | j                   nt                                                      S )Nz meta and packed must not be Noner,   )r#   r"   rF   ndimr   superr   )rI   rG   s    r?   r   z*SparseSemiStructuredTensorCUTLASS.to_dense  sj    9 3 !CDDD y~""	 4	  
 !!##	
rA    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   )r6   _sparse_semi_structured_tiler)   r<   ry   r   r"   r#   r$   r%   r&   s           r?   prune_dense_static_sortz9SparseSemiStructuredTensorCUTLASS.prune_dense_static_sort  sh    z .yd
 
 
	
' s!(C
 
 
 	
rA   NFr   should_transpose_denser   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                 }t          j        j                            || j        | j        || j        d         |j        |j        |          S )NZ`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4 	l   >*9>>QVq[[%GHGGG   ;$)"3%BHBBB   *+++7@K9,77	
1**&	 	 	rA   r   )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22sBCC55b"aCC66r2q!DD55b"aCC	   1@
 

 
 
-	
 
 
 [
*

 

 

 

 

 68I
 I
#lI
	%I
 I
 I
 [I
^ %)',! ! !<! lT!	!
 !%! 
! ! ! ! ! ! ! !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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   ry   r   rB   c                     |                      |            | |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  s`     	,,_===s!''88(,&@&P$)7

 

 

 
	
rA   r   r   c           	          t          j        ||d          \  }}}}}|                    |j        d         d          }|                    |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 .ye
 
 
	
' _215r::==!6q!92>> s!(C
 
 
 	
rA   NFr   r   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                 }t          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  s    a344 	l   9>>QVq[[%VDN+VVV   7dj  %YDN+ Y YuTZGXGX Y Y_defel_m_m Y Y $
Y Y9:Y Y Y  
 
dj 8 8%\DN+ \ \uTZGXGX \ \_defel_m_m \ \(,
\ \AB\ \ \   :,,,%`DN+ ` `uTZGXGX ` `_defel_m_m ` `(,
` ` `  
 ;%QDN+QQQ   -...7@K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   "  so       	 	 G;;BBKK
222r2rBB55b"aCC66r2q!DD	   1@
 

 
 
0	
 
 
 [
& 68>
 >
#l>
	%>
 >
 >
 [>
H %)',4 4 4<4 lT!	4
 !%4 
4 4 4 4 4 4rA   r   c                     t           rdS 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            }dS )zLazily 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k    p|dk    }| }|r)t          j        j                            | d|d|
f          }|r|                                n|}|t          j        |||          }nt          j        ||||          }|rC|r|n|	}|d |                             dd|          	                    t          j
                  S |                                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=1HM 	V 8.2251h8:TUUL'=O<>>###<<264JJCC5dFD(SSC 	29qqHM\M"1h''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  sG     &5H5;q>>%+a.{+<	
 
 
 	
rA   )_cutlass_mm_registeredtorch.libraryr   r6   r:   r   r   register_fake)r   r   r   s      r?   r   r     sP     !''''''Y,2>>> |   l  lT!	 
       !%  
      ?> > 
|

 l
 lT!	

 
 
 
 
 

 
 
 
 
 
rA   c                     t           rdS 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            }dS )z,Lazily register the cusparselt_mm custom op.NTr   r   zsemi_structured::cusparselt_mmr   r   Fr   r"   r   r   r   r   fuse_transposer   r   rB   c	                    | j         \  }	}
|	 |z  }|
 |z  }|dk    p|dk    }| }|r)t          j        j                            | d|d|f          }|r|                                n|}t          j        |||||          }|r|                                }|r;|r|	n|
}|                    dd|                              t          j	                  S |
                                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=1HM 	V 8.2251h8:TUUL'=O<>>###<#+
 
 
  	%%''C 	29qqH::aH--33#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  sG     &<O5;q>>Q{+<	
 
 
 	
rA   )F)_cusparselt_mm_registeredr  r   r6   r:   r   r   r  )r   r   r	  s      r?   r   r   	  sl    !  $''''''Y/bAAA (-!  ! |! !  lT!!  	! 
 !  !  !  !  !%!  
!  !  !  BA! F  
|

 lT!
 	

 
 
 
 
 !%
 

 
 
 ! 
 
 
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     si    " " " " " " $ $ $ $ $ $                                           "   ",$C" " H" H" H" H" H" H" H" H"Z ,<DF DF\DFDF DF  	DF DF DF DFNc c c c c(B c c cL] ] ] ] ]+E ] ] ]@  >
 >
 >
B " ?
 ?
 ?
 ?
 ?
rA   