
    uki                    <   d Z ddlmZ ddlmZ ddlZddl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 dd
lmZm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 ddlmZ ddlmZmZm Z   ejB                  d      Z"de"_#        ddZ$e"jJ                  d        Z&e"jN                  d        Z(d Z)d Z*d Z+e)ejX                  e"<   e*ejZ                  e"<   e+ej\                  e"<    ej^                  e" ej`                  e&d             	 	 d	 	 	 ddZ1	 	 d 	 	 	 	 	 d!dZ2y)"a  JAX primitives related to sparse operations.

This is experimental work to explore sparse support in JAX.

The primitives defined here are deliberately low-level: each primitive implements
a common sparse operation (sparse to dense, dense to sparse, sparse matrix/vector
product, sparse matrix/matrix product) for two common sparse representations
(CSR and COO).

These routines have reference implementations defined via XLA scatter/gather
operations that will work on any backend, although they are not particularly
performant. On GPU runtimes built against CUDA 11.0/ROCm 5.0 or newer, each operation is
computed efficiently via cusparse/hipsparse.

Further down are some examples of potential high-level wrappers for sparse objects.
(API should be considered unstable and subject to change).
    )annotations)partialN)	tree_util)	JAXSparse)BCOO)BCSR)COO)CSRCSC)_coo_extract)mlir)core)dtypes)ad)batching)Array	DTypeLikeShapetodenseFc                \    t        j                  |       \  }}t        j                  |d|iS )zIConvert input to a dense matrix. If input is already dense, pass through.tree)r   tree_flatten	todense_pbind)arrbufsr   s      V/home/cdr/jupyterlab/.venv/lib/python3.12/site-packages/jax/experimental/sparse/api.pyr   r   =   s*    %%c**$		)D	))    c                r    t        j                  | |      }t        |t              r|j	                         S |S N)r   tree_unflatten
isinstancer   r   r   r   r   s      r   _todense_implr$   B   s.      t,#$S)4=#=r   c                    t        j                  | |      }t        |t        j                        r|S t        j                  |j
                  |j                  t        j                  |j                              S )N)	weak_type)
r   r!   r"   r   ShapedArrayshapedtyper   is_weakly_typeddatar#   s      r   _todense_abstract_evalr,   G   sX      t,#T%%&J			#))SYY&:P:PQTQYQY:Z	[[r   c                   t        |d   t        j                        rJ t        d |dd  D              sJ t	        j
                  | d|i}t	        j
                  |d   g| dd  d|i}||fS )Nr   c              3  P   K   | ]  }t        |t        j                           y wr    )r"   r   Zero).0ts     r   	<genexpr>z_todense_jvp.<locals>.<genexpr>P   s     :Z277#:s   $&   r   )r"   r   r/   allr   r   )primalstangentsr   primals_outtangents_outs        r   _todense_jvpr9   N   st    RWW--	-	:Xab\:	::	:3d3+EgabkEE,	l	""r   c                  t        j                  |d         sJ t        d |dd  D              rJ t               }t	        j
                  ||gt        |      z        }ddlm}m	} ddl
m} ddlm} ||u r| fS t        ||      r|\  }	}
 ||
|       |
fS t        ||      r|\  }	}
} ||
||       |
|fS t        |t              r|\  }	}}t!        |||       ||fS t#        dt%        |             )Nr   c              3  F   K   | ]  }t        j                  |        y wr    )r   is_undefined_primal)r0   bufs     r   r2   z%_todense_transpose.<locals>.<genexpr>W   s     A'',As   !r3   )r   r   )_bcoo_extract)bcsr_extractztodense_transpose for )r   r<   anyobjectr   r!   lenjax.experimental.sparser   r   jax.experimental.sparse.bcoor>   jax.experimental.sparse.bcsrr?   r"   r	   r   NotImplementedErrortype)ctr   r   standinobjr   r   r>   r?   _indicesindptrrowcols                 r   _todense_transposerP   U   s   			Q	((	(AQRAAA	AH'  y3t9'<=#087G^5L#tJAw"%w..#tAw,gv==#sKAsCS"%sC//
 6tCykB
CCr   c               V     t        j                  t        t        |      |      |  dfS )N)r   r   )jaxvmapr   r$   )batched_args
batch_dimsr   s      r   _todense_batching_rulerV   l   s'    	@'-d3Z	@,	OQR	RRr   )multiple_resultsc           	         t         t        t        t        t        d}||vr(t        d|dt        |j                                      ||   } |j                  | f||d|S )a~  Create an empty sparse array.

  Args:
    shape: sequence of integers giving the array shape.
    dtype: (optional) dtype of the array.
    index_dtype: (optional) dtype of the index arrays.
    format: string specifying the matrix format (e.g. ['bcoo']).
    **kwds: additional keywords passed to the format-specific _empty constructor.
  Returns:
    mat: empty sparse matrix.
  )bcsrbcoocoocsrcsczsparse_format=z  not recognized; must be one of )r)   index_dtype)	r   r   r	   r
   r   
ValueErrorlistkeys_empty)r(   r)   r^   sparse_formatkwdsformatsclss          r   emptyrg   v   sr     4CL''!
~m%6 7''+GLLN';&<> ? ?#	E	HK	H4	HHr   c           	     J   t         t        t        t        d}|| }t	        j
                  t        j                  |       } t	        j
                  t        j                  |      }t	        j
                  t        j                  |      }||   } |j                  d|| |||d|S )a  Create 2D sparse identity matrix.

  Args:
    N: int. Number of rows in the output.
    M: int, optional. Number of columns in the output. If None, defaults to `N`.
    k: int, optional. Index of the diagonal: 0 (the default) refers to the main
       diagonal, a positive value refers to an upper diagonal, and a negative value
       to a lower diagonal.
    dtype: data-type, optional. Data-type of the returned array.
    index_dtype: (optional) dtype of the index arrays.
    format: string specifying the matrix format (e.g. ['bcoo']).
    **kwds: additional keywords passed to the format-specific _empty constructor.

  Returns:
    I: two-dimensional sparse matrix with ones along the k-th diagonal.
  )rZ   r[   r\   r]   )MNkr)   r^    )	r   r	   r
   r   r   concrete_or_erroroperatorindex_eye)	rj   ri   rk   r)   r^   rc   rd   re   rf   s	            r   eyerq      s    $ #c#>'Y	A
X^^Q/!
X^^Q/!
X^^Q/!#		NAau+	N	NNr   )r   zJAXSparse | Arrayreturnr   )Nint32rZ   )
r(   r   r)   DTypeLike | Noner^   r   rc   strrr   r   )Nr   Nrs   rZ   )rj   intri   z
int | Nonerk   rv   r)   rt   r^   r   rc   ru   rr   r   )3__doc__
__future__r   	functoolsr   rn   rR   r   jax.experimental.sparse._baser   rD   r   rE   r   jax.experimental.sparse.coor	   jax.experimental.sparse.csrr
   r   jax.experimental.sparse.utilr   jax.interpretersr   jax._srcr   r   jax._src.interpretersr   r   jax._src.typingr   r   r   	Primitiver   rW   r   def_implr$   def_abstract_evalr,   r9   rP   rV   primitive_jvpsprimitive_transposesprimitive_batchersregister_lowering	lower_funrg   rq   rl   r   r   <module>r      sK  $ #   
  3 - - + 0 5 !   $ * 3 3 DNN9%	"	 *
 > > \ \#D.S  ,  ) %7  	 ")?  I &   y.$..E#+ , PW%II2;I* MQ?EOO9<OR[Or   