
    uki!                     6   d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlm	Z	m
Z
 ddlmZ ddlmZ ddlZ ej"                  d	      Zej&                  ej(                  ej*                  ej,                  fZej,                  ej0                  fZd
dej,                  fde	de	de	dedede
de	fdZd Zd Zd%dZd Zd Z d Z!ejD                  d        Z# ejH                  ee         ejJ                  e        ejH                  ee!d        ejH                  ee!d        ej"                  d      Z&d%de	de	fdZ'd  Z(e&jR                  d!        Z*e&jD                  d"        Z+ ejX                  e*d#$      Z- ejH                  e&e-        ejJ                  e&       y)&z#N:M-sparsity associated primitives.    )core)dispatch)DotDimensionNumbers)mhlo)Array	DTypeLike)mlirNsparse_dense_matmul)))   )r   ) r   lhsrhsmetadatadimension_numberssparse_operand_idxoutput_dtypereturnc                 8    t         j                  | |||||      S )a  Dot operation where one of the operands has N:M sparsity.

  Args:
    lhs: An ndarray (first dot operand).
    rhs: An ndarray (second dot operand).
    metadata: An ndarray with structured sparsity metadata for the contracting
      dimension. For 2:4 sparsity it should contain (N=2) two-bit index values
      for each (M=4) element group.
    dimension_numbers: a tuple of tuples of the form `((lhs_contracting_dims,
      rhs_contracting_dims), (lhs_batch_dims, rhs_batch_dims))`.
    sparse_operand_idx: index of the sparse operand (0 or 1).
    output_dtype: result type.

  Returns:
    An ndarray dense array containing the result.
  )r   r   r   )	nm_spmm_pbind)r   r   r   r   r   r   s         U/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/jax/experimental/sparse/nm.pynm_spmmr   #   s,    0 
		)+ 
 
     c                 8    | |j                         dz
  z  }d|z  S )Nr      )
bit_length)nm
group_bitss      r   _calc_groups_per_elementr    E   s"    ALLNQ&'*	z	r   c           	          t        t        t        t        |             t        ||z         z
              }t        ||z   |z         t	        t        |             k7  rt        d|       |S )Nz Incorrect dimension numbers for )tuplesortedsetrangelist	TypeError)rankcontractbatchnamenon_contracts        r   _validate_dnumsr-   J   sb    vc%+.X5E1FFGH,L8#e+,U4[0AA
6tf=
>>	r   c                    |dv sJ |t        ||      z  }| |g|   }|d   |   }	|j                  t        j                  k7  rt	        d|j                         |	d   |j
                  dz
  k7  rt	        d      |j                  d d |j                  d d k7  rt	        d      |j                  d   |z  |j                  d   k7  r8t	        d| d	| d
| d|j                  d   |z   d|j                  d    d      |j                  d   |z  dk7  rt        d      | |gd|z
     }
|d   d|z
     }|j                  |	d      |
j                  |d      }}||z  ||z  k7  rt	        d| d
| d| d
|       y )Nr   r   r   zMetadata must be uint16, got r   z+Contracting dimension must be the minor onezRMetadata shape must match the operand shape (except for the contracting dimension)zMetadata must be exactly z/ times less than the contracting dimension for :z structured sparsity (expected , got )z&Metadata with padding is not supportedz(Contracting dimension sizes should have z ratio, got )r    dtypenpuint16r'   ndimshapeNotImplementedError)r   r   r   r   indexr   r   size_factorsparsesparse_contractdensedense_contractabs                 r   _validate_metadatarB   Q   s   	&,Q22+:e&%a(//^^ryy 
3HNN3CD
EEQ6;;?*
A
BB^^CRFLL"--
	"  ^^B+%b)99

#K= 1&&'S! -LL+,F8>>"3E2Fa	I 
 \\"#q(
F
GG*QY
%$Q'E	2.	oa(	)5;;~a7H+IQ!Ua!e^

21#QqcaS!M  r   c                    |\  \  }}\  }}t        |      dk7  st        |      dk7  rt        d      t        | j                  ||d      }t        |j                  ||d      }t        |      dk7  st        |      dk7  rt        d      |D 	cg c]  }	| j                  |	    }
}	|
|D 	cg c]  }	|j                  |	    c}	k7  rt        d      t        |
| j                  |d      |j                  |d      gz         S c c}	w c c}	w )Nr   z.Only single contracting dimension is supportedr   r   z2Only single non-contracting dimension is supportedz"Batch dimension sizes do not matchr   )lenr'   r-   r7   r8   r"   )r   r   r   lhs_contractrhs_contract	lhs_batch	rhs_batchlhs_dimsrhs_dimsir*   s              r   _infer_result_shaperL   r   s    ;L8L,!7)Y!s<0A5
D
EESXX|YF(SXX|YF(]a3x=A-
H
II!*
+A399Q<
+%
+
Y/syy|//
8
99	u		(1+.		(1+0FGG	HH ,/s   D+Dc                      t        d      )Nz,Sparse N:M matmul is only implemented on GPU)r9   )_args_kwargss     r   _nm_spmm_default_loweringrP      s    JKKr   c                   |dv sJ t         j                  j                  |d   |   d   dd      }t         j                  j                  |d   |   |d   d|z
     |d   |   |d   d|z
           }| j                  d   }	dd	g|   }
