
    VpfH                       d 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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mZmZmZmZ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(m)Z) ddl*m+Z+ ddl,m-Z- ddl.m/Z/ ddl.m0Z0 ddl.m1Z1 ddl2m3Z3m4Z4m5Z5 dddZ6dddZ7ddZ8 G d  d!e
          Z9dd&Z:dd+Z;dd-Z<dd.Z=ej>        d/dd4Z? e%j@        d5          ZAd6eA_B        d7ZCdddej>        d8dd=ZDddej>        d>dd@ZEeAjF        dA             ZGeAjH        dB             ZIdC ZJdD ZKdE ZLeKe/jM        eA<   eLe/jN        eA<   eJe0jO        eA<    e1jP        eA e1jQ        eGd6F                      e%j@        dG          ZRddHZSddKZTeRjF        dL             ZUeRjH        dM             ZVdN ZWdO ZXdP ZY e/jZ        eReXdd           eYe/jN        eR<   eWe0jO        eR<    e1jP        eR e1jQ        eUdQF                      e%j@        dR          Z[ddSZ\e[jF        dT             Z]e[jH        dU             Z^dV Z_dW Z`dX Za e/jZ        e[dde_           e`e/jN        e[<   eae0jO        e[<    e1jP        e[ e1jQ        e]dQF                      e%j@        dY          ZbdddZddcZcddiZddj ZeebjH        dk             Zfdl Zgdm Zhdn Zido Zj e/jZ        ebegddeh           eie/jN        eb<   eje0jO        eb<   dp Zk e1jQ        ekd6F          ZlddqZm e1jQ        eedQF          Zn e1jP        eben            e&jo        eb           e+jp        r( e1jP        eb eeme+jq        e+jr                  drs           e+js        r( e1jP        eb eeme+jt        e+ju                  dts           ddwZvdd{Zwejx         G d| de                      Zyd} Zzd~ Z{ e0j|        eye}e}eze{d           dS )zEBCSR (Bached compressed row) matrix object and associated primitives.    )annotations)Sequence)partialN)Any
NamedTuple)lax)	tree_util)	JAXSparse)bcoo)
nfold_vmap_count_stored_elements_csr_to_coo_dot_general_validated_shapeCuSparseEfficiencyWarning
SparseInfoShape)
split_listsafe_zip)api_util)config)core)dispatch)DotDimensionNumbers_dot_general_batch_dim_nums)
gpu_sparse)hlo)ad)batching)mlir)Array	ArrayLike	DTypeLikematBCSRnse
int | Nonereturnc                    t                               t          j        |                                 |                    S )z'Eliminate zeros in BCSR representation.r%   )r$   	from_bcoor   bcoo_eliminate_zerosto_bcoor#   r%   s     \/var/www/html/nettyfy-visnx/env/lib/python3.11/site-packages/jax/experimental/sparse/bcsr.pybcsr_eliminate_zerosr/   3   s,    	1#++--SIII	J	JJ    c                    t                               t          j        |                                 |                    S )a  Sums duplicate indices within a BCSR array, returning an array with sorted indices.

  Args:
    mat : BCSR array
    nse : integer (optional). The number of specified elements in the output matrix. This must
      be specified for bcoo_sum_duplicates to be compatible with JIT and other JAX transformations.
      If not specified, the optimal nse will be computed based on the contents of the data and
      index arrays. If specified nse is larger than necessary, data and index arrays will be padded
      with standard fill values. If smaller than necessary, data elements will be dropped from the
      output matrix.

  Returns:
    mat_out : BCSR array with sorted indices and no duplicate indices.
  r)   )r$   r*   r   bcoo_sum_duplicatesr,   r-   s     r.   bcsr_sum_duplicatesr3   8   s.     
