+
    &j                     2   ^ RI t ^ RIHt ^ RIHt ^ RIHt ^ RIt^ RIH	t	H
t
 ^ RIHtHtHtHtHtHtHtHtHtHtHtHtHt . ROt]! R
R4      t ! R R]P6                  4      tR]P:                  3R R llt ! R R]4      t ! R R	]4      t Rs!R t"Rs#R t$R# )    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_SEMI_STRUCTURED_SPARSE_CONFIGz=sparse_min_rows sparse_min_cols dense_min_rows dense_min_colsc                   n  a  ] tR t^*t o Rt^ tRtRtRt. ROt	]
RV 3R lR ll4       tV 3R lR ltV 3R lR lt]V 3R	 lR
 l4       t]P"                  P$                  t]V 3R lR l4       t]RV 3R lR ll4       t]V 3R lR l4       tR t]]3V 3R lR ll4       tRR/V 3R lR lltV 3R ltRtV tR# )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))
Fc                  < V ^8  d   QhRS[ P                  RS[ P                  R,          RS[ P                  R,          RS[ P                  R,          RS[ P                  R,          RS[ P                  R,          RS[R	S[R
S[/	# )   shapepackedNmetapacked_tmeta_tcompressed_swizzled_bitmaskfuse_transpose_cusparseltalg_id_cusparseltrequires_grad)torchSizeTensorboolint)format__classdict__s   "t/Users/jameslopez/projects/CWCArchive/cwc-podcast/.venv/lib/python3.14/site-packages/torch/sparse/semi_structured.py__annotate__'SparseSemiStructuredTensor.__annotate__P   s     R RzzR t#R llT!	R
 ,,%R t#R &+\\D%8R $(R R R    c
           	        V P                   '       gT   \        P                  ! R\        ^R7       RV n         V P	                  4        \
        P                  P                  V 4       Ve   Tp
MVe   Tp
M\        R4      h\
        P                  P                  V VV
P                  V
P                  V
P                  V	R7      pW+n        W;n        WKn        W[n        Wkn        W{n        Wn        V# )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.
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.
stacklevelTz3At least one of packed or packed_t must be provided)devicedtypelayoutr%   )_PROTOTYPE_WARNING_SHOWNwarningswarnUserWarning_load_dispatch_tabler&   _dynamoallow_in_graph
ValueErrorr(   _make_wrapper_subclassr4   r5   r6   r   r   r    r!   r"   r#   r$   )clsr   r   r   r    r!   r"   r#   r$   r%   previous_tensortensors   &&&&&&&&&&  r-   __new__"SparseSemiStructuredTensor.__new__O   s    N +++MMH
 	 ,0C(
 $$& MM((-$O!&ORSS44"))!''"))' 5 
 "-H*+D(#4 r0   c                    < V ^8  d   QhRS[ /# r   return)str)r+   r,   s   "r-   r.   r/      s     @ @# @r0   c                    \        V R 4      '       g   \        R4      hV P                  P                   RV P                   R2# )r   ztensor has no shape attributez(shape=))hasattrAssertionError	__class____name__r   )selfs   &r-   __repr__#SparseSemiStructuredTensor.__repr__   s=    tW%% !@AA..))*'$**Q??r0   c                x   < V ^8  d   QhRS[ S[S[,          S[ S[P                  S[S[S[3,          3,          /# rF   )tuplelistrH   r&   r'   r)   r*   )r+   r,   s   "r-   r.   r/      s5     * *	tCy%

D#t ;<<	=*r0   c                   a  \        \        V 3R  lS P                  4      4      pS P                  S P                  S P
                  S P                  3pW3# )c                     < \        SV 4      R J# N)getattr)xrO   s   &r-   <lambda>?SparseSemiStructuredTensor.__tensor_flatten__.<locals>.<lambda>   s    WT1-T9r0   )rT   filter	__slots__r   r#   r$   r%   )rO   inner_tensorstensor_metas   f  r-   __tensor_flatten__-SparseSemiStructuredTensor.__tensor_flatten__   sT     94>>J
 JJ**""	
 ))r0   c                l   < V ^8  d   QhRS[ S[P                  S[S[S[3,          RS[P
                  /# )r   r_   rG   )rS   r&   r'   r)   r*   r(   )r+   r,   s   "r-   r.   r/      s7     
 
 5::tS$67
 

r0   c                    Vw  rVrxV ! VVP                  R R4      VP                  RR4      VP                  RR4      VP                  RR4      VP                  RR4      VVVR7	      # )r   Nr   r    r!   r"   	r   r   r   r    r!   r"   r#   r$   r%   )get)	r@   r^   r_   
outer_sizeouter_strider   r#   r$   r%   s	   &&&&&    r-   __tensor_unflatten__/SparseSemiStructuredTensor.__tensor_unflatten__   s     NYJ*; $$Xt4""640"&&z48 $$Xt4(5(9(9-t) '@/'
 	
r0   c                    < V ^8  d   QhRS[ /# rF   r   )r+   r,   s   "r-   r.   r/      s     T Tc Tr0   c                    VP                   V P                  9  d&   \        V P                   R VP                   R24      hV P                  VP                   ,          ! WW44      # )zI only supports a specific set of operations, can't perform requested op (rJ   )_overloadpacketSPARSE_DISPATCHNotImplementedErrorrN   )r@   functypesargskwargss   &&&&&r-   __torch_dispatch__-SparseSemiStructuredTensor.__torch_dispatch__   sb    s':'::%<<. !//3}}oQ@  ""4#7#78dSSr0   Nc                   < V ^8  d   QhRR/# )r   rG   N )r+   r,   s   "r-   r.   r/      s     B B Br0   c                *   \        V RR4      Ef   \        P                  P                  P                  \
        \        P                  P                  P                  \        \        P                  P                  P                  \        \        P                  P                  P                  \        \        P                  P                  P                  \        \        P                  P                  P                  \        \        P                  P                  P                  \         \        P                  P                  P"                  \$        \        P                  P                  P&                  \$        \        P                  P                  P(                  \*        \        P                  P                  P,                  \.        \        P                  P                  P0                  \2        \        P                  P                  P4                  \6        \        P                  P                  P8                  \:        \        P                  P                  P<                  \>        /V n         Ve   V P@                  PC                  V4       R# R# R# )zD
Loads the op overload sparse dispatch table for the current class.
rm   N)"rX   r&   opsatenvaluesr   indicesr   is_same_sizer	   detach_detachr   tr   viewr   mmr   matmuladdmmr
   linearr   _to_copyr   
_scaled_mmr   cloner   tor   rm   update)r@   custom_dispatch_tables   &&r-   r;   /SparseSemiStructuredTensor._load_dispatch_table   sm   
 3)408		%%'9		&&(;		++-@		&&(;		%%'9		  -		##%5		!!>		%%~		$$&7		%%'9		'')<		))+@		$$&7		!!>#C" %0##**+@A 1% 9r0   c                8   < V ^8  d   QhRS[ P                  RR/# )r   original_tensorrG   Nr&   r(   )r+   r,   s   "r-   r.   r/      s      ( (u|| (PT (r0   c           	        VP                   '       g   \        RVP                   R24      hVP                  4       ^8w  d   \        RVP                  4        R24      hVP	                  4       '       g   \        R4      hVP
                  V P                  9  d   \        RVP
                   RV  R24      hVP                  w  r#V P                  VP
                  ,          P                  pV P                  VP
                  ,          P                  pW$8  g#   W$,          '       g   W58  g   W5,          '       d    \        R	VP                   R
V RV R24      hR# )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.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, rJ   N)
is_cudaRuntimeErrorr4   dimis_contiguousr5   _DTYPE_SHAPE_CONSTRAINTSr   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   sr    &&&01G1G0H I= =   A%./B/B/D.E F; ;  ,,..C    (D(DD./D/D.EEcdgchhij 
 $$//0E0EFVV//0E0EFVV<1<<1<1<<./D/D.E FSS[R\\^_g^hhik  <Hr0   c           	         V P                   R,          p\        P                  ! V \        P                  ! WP                  V P
                  R7      4      # )   r5   r4   )r   r&   r   eyer5   r4   )rO   cols   & r-   to_dense#SparseSemiStructuredTensor.to_dense  s3    jjnxxeii::dkkRSSr0   c                >   < V ^8  d   QhRS[ P                  RS[RR/# )r   r   alg_idrG   r   r&   r(   r*   )r+   r,   s   "r-   r.   r/   $  s-     " "" " 
&	"r0   c                    \         hrW   rn   r@   r   r   s   &&&r-   
from_dense%SparseSemiStructuredTensor.from_dense#  s
     "!r0   biasc                v   < V ^8  d   QhRS[ P                  RS[ P                  R,          RS[ P                  /# )r   Br   NrG   r   )r+   r,   s   "r-   r.   r/   +  s:     " "<<" llT!	" 
"r0   c                   \         hrW   r   )rO   r   r   rr   s   &&$,r-   _mmSparseSemiStructuredTensor._mm+  s
     "!r0   c                  < V ^8  d   Qh/ S[ ;R&   S[S[P                  S[3,          ;R&   S[;R&   S[;R&   S[;R&   S[;R&   S[S[S[3,          ;R&   S[P                  R,          ;R	&   S[P                  R,          ;R
&   S[P                  R,          ;R&   S[P                  R,          ;R&   S[P                  R,          ;R&   S[;R&   S[ ;R&   # )r   _DEFAULT_ALG_IDr   _FORCE_CUTLASS_FUSE_TRANSPOSEr7   BACKENDrm   Nr   r   r    r!   r"   r#   r$   )	r*   dictr&   r5   r   r)   rH   r   r(   )r+   r,   s   "r-   r.   r/   *   s    $ % & #5;;0N#NOO' (  ) * !+ , #*- 0 L1 2 (H,--3 6 LL47 8 ,,
9 : llT!!; < LL4= > "'!44? @  $#A B C r0   rv   )r   r   r    r!   r"   )Fr   FrW   )rN   
__module____qualname____firstlineno____doc__r   r   r   r7   r]   staticmethodrC   rP   r`   classmethodrh   r&   _C_disabled_torch_function_impl__torch_function__rs   r;   r   r   r   r   __annotate_func____static_attributes____classdictcell__r,   s   @r-   r   r   *   s    " O N!O%* XIR R Rh@ @
* * 
 
. ??T T B B B2 ( (TT  &" " "" %)	" "C  r0   Fc                \    V ^8  d   QhR\         P                  R\        R\        R\        /# )r   r   
transposedr   rG   )r&   r(   r)   r*   r   )r+   s   "r-   r.   r.   5  s@     DF DF\\DFDF DF  	DFr0   c                   V'       d   \         P                  ! R\        ^R7       \        P                  '       d   \
        P                  P                  M\
        P                  P                  pVP                  WR7      # )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.r2   )r   )
r8   r9   FutureWarningr   r   r&   sparser   r   r   )r   r   r   SPARSE_SUBCLASSs   &&& r-   to_sparse_semi_structuredr   5  sg    h R 	
 &444 	66\\>>  %%o%EEr0   c                   Z  a a ] tR tRt oRtRt]P                  ]! ^^^^4      ]P                  ]! ^ ^@^^4      ]P                  ]! ^ ^@^^4      ]P                  ]! ^ ^ ^^4      /t]]P                  3V3R lR ll4       tV 3R lt]RV3R lR ll4       tR	R
RR/V3R lR lltRtVtV ;t# )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.
cutlassc                >   < V ^8  d   QhRS[ P                  RS[RR/# )r   r   r   rG   r   r   )r+   r,   s   "r-   r.   .SparseSemiStructuredTensorCUTLASS.__annotate__  s-     
 

 
 
-	
r0   c           
         V P                  V4       \        V4      w  ppV ! VP                  VVR R R VP                  R7      # )Nr   r   r    r!   r"   r%   )r   r   r   r%   )r@   r   r   sparse_tensor_cutlassmeta_tensor_cutlasss   &&&  r-   r   ,SparseSemiStructuredTensorCUTLASS.from_dense  sW     	,,_= 6oF	
! !!($(,)77
 	
r0   c                   < V P                   e   V P                  f   \        R4      hV P                   P                  ^8X  d!   \	        V P                  V P                   4      # \
        SV `  4       # )Nz meta and packed must not be None)r   r   rL   ndimr   superr   )rO   rM   s   &r-   r   *SparseSemiStructuredTensorCUTLASS.to_dense  sc    99 3 !CDD yy~~"	 4			
 !#	
r0   c                8   < V ^8  d   QhRS[ P                  RR/# r   r   rG   r   r   )r+   r,   s   "r-   r.   r     s%     I
 I
#llI
	%I
r0   c           
     p    \         P                  ! WRR7      w  pppppV ! VP                  VVVVVRR7      # )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   )r&   _sparse_semi_structured_tiler   r@   r   r   r   r   r    r!   r"   s   &&&     r-   prune_dense_static_sort9SparseSemiStructuredTensorCUTLASS.prune_dense_static_sort  sV    z ..d
	
' !!(C
 	
r0   r   Nshould_transpose_denseFc                |   < V ^8  d   QhRS[ P                  RS[ P                  R,          RS[RS[ P                  /# r   r   r   Nr   rG   r&   r(   r)   )r+   r,   s   "r-   r.   r     sD     ! !<<! llT!	!
 !%! 
!r0   c          
     H   \        V\        4      '       d   \        R 4      hV P                  P                  pV P
                  ^8w  g   VP
                  ^8w  d   \        RV R24      hV P                  e   V P                  f   \        RV R24      h\        4        V P                  VP                  ,          p\        P                  P                  P                  VV P                  V P                  VV P                   ^ ,          VP"                  VP$                  V4      # )Z`SparseSemiStructuredTensor @ SparseSemiStructuredTensor` is not supported by the hardware`)` matmul: Broadcasting is not implemented$` matmul: operation is not supported)
isinstancer   r>   rM   rN   r   rn   r   r   _ensure_cutlass_mm_registeredr   r5   r&   rx   semi_structured
cutlass_mmr   dense_min_rowsdense_min_cols)rO   r   r   r   rr   cls_nameconstraintss   &&$$,  r-   r   %SparseSemiStructuredTensorCUTLASS._mm  s     a344l  >>**99>QVVq[%H:FG  ;;$))"3%H:AB  *+77@K99,,77		

1****&	 	r0   rv    )rN   r   r   r   r   r   r&   int8r   float16bfloat16float32r   r   r   r   r   r   r   r   r   r   __classcell__)rM   r,   s   @@r-   r   r   |  s     	 G

22sBC5b"aC6r2q!D5b"aC	   1@@
 
 
*

 I
 I
 I
V! %)	!
 (-! ! !r0   c                   H  a  ] tR tRt o RtRt]P                  ]! ^ ^ ^^4      ]P                  ]! ^ ^ ^^4      ]P                  ]! ^^^^4      ]P                  ]! ^^^^4      /t]]P                  3V 3R lR ll4       t]RV 3R lR ll4       tRR	R
R/V 3R lR lltRtV tR	# )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.

cusparseltc                >   < V ^8  d   QhRS[ P                  RS[RR/# )r   r   r   rG   r   r   )r+   r,   s   "r-   r.   1SparseSemiStructuredTensorCUSPARSELT.__annotate__7  s-     
 

 
 
0	
r0   c                    V P                  V4       V ! VP                  \        P                  ! V4      R R R R \        P
                  VVP                  R7	      # )Nrd   )r   r   r&   _cslt_compressr   r   r%   r   s   &&&r-   r   /SparseSemiStructuredTensorCUSPARSELT.from_dense6  sW     	,,_=!''''8(,&@&P&P$)77

 
	
r0   c                8   < V ^8  d   QhRS[ P                  RR/# r   r   )r+   r,   s   "r-   r.   r  K  s!     >
 >
#ll>
	%>
r0   c           
         \         P                  ! WRR7      w  pppppVP                  VP                  ^ ,          R4      pVP                  VP                  ^,          R4      pV ! VP                  VVVVVRR7      # )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&   r   r   r   r   s   &&&     r-   r   <SparseSemiStructuredTensorCUSPARSELT.prune_dense_static_sortJ  s    Z ..e
	
' _2215r:==!6!6q!92> !!(C
 	
r0   r   Nr   Fc                |   < V ^8  d   QhRS[ P                  RS[ P                  R,          RS[RS[ P                  /# r   r   )r+   r,   s   "r-   r.   r    sD     4 4<<4 llT!	4
 !%4 
4r0   c               t   \        V\        4      '       d   \        R 4      hV P                  ^8w  g   VP                  ^8w  d$   \	        RV P
                  P                   R24      hVP                  V P                  8w  dj   \	        RV P
                  P                   R\        V P                  4       R\        VP                  4       RV P                   RVP                   R24      hVe   VP                  V P                  8w  dj   \	        RV P
                  P                   R\        V P                  4       R\        VP                  4       RV P                   R	VP                   R
24      hV P                  \        P                  8X  d]   \	        RV P
                  P                   R\        V P                  4       R\        VP                  4       RV P                   R2	4      hV P                  f$   \	        RV P
                  P                   R24      h\        4        V P                  VP                  ,          p\        P                  P                   P#                  VV P                  VV P                  ^ ,          VP$                  VP&                  V P(                  V P*                  V4	      # )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>   r   rn   rM   rN   r5   rS   r   r&   float8_e4m3fnr    _ensure_cusparselt_mm_registeredr   rx   r   cusparselt_mmr   r   r#   r$   )rO   r   r   r   rr   r   s   &&$$, r-   r   (SparseSemiStructuredTensorCUSPARSELT._mm  sz    a344l  99>QVVq[%DNN++,,UV  77djj %DNN++,,FuTZZGXFYY^_defelel_m^n o  $

|=	 BYY 
 

djj 8%DNN++,,FuTZZGXFYY^_defelel_m^n o((,

|=	 J\\  ::,,,%DNN++,,FuTZZGXFYY^_defelel_m^n o((,

| 4`` 
 ;;%DNN++,,PQ  -.77@K99,,::

1****..&&&
 
r0   rv   r   )rN   r   r   r   r   r   r&   r
  r   r   r   r   r   r   r   r   r   r   r   r   r   r   s   @r-   r   r   "  s     	 G;BBK

22r2rB5b"aC6r2q!D	   1@@
 
 
& >
 >
 >
@4 %)	4
 (-4 4 4r0   c                     \         '       d   R# Rs ^ RIHp  V ! RR
R7      R R l4       pVP                  R R	 l4       pR# )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``.
NT	custom_opzsemi_structured::cutlass_mmmutates_argsc                    V ^8  d   QhR\         P                  R\         P                  R\         P                  R\         P                  R,          R\        R\        R\        R	\        R
\         P                  /	# )r   denser   r   r   Nout_featuresr   r   r   rG   r&   r(   r*   r)   )r+   s   "r-   r.   3_ensure_cutlass_mm_registered.<locals>.__annotate__  s{        ||   ll  llT!	 
       !%  
 r0   c                 $   V P                   w  rV) V,          p
V	) V,          pV
^ 8g  ;'       g    V^ 8g  pT pV'       d/   \        P                  P                  P	                  V ^ V^ V
34      pV'       d   VP                  4       MTpVf   \        P                  ! WV4      pM\        P                  ! W1W.4      pV'       dA   V'       d   TMT	pVRV P                  ^^ V4      P                  \        P                  R7      # VP                  4       # )r   Nmemory_format)r   r&   nn
functionalpadr   _sparse_semi_structured_mm_sparse_semi_structured_addmmnarrowr   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   1_ensure_cutlass_mm_registered.<locals>.cutlass_mm  s     {{B(?B(?q=11HM 88..2251h8:TUL'=<>>#<<226JC55dDSC2qHM\"1h'U%<%<=
 ~~r0   c                    V ^8  d   QhR\         P                  R\         P                  R\         P                  R\         P                  R,          R\        R\        R\        R	\        R
\         P                  /	# )r   r  r   r   r   Nr  r   r   transpose_denserG   r  )r+   s   "r-   r.   r    s{     
 
||

 ll
 llT!	

 
 
 
 
 

r0   c                     V'       d   V P                   ^ ,          MV P                   ^,          p\        P                  ! VVV P                  V P                  R7      # r   r   r   r&   emptyr5   r4   )	r  r   r   r   r  r   r   r,  r)  s	   &&&&&&&& r-   _cutlass_mm_fake7_ensure_cutlass_mm_registered.<locals>._cutlass_mm_fake  sB     &55;;q>%++a.{{++<<	
 	
r0   rv   )_cutlass_mm_registeredtorch.libraryr  register_fake)r  r   r1  s      r-   r   r     sJ     !',2>  ? > 
 
r0   c                     \         '       d   R# Rs ^ RIHp  V ! RR
R7      RR R ll4       pVP                  R R	 l4       pR# )z,Lazily register the cusparselt_mm custom op.NTr  zsemi_structured::cusparselt_mmr  c                    V ^8  d   QhR\         P                  R\         P                  R\         P                  R,          R\        R\        R\        R\        R	\        R
\        R\         P                  /
# r   r  r   r   Nr  r   r   fuse_transposer   r   rG   r  )r+   s   "r-   r.   6_ensure_cusparselt_mm_registered.<locals>.__annotate__  s     !  ! ||! !  llT!!  	! 
 !  !  !  !  !%!  
! r0   c	                    V P                   w  rV	) V,          pV
) V,          pV^ 8g  ;'       g    V^ 8g  pT pV'       d/   \        P                  P                  P	                  V ^ V^ V34      pV'       d   VP                  4       MTp\        P                  ! VVVVVR7      pV'       d   VP                  4       pV'       d>   V'       d   T	MT
pVP                  ^^ V4      P                  \        P                  R7      # VP                  4       # )r   )r   transpose_resultr   r  )r   r&   r  r  r  r   _cslt_sparse_mmr   r   r!  r"  )r  r   r   r  r   r   r9  r   r   r   r   r#  r$  r%  r&  r'  r(  r)  s   &&&&&&&&&         r-   r  7_ensure_cusparselt_mm_registered.<locals>.cusparselt_mm  s     {{B(?B(?q=11HM 88..2251h8:TUL'=<>>#<##+
 %%'C2qH::aH-33#55 4   ~~r0   c                    V ^8  d   QhR\         P                  R\         P                  R\         P                  R,          R\        R\        R\        R\        R	\        R
\        R\         P                  /
# r8  r  )r+   s   "r-   r.   r:  7  s     
 
||

 llT!
 	

 
 
 
 
 !%
 

r0   c	                     V'       d   V P                   ^ ,          MV P                   ^,          p	\        P                  ! VV	V P                  V P                  R7      # r.  r/  )
r  r   r   r  r   r   r9  r   r   r)  s
   &&&&&&&&& r-   _cusparselt_mm_fake=_ensure_cusparselt_mm_registered.<locals>._cusparselt_mm_fake6  sB     &<5;;q>Q{{++<<	
 	
r0   rv   )F)_cusparselt_mm_registeredr4  r  r5  )r  r  rA  s      r-   r  r  	  sL     !  $'/bA!  B! F   
 !
r0   )r   r   r   r   )%r8   collectionsr   collections.abcr   typingr   r&   )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   r3  r   rC  r  rv   r0   r-   <module>rJ     s     " $     " ",$C" H" H"Z ,<<DFNc(B cL]+E ]@  >
B " ?
r0   