|
|i}t        j
                  t        j                  |	      |||g|fi |}|j                  S )
Nr/   r         )	dimensionr   r   r   )lhs_batching_dimensionsrhs_batching_dimensionslhs_contracting_dimensionsrhs_contracting_dimensionslhs_sparsityrhs_sparsity)	r   SparsityDescriptorgetr   	avals_outSparseDotOpr	   aval_to_ir_typeresults)ctxr   r   r   r   r   r   sparsity_descriptor	dot_dnumsdot_typekeykwargsops                r   _nm_spmm_gpu_loweringrh      s    
v	%%	%//33!!$%78;qA 4  &&**/23EF/217I3IJ!21!56H!I!21!5a:L6L!M	 + ) ]]1(	();<#$%&
8$c3
IIO" 
r   c                :   | j                   t        vrt        d| j                          |j                   t        vrt        d|j                          |t        vrt        d|       t	        | ||      }t        | ||||       t        j                  ||      S )NzUnsupported lhs input type: zUnsupported rhs input type: zUnsupported output type: )r4   _supported_input_typesr'   _supported_output_typesrL   rB   r   ShapedArray)r   r   r   r   r   r   	res_shapes          r   _nm_spmm_abstract_evalrn      s     	YY,,
2399+>
??YY,,
2399+>
??00
/~>
??!#s,=>)S#x):<NO			)\	22r   cuda)platformrocmsparse_pack_nmmaskc                 2    t         j                  | ||      S )a  Generate metadata tensor for an N:M mask.

  Args:
    mask: Predicates for the input tensor, where the elements are grouped in the
      minor dimension. In each group of size M there should be exactly N true
      values, which mark the data elements to keep.
    n: Number of non-zero elements in a group.
    m: Group size.

  Returns:
    An ndarray containing only the masked input elements.
  )r   r   )	nm_pack_pr   )rs   r   r   s      r   nm_packrv      s     
Q	''r   c           	      L   g }||z  z  }t        dt        |       |      D ]\  }t        t        j                  | |||z    |      d   z        }t        fdt        |      D              }|j                  |       ^ t        j                  |t        j                        S )Nr   )sizec              3   B   K   | ]  \  }}|t        |      z    y wN)pow).0rK   jr   s      r   	<genexpr>z_compress.<locals>.<genexpr>   s     ;$!QC1I;s   )r4   )r%   rD   r"   jnpnonzerosum	enumerateappendarrayr5   r6   )	datar   r   kresultexpectedrK   r:   values	     `      r   	_compressr      s    &!q&\(CIq! a#++d1q1uoH=a@1DEE;)E*:;;E
MM% 
6	++r   c                ^    t              z  t        j                  fdd|       S )Nc                      t        |       S rz   )r   )x
batch_sizer   r   s    r   <lambda>z_nm_pack_impl.<locals>.<lambda>   s    	!Q:. r   r0   )r    r   apply_along_axis)rs   r   r   r   s    ``@r   _nm_pack_implr      s/    +Aq11*			.D
 r   c                b   |t        ||      z  }| j                  t        k7  rt        d| j                         | j                  d   |z  dk7  rt        d| d| j                         t        | j                        }|dxx   |z  cc<   t        j                  |t        j                        S )NzMask should be bool, got r0   r   z,Inner dimension size should be divisible by r2   )
r    r4   boolr'   r8   r&   r   rl   r5   r6   )rs   r   r   r;   rm   s        r   _nm_pack_abstract_evalr      s    ,Q22+	ZZ4
/

|<
==	ZZ^k!Q&

6{m DJJ<	  4::)B-K-			)RYY	//r   F)multiple_results)rR   rS   ).__doc__jax._srcr   r   jax._src.lax.laxr   jax._src.lib.mlir.dialectsr   jax._src.typingr   r   jax.interpretersr	   	jax.numpynumpyr   r5   	Primitiver   int8int16float16bfloat16rj   float32rk   intr   r    r-   rB   rL   rP   rh   def_abstract_evalrn   register_loweringsimple_implru   rv   r   def_implr   r   	lower_fun_nm_pack_loweringr   r   r   <module>r      s   *   0 + , !  
 DNN01	((CIIs{{CLLI <<5  .F!ll		  +	
   D
BIL: 3 3   y"; <   Y    y"7& I   y"7& I
 DNN+,	(% (e ( ,   0 0 #DNN=5I    y"3 4   Y r   