0CHHH	I	IIr0   c                   | \  }}}|\  }}}	|j         dz
  t          |d u           z   t          fd|D                       st          d|dd          d ||f||f||	ffD             \  }
}}|'t	          d t          | |          D                       }t          |g|j        R |j        |j	                  }|
|||fS )	N   c              3  @   K   | ]}|d u pd|cxk    ok     nc V  d S Nr    ).0bn_batchs     r.   	<genexpr>z,_bcsr_batch_dims_to_front.<locals>.<genexpr>N   sH      ??qQ$Y*!q****7****??????r0   zEbatch_dims must be None or satisfy 0 < dim < n_batch. Got batch_dims=z for n_batch=.c              3  x   K   | ]5\  }}|t          j        |dg          nt          j        ||d          V  6d S r7   )r   expand_dimsjnpmoveaxis)r9   argbdims      r.   r<   z,_bcsr_batch_dims_to_front.<locals>.<genexpr>Q   sg       3\ 3\
#t $(<cocA3S\#tQ5O5O3\ 3\ 3\ 3\ 3\ 3\r0   c              3  :   K   | ]\  }}||j         |         V  d S Nshape)r9   rB   dims      r.   r<   z,_bcsr_batch_dims_to_front.<locals>.<genexpr>U   s2      eeSUXUdSYs^UdUdUdUdeer0   indices_sortedunique_indices)
ndimintallNotImplementedErrormaxzipr   rG   rJ   rK   )batched_args
batch_dimsspinfo
batch_sizedataindicesindptr	data_bdimindices_bdimindptr_bdimbatched_databatched_indicesbatched_indptrbatched_spinfor;   s                 @r.   _bcsr_batch_dims_to_frontr`   J   sO   &$)3&)\;L1s<4#7888'	????J???	?	? D
 C%/C C7>C C C D D D3\ 3\y)G\+BV[DYZ3\ 3\ 3\/, eeCj4Q4QeeeeeJz9FL99-3-B-3-BD D D. 
	FFr0   c                  .    e Zd ZU ded<   ded<   ded<   dS )BCSRPropertiesrM   r;   n_denser%   N)__name__
__module____qualname____annotations__r8   r0   r.   rb   rb   \   s+         ,,,,,,
(((((r0   rb   shape1Sequence[int]shape2boolc                P    t          d t          | |          D                       S )Nc              3  (   K   | ]\  }}|d |fv V  dS )r5   Nr8   )r9   s1s2s      r.   r<   z_compatible.<locals>.<genexpr>c   s.      BBvr2RAr7]BBBBBBr0   )rN   r   )rh   rj   s     r.   _compatiblerp   b   s)    	BB&&)A)ABBB	B	BBr0   rW   	jax.ArrayrX   rG   c                   t          j        | j        t           j                  sJ t          j        |j        t           j                  sJ t	          |          }| j        d         }| j        dz
  }t          |          |z
  dz
  }|dk    sJ t          | j        d |         |d |                   st          d| j        d|          t          |j        d |         |d |                   st          d|j        d|          |j        |d          ||         dz   fk    rt          d          t          |||	          S )
Nr5      r   z:indices batch dimensions not compatible for indices.shape=, shape=z8indptr batch dimensions not compatible for indptr.shape=z0indptr shape must match the matrix shape plus 1.)r;   rc   r%   )r@   
issubdtypedtypeintegertuplerG   rL   lenrp   
ValueErrorrb   )rW   rX   rG   r%   r;   rc   s         r.   _validate_bcsr_indicesr|   f   sU   	s{	3	3333	ck	2	2222
,,%b#L1'JJ 1$'	A	W]8G8,eHWHo	>	> `
^GM^^V[^^
_
__	V\(7(+U8G8_	=	= ^
\6<\\TY\\
]
]]\'((g 2444
G
H
HH	c	B	B	BBr0   rV   c           
        t          |||          }t          |          }|j        |j        |j        }}}t          |          |z
  |z
  }|dk    rt          d| d          t          | j        d |         |d |                   st          d| j        d|          | j        |dz    d          |f||dz   d          z   k    r t          d| j        d|d	|d
|          |S )Nrt   z*BCSR array must have 2 sparse dimensions; z
 is given.z4data batch dimensions not compatible for data.shape=ru   r5   zInvalid data.shape=z	 for nse=
, n_batch=
, n_dense=)	r|   ry   r;   rc   r%   rz   r{   rp   rG   )	rV   rW   rX   rG   propsr;   rc   r%   n_sparses	            r.   _validate_bcsrr   {   s&   
 &%
8
8%
,,%-	C7'ZZ'!G+(]]
 - - - - . . .	TZ)5'?	;	; Z
XXXPUXX
Y
YY	Z'A+ SFU7Q;<<-@$@@@
P
PP#PP'PPgPP
Q
QQ	,r0   c                   t          | ||          \  }}}t          t          |          }t          j         || |          | j                  S )z4Given BCSR (indices, indptr), return BCOO (indices).)axis)r|   r   r   r@   stackrL   )rW   rX   rG   r;   _
csr_to_coos         r.   _bcsr_to_bcoor      sM     )&%@@-'1a+w//*	::gv..W\	B	B	BBr0   )index_dtyper    r   r"   tuple[Array, Array]c                   t          j        | |          \  }}}}|dk    rt          d          ||         t          t          |d          fd            }| d          || d                   fS )zGiven BCOO (indices), return BCSR (indices, indptr).

  Note: this assumes that ``indices`` are lexicographically sorted within each batch.
  rt   z6Must have 2 sparse dimensions to be converted to BCSR.F)Nbroadcastedc                    t          j        dz             }|j        dd                              t          j        t          j        |                                                             S )Nr5   )length)r@   zerosatsetcumsumbincountastype)irX   r   n_rowss     r.   get_ptrz_bcoo_to_bcsr.<locals>.get_ptr   sh    Yvz;//F9QRR=SZQv&&&--k::< < = = =r0   ).r5   ).r   )r   _validate_bcoo_indicesr{   r   r   )rW   rG   r   r;   r   r   r   r   s     `    @r.   _bcoo_to_bcsrr      s     !7GG'8Q]]
M
N
NN>&
:e444= = = = = 54=
 
'''&/22	22r0   bcsr_fromdenseTz
The error arose for the nse argument of bcsr_fromdense. In order for
BCSR.fromdense() to be used in traced/compiled code, you must pass a concrete
value to the nse (number of stored elements) argument.
r%   r;   rc   r   r!   r;   rM   rc   c          	         t          j        |           }|}|t          |||          }t          j        t
          j        |t                    }t          t          |||||          |j
                  S )a  Create BCSR-format sparse matrix from a dense matrix.

  Args:
    mat : array to be converted to BCOO.
    nse : number of stored elements in each batch
    n_batch : number of batch dimensions (default: 0)
    n_dense : number of dense dimensions (default: 0)
    index_dtype : dtype of sparse indices (default: int32)

  Returns:
    mat_bcsr: BCSR representation of the matrix.
  Nr   rF   )r@   asarrayr   r   concrete_or_erroroperatorindex_TRACED_NSE_ERRORr$   _bcsr_fromdenserG   )r#   r%   r;   rc   r   	mat_arraynse_arrnse_ints           r.   r   r      s     k#) #'_$YAAG'ARSS'	oiWg&-;H H HO
% 
% 
% %r0   )r;   rc   r   tuple[Array, Array, Array]c                   t          j        |           } t          j        t          j        |t                    }t                              | ||||          S )a  Create BCSR-format sparse matrix from a dense matrix.

  Args:
    mat : array to be converted to BCSR, with
      ``ndim = n_batch + n_sparse + n_dense``.
    nse : number of stored elements in each batch.
    n_batch : number of batch dimensions (default: 0)
    n_dense : number of dense dimensions (default: 0)
    index_dtype : dtype of sparse indices (default: int32)

  Returns:
    data : array of shape
    ``mat.shape[:n_batch] + (nse,) + mat.shape[mat.ndim - n_dense:]``
      and dtype ``mat.dtype``
    indices : array of shape ``mat.shape[:n_batch] + (nse,)`` and dtype of
      ``index_type``.
    indptr: array of shape ``mat.shape[:n_batch] + (mat.shape[n_batch] + 1,)``
      and dtype of ``index_type``.
  r   )	r@   r   r   r   r   r   r   bcsr_fromdense_pbind)r#   r%   r;   rc   r   s        r.   r   r      sR    * 	C#x~s4EFF#			sWg+6 
 
8 
8 8r0   c                   t          j        |           } | j        |z
  |z
  }|dk    rt          d          t	          j        | ||||          }t          |j        | j                  \  }}|j	        ||fS )Nrt   .bcsr_fromdense: must have 2 sparse dimensions.r%   r   rc   r;   rF   )
r@   r   rL   r{   r   bcoo_fromdenser   rW   rG   rV   )	r#   r%   r;   rc   r   r   bcoo_matrW   rX   s	            r.   _bcsr_fromdense_implr      s    C#X')(]]
E
F
FF #;)0'C C C(!("2#)DDD/'6		''r0   c                  | j         |z
  |z
  }|dk    rt          d          | j        d |         |fz   | j        ||z   d          z   }| j        d |         |fz   }| j        d |         | j        |         dz   fz   }t          j        || j                  t          j        ||          t          j        ||          fS )Nrt   r   r5   )rL   r{   rG   r   ShapedArrayrw   )	r#   r%   r;   rc   r   r   
data_shapeindex_shapeindptr_shapes	            r.   _bcsr_fromdense_abstract_evalr      s    X')(]]
E
F
FFy'"cV+ci(8J8K8K.LL*	(7(#sf,+8G8$	'(:Q(>'@@,

:sy
1
1

;
4
4

<
5
5
7 7r0   c                   | \  }|\  }d|cxk    r|k    sn t          d|d|          t          |||dz   ||          |||ffS )Nr   z'Expected 0 < bdim <= n_batch; got bdim=r~   r5   r   )r{   r   )rR   rS   r%   r;   rc   r   MrC   s           r.   _bcsr_fromdense_batching_ruler     s{    "!
%$
t



w




M$MM7MM
N
NN	Wq['Wb	c	c	cfjlprvew	wwr0   c               d   | \  }|\  }t          |||||          }|\  }	}
}t          |          t          j        u r t          j                            |	          }nt          |
||          }|t          j                            |
          t          j                            |          f}||fS )Nr   )r   typer   Zero
from_valuebcsr_extract)primalstangentsr%   r;   rc   r   r   Mdotprimals_outrV   rW   rX   data_dottangents_outs                 r.   _bcsr_fromdense_jvpr     s    "!
%$sGWZefff+%$	$ZZ27w!!$''HHGVT22HBG..w779K9KF9S9ST,	l	""r0   c               Z   | \  }}}|j         |z
  |z
  }	|j        |j        d |         |fz   |j        ||	z   d          z   k    sJ |j        |j        d |         |	|fz   k    sJ |j        |j        d |         |j        |         dz   fz   k    sJ |j        |k    sJ |j        |k    sJ t          |t          j                  st          |t          j                  rt          d          t	          j        |          sJ t          |||t          |j
        j                            S )Nr5   /Cannot transpose with respect to sparse indicesrT   )rL   rG   rw   
isinstancer   r   r{   is_undefined_primal_bcsr_todenser   aval)
ctr   r%   r;   rc   r   rV   rW   rX   r   s
             r.   _bcsr_fromdense_transposer     sL   $Vg'(	qwxx(C61AGGh<N<O<O4PP	P	P	P	P	!'(7(+xo=	=	=	=	=	'*agg.>.B-DD	D	D	D	D	+	%	%	%	%		$	$	$	$!! HZ%@%@ H
F
G
GG			"	""""	tWfZ5M5M	N	N	NNr0   )multiple_resultsbcsr_todensec                P    t          | j        | j        | j        | j                  S )zConvert batched sparse matrix to a dense matrix.

  Args:
    mat: BCSR matrix.

  Returns:
    The dense version of ``mat``.
  r   )r   rV   rW   rX   _info)r#   s    r.   r   r   6  s#     
sxcj	K	K	KKr0   rT   r   c                   t                               t          j        |           t          j        |          t          j        |          |          S )a	  Convert batched sparse matrix to a dense matrix.

  Args:
    data : array of shape ``batch_dims + (nse,) + dense_dims``.
    indices : array of shape ``batch_dims + (nse,)``.
    indptr : array of shape ``batch_dims + (shape[len(batch_dims)] + 1,).
    spinfo : SparseInfo. In particular, this includes the shape
      of the matrix, which is equal to
      ``batch_dims + 2(sparse_dims) + block_dims`` where
      ``len(sparse_dims) == 2``.
  Returns:
    mat : array with specified shape and dtype matching ``data``
  r   )bcsr_todense_pr   r@   r   )rV   rW   rX   rT   s       r.   r   r   B  sK     
		S[..G0D0D [00 
 
A 
A Ar0   c                   |j         }t          |||          }t          j        | |f|                                          S NrF   )rG   r   r   BCOOtodense)rV   rW   rX   rT   rG   bcoo_indicess         r.   _bcsr_todense_implr   U  sC    
,%we<<<,
)T<(
6
6
6	?	?	A	AAr0   c               h    |j         }t          | |||           t          j        || j                  S rE   )rG   r   r   r   rw   )rV   rW   rX   rT   rG   s        r.   _bcsr_todense_abstract_evalr   \  s2    
,%w...		%	,	,,r0   c               X    t          | ||          \  }}}}t          ||||          dfS )Nr   r   )r`   r   )rR   rS   rT   rV   rW   rX   s         r.   _bcsr_todense_batching_ruler   c  s9    ";L*V\"]"]$	tWfV	<	<	<a	??r0   c               *    ~t          | |||          S )Nr   )r   )r   rV   rW   rX   rT   s        r.   _bcsr_todense_jvpr   h  s    
	x&	@	@	@@r0   c                  |j         }t          j        |          sJ t          j        |          st          j        |          rt          d          | j         |k    sJ | j        |j        j        k    sJ t          |||           ||fS )Nr   )rG   r   r   r{   rw   r   r   )r   rV   rW   rX   rT   rG   s         r.   _bcsr_todense_transposer   m  s    
,%			%	%%%%G$$ H(>v(F(F H
F
G
GG	U					TY_	$	$	$	$	gvr	*	*GV	;;r0   Fr   c                :    t                               | ||          S )zExtract values from a dense matrix at given BCSR (indices, indptr).

  Args:
    indices: An ndarray; see BCSR indices.
    indptr: An ndarray; see BCSR indptr.
    mat: A dense matrix.

  Returns:
    An ndarray; see BCSR data.
  )bcsr_extract_pr   )rW   rX   r#   s      r.   r   r     s     
		Wfc	2	22r0   c                    t          j        |          }t          | ||j                  }t	          j        ||          S r   )r@   r   r   rG   r   _bcoo_extract)rW   rX   r#   r   s       r.   _bcsr_extract_implr     s:    C#wci@@@,		L#	.	..r0   c                    t          | ||j                  \  }}}|j        d |         |fz   |j        |j        |z
  d          z   }t          j        ||j                  S rE   )r|   rG   rL   r   r   rw   )rW   rX   r#   r;   rc   r%   	out_shapes          r.   _bcsr_extract_abstract_evalr     sa    0&#)LL'7Ci!SF*SYsx'7I7J7J-KK)		)SY	/	//r0   c                H    | j         |j         k    sJ t          |||           S rE   )rG   r   )arr_dotrW   rX   arrs       r.   _bcsr_extract_jvpr     s)    	#)	#	#	#	#	gvw	/	//r0   c           
     $   t          j        |          sJ t          j        |          st          j        |          rt          d          | j        |j        j        k    sJ ||t          | ||t          |j        j                            fS )Nr   r   )r   r   r{   rw   r   r   r   rG   )r   rW   rX   r   s       r.   _bcsr_extract_transposer     s    			$	$$$$G$$ H(>v(F(F H
F
G
GG	SX^	#	#	#	#	&-GVJsx~D^D^___	__r0   c                2   | \  }}}d |D             }t          |          dk    rt          d          t          t          |                    }|d         t	          j        ||f          }|d         t	          j        ||f          }|d         Lt          |j                  }|                    ||j        |                    t	          j	        |||f          }|j
        dz
  }||k    rt          d|d|          t          |||          |fS )Nc                    h | ]}||S rE   r8   )r9   r:   s     r.   	<setcomp>z._bcsr_extract_batching_rule.<locals>.<setcomp>  s    555Aq}a}}}r0   r5   z+bcoo_extract with unequal batch dimensions.r   rt   zbatch_dims=z' out of range for indices with n_batch=)rz   rO   nextiterr   r?   listrG   insertbroadcast_in_dimrL   r{   r   )	rR   rS   rW   rX   r   bdim_setrC   result_shaper;   s	            r.   _bcsr_extract_batching_ruler     s#   %'6355555(]]a
K
L
LL	d8nn		$]ogw//G]_VdW--F]	??LgmD1222

sL4'
:
:CL1'	W__
N
NNGNN
O
OO	gvs	+	+T	11r0   bcsr_dot_general)	precisionpreferred_element_typelhsBCSR | Arrayrhsdimension_numbersr   r   Noner   c          	     `   ~t          |t          j        t          j        f          ryt          | t          j        t          j        f          rt          j        | |||          S t          | t                    r&| j        \  }}}t          ||||||| j
                  S t          d          )a<  A general contraction operation.

  Args:
    lhs: An ndarray or BCSR-format sparse array.
    rhs: An ndarray or BCSR-format sparse array..
    dimension_numbers: a tuple of tuples of the form
      `((lhs_contracting_dims, rhs_contracting_dims),
      (lhs_batch_dims, rhs_batch_dims))`.
    precision: unused
    preferred_element_type: unused

  Returns:
    An ndarray or BCSR-format sparse array containing the result. If both inputs
    are sparse, the result will be sparse, of type BCSR. If either input is
    dense, the result will be dense, of type ndarray.
  r  r   r  r   
lhs_spinfozDbcsr_dot_general currently implemented for BCSR lhs and ndarray rhs.)r   npndarrayjaxr    r   dot_generalr$   _bufs_bcsr_dot_generalr   rO   )r   r  r  r   r   lhs_datalhs_indices
lhs_indptrs           r.   r   r     s    ( bj#),-- 
5#
CI.// L_S#9J4JL L L L #t 5*-)'hZxj#1B6L*-)5 5 5 5
 	 3 	4 	4 4r0   r  r  r  r   r  c          	        |\  \  }}\  }	}
t          j        |          t          j        |          f}t          j        |	          t          j        |
          f}t                              t	          j        |           t	          j        |          t	          j        |          t	          j        |          ||f||          S Nr  )r   _ensure_index_tuplebcsr_dot_general_pr   r@   r   )r  r  r  r  r  r   r  lhs_contractrhs_contract	lhs_batch	rhs_batchcdimsbdimss                r.   r  r    s    
 :K6< 6I'55'557%'	22'	224%		 	 X!6!6!$[!9!9!$Z!8!8#+c:J:J495>8N,6 
! 
8 
8 8r0   c                  t          j        |           } t          j        |          }t          j        |          }t          j        |          }t          |||j                  }	t	          j        | |	||||          S NrF   r  )r@   r   r   rG   r   _bcoo_dot_general_impl)
r  r  r  r  r  r   r  lhs_bcsr_indiceslhs_bcsr_indptrlhs_bcoo_indicess
             r.   _bcsr_dot_general_implr!    s    [""([--K
++/C#"#3_)3)9; ; ;		$X/?7H<R0:
< 
< 
< <r0   c                  |\  \  }}\  }	}t          |||j                  t          j        t	          t
          j        ||          t          j        |j        | j                  t          j        |j        |j                            }
|	r2t          |	          j
        k    rt          d|	dj
                  t          fd|D                       rt          d          t          j        |
j        |
j                  S )Nr  zqbcsr_dot_general batch dimensions must be among the batch dimensions in the sparse representtaion.
got lhs_batch=z, props.n_batch=c              3  4   K   | ]}|j         d z   k    V  dS )rt   N)r;   )r9   dr   s     r.   r<   z2_bcsr_dot_general_abstract_eval.<locals>.<genexpr>&  s/      99Aema	999999r0   z4bcsr_dot_general: contracting over dense dimensions.)r|   rG   r
  
eval_shaper   r   r  ShapeDtypeStructrw   rP   r;   rO   anyr   r   )r  r  r  r  r  r   r  lhs_contractingr   r  out_avalr   s              @r.   _bcsr_dot_general_abstract_evalr*    s!    *;&?AA
 j*:J
K
K%^CO/#9; ; ; )8>::CI..0 0(  -3y>>U]22
,, , =, ,- - -
 	999999999 V
T
U
UU		(.(.	9	99r0   c          	     0    ~t          | ||||||          S r  r  )lhs_data_dotr  r  r  r  r  r   r  s           r.   _bcsr_dot_general_jvp_lhsr.  ,  s-    	<j#->2H&0
2 
2 
2 2r0   c          	     0    ~t          |||| |||          S r  r,  )rhs_dotr  r  r  r  r  r   r  s           r.   _bcsr_dot_general_jvp_rhsr1  5  s-    		8[*g->2H&0
2 
2 
2 2r0   c          	     z    t          |||j                  }t          j        | ||||||          \  }	}
}|	|||fS r  )r   rG   r   _bcoo_dot_general_transpose)r   r  r  r  r  r  r   r  r   data_outr   rhs_outs               r.   _bcsr_dot_general_transposer6  >  sg     #:#35 5 59($c=N3
L L L(Aw 
;
G	33r0   c                   | ^ }}|^ }}t          ||||d n|j        |                   ^ }	}
t          t          |j                  |j        fd|f|          \  }}t          g |	|R |
||d}||fS )N)rU   r   )r  r  r   )r`   rG   r   rz   rL   r  )rR   rS   r  r   r  lhs_argsr  lhs_dimsrhs_bdimnew_lhs_argsnew_lhs_spinfonew_dimension_numbersresult_batch_dimbatched_outs                 r.   _bcsr_dot_general_batch_ruler@  I  s      .8S"8X";h
'ttSYx-@#B #B #B< -H
:ch'!X8I-K -K))! Q< Q Q Q4I9OQ Q Q+ 
&	&&r0   c                  t          | |||          }|j        rDt          t          |||j        d                    } t	          ||j                  | ||          S |d         }t          j        |j        | j        d          }t          j
        ||k     | d          } t          j        |j        |j        d          }	t          j
        |	|k     |d          }| |gS )N)r  rG   rs   r   )r   r;   r   "_bcsr_correct_out_of_bound_indicesr   r   broadcasted_iotarw   rG   r@   where)
rV   rW   rX   r  rG   r   fextenti_data	i_indicess
             r.   rB  rB  _  s    
w
6
6%
] ?25CXYYYA':a''gv>>>":&dj!<<&	6F?D!	,	,$"6<BB)Ii&('155'
r0   c          
        t           j        j        st          ||||||||	          S |\  \  }
}\  }}|j        \  }}}}t          ||||	j                  }d}|j        }|s|rd}n|j        |j        k    rd}n|||j        k    rd}nt          |	j                  dk    s	|j	        dvrd}nx|j
        s|j        rd}ngt          |
          dgk    rd}nP|t          j        t          j        t          j        t          j        fvr t%          j        d|dt(                     d}|rt          ||||||||	          S t+          ||||||	j        	          \  }}|j	        dk    r| }d
}n^|j	        dk    r;|}d}|d         dk    r*t-          j        |t1          j        ddg                    }nt5          d|j	         d           |||||f|	j        d|j        |j        d||j        igS )Nr  FTrt   )r5   rt   r5   zEbcsr_dot_general cusparse/hipsparse lowering not available for dtype=z). Falling back to default implementation.rF   x_dtypeB_dtyper   )permutationzrhs has to be 1d or 2d; get zd.)rG   	transpose
data_dtyper   )r   bcoo_cusparse_loweringvalue"_bcsr_dot_general_default_loweringavals_inr   rG   rw   rz   rL   r;   rc   r   r  float32float64	complex64
complex128warningswarnr   *_bcsr_correct_out_of_bound_indices_loweredr   rM  r   dense_int_arrayr{   )csr_matvec_loweringcsr_matmat_loweringctxr  r  r  r  r  r   r  r  r  r  r  lhs_data_avallhs_indices_avallhs_indptr_avalrhs_avalr   use_default_loweringrw   dot_general_fnrJ  s                          r.   _bcsr_dot_general_gpu_loweringrd  n  s   
 
	&	, -	8[*c)3	    :K6< 6I?B|<-!?H
%
8HJ J% 

%  )  x~--).DH[.[.[
:!!X]&%@%@}    LaS  RZR\2=IIIM KK K K+- - -   -	8[*c)3	    E;
Cz7GI I I(K ]a(NGG}(NGA!M#4+?A+G+GHHHc
EHMEEE
F
FF
.;
C 6)/5$1$7%5%;6 6 $X^4	6 6 
7 7r0   cuda)platformrocmr   broadcast_dimensionsc                   t          j        |                                 ||          }t                              |          S )N)rG   rh  )r   bcoo_broadcast_in_dimr,   r$   r*   )r#   rG   rh  result_bcoos       r.   bcsr_broadcast_in_dimrl    s>    *KKMM5IK K K+		$	$$r0   operandsSequence[BCSR]	dimensionc               r    t                               t          j        d | D             |                    S )aP  Sparse implementation of :func:`jax.lax.concatenate`

  Args:
    operands : Sequence of BCSR arrays to concatenate. The arrays must have equal
      shapes, except in the `dimension` axis. Additionally, the arrays must have
      have equivalent batch, sparse, and dense dimensions.
    dimension : Positive integer specifying the dimension along which to concatenate
      the arrays. The dimension must be among batch or sparse dimensions of the input;
      concatenation along dense dimensions is not supported.

  Returns:
    A BCSR array containing the concatenation of the inputs.
  c                6    g | ]}|                                 S r8   )r,   )r9   r#   s     r.   
<listcomp>z$bcsr_concatenate.<locals>.<listcomp>  s     ===S3;;=====r0   )ro  )r$   r*   r   bcoo_concatenate)rm  ro  s     r.   bcsr_concatenatert    s?     
==H===SSS
U 
U Ur0   c                      e Zd ZU dZded<   ded<   ded<   ded<    ed           Z ed	           Z ed
           Z ed           Z	 ed           Z
ded<   ded<    ed           Z ed           Zed             Zdddd1 fdZd Zd Zd Zed             Zedddddd d!            Zd2d3d'Zedej        ddd(d)            Zd* Zd4d,Zed5d.            Zedddd/d0            Z xZS )6r$   z3Experimental batched CSR matrix implemented in JAX.rq   rV   rW   rX   r   rG   c                &    | j         j        d         S )Nrs   )rW   rG   selfs    r.   <lambda>zBCSR.<lambda>  s    dl04 r0   c                    | j         j        S rE   )rV   rw   rw  s    r.   ry  zBCSR.<lambda>  s
    	 r0   c                     | j         j        dz
  S )Nr5   )rW   rL   rw  s    r.   ry  zBCSR.<lambda>  s    $,"3a"7 r0   c                    dS Nrt   r8   )r   s    r.   ry  zBCSR.<lambda>  s     r0   c                4    | j         j        | j        j        z
  S rE   )rV   rL   rW   rw  s    r.   ry  zBCSR.<lambda>  s    $).4<3D"D r0   rk   rJ   rK   c                *    | j         | j        | j        fS rE   )rV   rW   rX   rw  s    r.   ry  zBCSR.<lambda>  s    DL$+ F r0   c                B    t          | j        | j        | j                  S rE   )r   rG   rJ   rK   rw  s    r.   ry  zBCSR.<lambda>  s!    
4:t7J+/+>!@ !@ r0   c                T    t          | j        | j        | j        dz                      S r}  )ry   rG   r;   rw  s    r.   _sparse_shapezBCSR._sparse_shape  s%    DL)99:;;;r0   FrI   argsr   ri   c                  t          t          j        |          \  | _        | _        | _        || _        || _        t                      	                    ||           t          | j        | j        | j        | j                   d S r   )mapr@   r   rV   rW   rX   rJ   rK   super__init__r   rG   )rx  r  rG   rJ   rK   	__class__s        r.   r  zBCSR.__init__  sp    +.s{D+A+A(DIt|T[(D(D	GGT'''49dlDKDDDDDr0   c                r   | j         j        }	 | j        }| j        }| j        }| j        }t          | j                  }d|}|r|d|z  }|r|d|z  }| d| | | d}n# t          $ r | d}Y nw xY wt          | j
        t          j                  rt          | j
                  j         d| d}|S )	N, nse=r~   r   ()z(<invalid>)[])r  rd   r%   r;   rc   rw   r   rG   	Exceptionr   rV   r   Tracerr   )	rx  namer%   r;   rc   rw   rG   extrarepr_s	            r.   __repr__zBCSR.__repr__  s   >"D/Hcggje4:e 3kke	*%???*%	*%???*%...u.e...ee  # # #"""eee# $)T[)) 5di)44E444eLs   0A$ $A65A6c                     t          d          )NzTranspose is not implemented.)rO   )rx  r  kwargss      r.   rM  zBCSR.transpose  s    
=
>
>>r0   c                \    | j         | j        | j        f| j                                        fS rE   )rV   rW   rX   r   _asdictrw  s    r.   tree_flattenzBCSR.tree_flatten  s(    It|T[14:3E3E3G3GGGr0   c                    t                               |           }|\  |_        |_        |_        |                                h dk    rt          d|           |j        j        di | |S )N>   rG   rJ   rK   z&BCSR.tree_unflatten: invalid aux_data=r8   )	object__new__rV   rW   rX   keysr{   __dict__update)clsaux_datachildrenobjs       r.   tree_unflattenzBCSR.tree_unflatten  sv    
..

C(0%CHck3:}}GGGGGBxBBCCCCL##(###Jr0   Nint32r   )rw   r   rc   r;   r%   c          
        t          |          }|dk     s|dk     s|dk     rt          d|d|d|d|          t          |          |z
  |z
  }|dk    rt          d          t          |||g          \  }}	}
t	          j        g |||
R |          }t	          j        g ||R t	          j        |	d                   |          }t	          j        g ||	d         dz   R |          } | |||f|	          S )
z?Create an empty BCSR instance. Public method is sparse.empty().r   zInvalid inputs: shape=r   r~   r  rt   z1BCSR sparse.empty: must have 2 sparse dimensions.r5   rF   )ry   r{   rz   r   r@   r   fullarray)r  rG   rw   r   rc   r;   r%   r   batch_shapesparse_shapedense_shaperV   rW   rX   s                 r.   _emptyzBCSR._empty$  sB    %LLE{{gkkS1WWR%RRGRRRRCRRSSS5zzG#g-H1}}JKKK-79@(8K.M .M*K{96{6C6+66>>Dh**c**CIl1o,F,F"$ $GY::l1o&9::KHHF3gv&e4444r0   Tr%   r&   remove_zerosr'   c                J    |rt          | |          S t          | |          S )aq  Return a copy of the array with duplicate indices summed.

    Additionally, this operation will result in explicit zero entries removed, and
    indices being sorted in lexicographic order.

    Because the size of the resulting representation depends on the values in the
    arrays, this operation is not compatible with JIT or other transforms. To use
    ``sum_duplicates`` in such cases, you may pass a value to `nse` to specify the
    desired size of the output representation.

    Args:
      nse : integer (optional), if specified, gives the number of specified elements in
        the output sparse representation; if it is larger than the number required, data
        will be padded with zeros and indices will be padded with out-of-bounds values.
        If it is smaller than the number required, data will be silently discarded.
      remove_zeros : bool (default=True). If True, remove explicit zeros from the data
        as part of summing duplicates. If False, then explicit zeros at unique indices
        will remain among the specified elements. Note: remove_zeros=True is incompatible
        with autodiff.
    r)   )r/   r3   )rx  r%   r  s      r.   sum_duplicateszBCSR.sum_duplicates6  s2    *  0!$C0000 3////r0   r   c               *    t          |||||          S )z2Create a BCSR array from a (dense) :class:`Array`.r   )r   )r  r#   r%   r   rc   r;   s         r.   	fromdensezBCSR.fromdenseP  s&     #3K")7< < < <r0   c                     t          |           S )z$Create a dense version of the array.)r   rw  s    r.   r   zBCSR.todenseW  s    r0   	bcoo.BCOOc                    t          | j        | j        | j                  }t	          j        | j        |f| j                  S r   )r   rW   rX   rG   r   r   rV   )rx  coo_indicess     r.   r,   zBCSR.to_bcoo[  s:    dkLLLK9di-TZ@@@@r0   r   c                    |j         dk    rt          d|j                   |j        s|                                }t	          |j        |j                  \  }} | |j        ||f|j                  S )Nrt   z5BSCR.from_bcoo requires n_sparse=2; got arr.n_sparse=rF   )r   rO   rJ   sort_indicesr   rW   rG   rV   )r  r   rW   rX   s       r.   r*   zBCSR.from_bcoo_  s~    
|q Z3< Z Z[[[ c#CKsyAAAOGV3'6*#)<<<<r0   )r   rc   r;   c                  |dk    s|dk    rt          d          |j        dk    rt          d|j         d          |                                }t	          j        |j                  }t	          j        |j                                      |pt          j	                  }t	          j        |j
                                      |pt          j	                  } | |||f|j                  S )z5Create a BCSR array from a :mod:`scipy.sparse` array.r   z4BCSR from_scipy_sparse with nonzero n_dense/n_batch.rt   z*BCSR from_scipy_sparse requires 2D array; zD is given.rF   )rO   rL   r{   tocsrr@   r   rV   rW   r   r  rX   rG   )r  r#   r   rc   r;   rV   rW   rX   s           r.   from_scipy_sparsezBCSR.from_scipy_sparseh  s     !||w!|| VWWW
x1}}YCHYYYZZZ
))++C;sx  Dk#+&&--k.FSYGGG[$$++K,D39EEF3gv&ci8888r0   )r  r   rG   ri   rJ   rk   rK   rk   )NT)r%   r&   r  rk   r'   r$   )r'   r  )r   r  r'   r$   )rd   re   rf   __doc__rg   propertyr%   rw   r;   r   rc   r  r   r  r  r  rM  r  classmethodr  r  r  r  r  r  r   r,   r*   r  __classcell__)r  s   @r.   r$   r$     s        ;;///,,,4455#
(//
0
0%H7788'Xkk""(HDDEE'
(FF
G
G%
( @ @ A A% < < 8< ',EE E E E E E E E  &? ? ?H H H   ; "&GQA5 5 5 5 ;5"0 0 0 0 04 !%28Q< < < < ;<  A A A A = = = ;= 15q! 9 9 9 9 ;9 9 9 9 9r0   c                   ||S ||j         k    rt          d| d|j          d          t           | |j        |           | |j        |           | |j        |          f|j        d |         |j        |dz   d          z             S )NzCannot map in_axis= for BCSR array with n_batch=zM. in_axes for batched BCSR operations must correspond to a batched dimension.r5   rF   r;   r{   r$   rV   rW   rX   rG   )contr   valr   s       r.   _bcsr_to_eltr  y  s    	\J	S[
 :4 : :: : : ; ; ; 
ttCHd##tCK&&tCJ%%' Iete$sy';;
= 
= 
= =r0   c           	         ||S ||j         k    rt          d| d|j          d          t           | ||j        |           | ||j        |           | ||j        |          f|j        d |         |fz   |j        |d          z             S )NzBCSR: cannot add out_axis=r  zC. BCSR batch axes must be a contiguous block of leading dimensions.rF   r  )r  	axis_sizeeltr   s       r.   _bcsr_from_eltr    s    	\J	CK
 ?$ ? ? #? ? ? @ @ @ 
ttIsx..tIs{D11tIsz4002 Iete$	|3ci6FF
H 
H 
H Hr0   rE   )r#   r$   r%   r&   r'   r$   )rh   ri   rj   ri   r'   rk   )rW   rq   rX   rq   rG   ri   r'   rb   )
rV   rq   rW   rq   rX   rq   rG   ri   r'   rb   )rW   rq   rX   rq   rG   ri   r'   rq   )rW   r    rG   ri   r   r"   r'   r   )r#   r!   r%   r&   r;   rM   rc   rM   r   r"   r'   r$   )r#   r!   r%   rM   r;   rM   rc   rM   r   r"   r'   r   )r#   r$   r'   r    )
rV   r!   rW   r!   rX   r!   rT   r   r'   r    )rW   r!   rX   r!   r#   r!   r'   r    )r   r   r  r    r  r   r   r  r   r  r'   r    )r  rq   r  rq   r  rq   r  r    r  r   r   r   r  r   r'   r    )r  r   )r#   r$   rG   r   rh  ri   r'   r$   )rm  rn  ro  rM   r'   r$   )~r  
__future__r   collections.abcr   	functoolsr   r   typingr   r   rW  numpyr  r
  	jax.numpyr@   r   r	   jax.experimental.sparse._baser
   jax.experimental.sparser   jax.experimental.sparse.utilr   r   r   r   r   r   r   jax.utilr   r   jax._srcr   r   r   r   jax._src.lax.laxr   r   jax._src.libr   jax._src.lib.mlir.dialectsr   jax._src.interpretersr   r   r   jax._src.typingr    r!   r"   r/   r3   r`   rb   rp   r|   r   r   r  r   	Primitiver   r   r   r   r   def_implr   def_abstract_evalr   r   r   r   primitive_jvpsprimitive_transposesprimitive_batchersregister_lowering	lower_funr   r   r   r   r   r   r   r   defjvpr   r   r   r   r   r   r   r  r   r  r!  r*  r.  r1  r6  r@  rB  rY  rd  rQ  simple_implcuda_is_supportedcuda_csr_matveccuda_csr_matmatrocm_is_supportedrocm_csr_matvecrocm_csr_matmatrl  rt  register_pytree_node_classr$   r  r  register_vmappablerM   r8   r0   r.   <module>r     sy	   L K " " " " " " $ $ $ $ $ $        " " " " " " " "      



                   3 3 3 3 3 3 ( ( ( ( ( (2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 * ) ) ) ) ) ) )                         M M M M M M M M # # # # # # * * * * * * $ $ $ $ $ $ * * * * * * & & & & & & 7 7 7 7 7 7 7 7 7 7K K K K K
J J J J J$G G G G$    Z   C C C CC C C C*    C C C C ,/93 3 3 3 3 30 "4>"233 $(  !  9=Q!"SY% % % % % %0 ABRS-0Y8 8 8 8 8 86 ( ( ( #	7 	7 $#	7x x x# # #"O O O ': " #,E ( )0M , -  '4*1 *1 *1 2 2 2  //	L 	L 	L 	LA A A A& B B B !- - "!-@ @ @
A A A
< < < 
	.+T4 8 8 8*A  '.I N +  ~~t~(0 (0 (0 1 1 1  //3 3 3 3 / / / !0 0 "!00 0 0
` ` `2 2 2* 
	.$&7 8 8 8*A  '.I N +  ~~t~(0 (0 (0 1 1 1 $T^$677 
 (,48"4 "4 "4 "4 "4 "4J8 8 8 8$< < < %: : &%:.2 2 22 2 24 4 4' ' '  
	
7t
#% % %.I * +2N . /
 
 
 .<T^&.? .? .? *F7 F7 F7 F7P &4T^U&4 &4 &4 "  :< < <  ' ( ( ( +$+!'"@","<","<> > $*	+ + + +
  +$+!'"@","<","<> > $*	+ + + +% % % %
U U U U" %Q9 Q9 Q9 Q9 Q99 Q9 Q9 &%Q9j
= 
= 
=
H 
H 
H  D#sL.$ O O O O Or0   