
    Vpf:                       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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 d dlmZmZ  G d de          Ze	eeeef         edf         Z	 	 	 	 	 	 dMdNd&Z	 	 dOdPd(Z 	 	 dOdQd)Z!d* Z"d+ Z#	 	 	 	 	 dRdSd0Z$dTd3Z%d4 Z&d5 Z'd6 Z(d7 Z)dUd8Z*d9 Z+ ej,        e%e&d:          Z- ej.        e-e)e*           e+ej/        e-<   d; Z0d< Z1d,d=d>Z2 ej3        e-e2            ej3        e- ee2d?=          d@A            ej3        e- ee2d?=          dBA           dC Z4dD Z5dVdEZ6dF Z7dG Z8dWdHZ9dI Z:dXdKZ;dL Z<dS )Y    )annotations)Sequence)partialN)
NamedTupleUnion)core)dtypes)util)ad)batching)mlir)lax)hlo)Array	DTypeLikec                  2    e Zd ZU dZded<   ded<   ded<   dS )ConvDimensionNumbersa  Describes batch, spatial, and feature dimensions of a convolution.

  Args:
    lhs_spec: a tuple of nonnegative integer dimension numbers containing
      `(batch dimension, feature dimension, spatial dimensions...)`.
    rhs_spec: a tuple of nonnegative integer dimension numbers containing
      `(out feature dimension, in feature dimension, spatial dimensions...)`.
    out_spec: a tuple of nonnegative integer dimension numbers containing
      `(batch dimension, feature dimension, spatial dimensions...)`.
  Sequence[int]lhs_specrhs_specout_specN)__name__
__module____qualname____doc____annotations__     X/var/www/html/nettyfy-visnx/env/lib/python3.11/site-packages/jax/_src/lax/convolution.pyr   r   #   sB         	 	 r   r      lhsr   rhswindow_stridesr   paddingstr | Sequence[tuple[int, int]]lhs_dilationSequence[int] | Nonerhs_dilationdimension_numbers"ConvGeneralDilatedDimensionNumbersfeature_group_countintbatch_group_count	precisionlax.PrecisionLikepreferred_element_typeDTypeLike | Nonereturnc                   t          | j        |j        |          }|d| j        dz
  z  }nJt          |t                    r5t          |          |                    d          k    st          d          |d|j        dz
  z  }t          |t                    rz|\  }}}t          j	        |j        |          dd         }d t          ||          D             }t          j        t          j	        | j        |          dd         |||          }nG	 t          d |D                       }n,# t          t          f$ r}t          d|           |d}~ww xY w|
dn%t          j        t          j        |
                    }
t$                              | |t          |          t          |          t          |          t          |          |||t          j        |	          |
	          S )
a  General n-dimensional convolution operator, with optional dilation.

  Wraps XLA's `Conv
  <https://www.tensorflow.org/xla/operation_semantics#conv_convolution>`_
  operator.

  Args:
    lhs: a rank `n+2` dimensional input array.
    rhs: a rank `n+2` dimensional array of kernel weights.
    window_strides: a sequence of `n` integers, representing the inter-window
      strides.
    padding: either the strings `'SAME'`, `'SAME_LOWER'`, or `'VALID'`, or a
      sequence of `n` `(low, high)` integer pairs that give the padding to apply
      before and after each spatial dimension. `'SAME'` and `'SAME_LOWER'` add
      padding to produce same output size as the input. The padding is split
      between the two sides equally or almost equally. In case the padding is an
      odd number, the extra padding is added at the end for `'SAME'` and at the
      beginning for `'SAME_LOWER'`.
    lhs_dilation: `None`, or a sequence of `n` integers, giving the dilation
      factor to apply in each spatial dimension of `lhs`. LHS dilation is also
      known as transposed convolution.
    rhs_dilation: `None`, or a sequence of `n` integers, giving the dilation
      factor to apply in each spatial dimension of `rhs`. RHS dilation is also
      known as atrous convolution.
    dimension_numbers: either `None`, a ``ConvDimensionNumbers`` object, or a
      3-tuple ``(lhs_spec, rhs_spec, out_spec)``, where each element is a string
      of length `n+2`.
    feature_group_count: integer, default 1. See XLA HLO docs.
    batch_group_count: integer, default 1. See XLA HLO docs.
    precision: Optional. Either ``None``, which means the default precision for
      the backend, a :class:`~jax.lax.Precision` enum value
      (``Precision.DEFAULT``, ``Precision.HIGH`` or ``Precision.HIGHEST``), a
      string (e.g. 'highest' or 'fastest', see the
      ``jax.default_matmul_precision`` context manager), or a tuple of two
      :class:`~jax.lax.Precision` enums or strings indicating precision of
      ``lhs`` and ``rhs``.
    preferred_element_type: Optional. Either ``None``, which means the default
      accumulation type for the input types, or a datatype, indicating to
      accumulate results to and return a result with that datatype.

  Returns:
    An array containing the convolution result.

  In the string case of ``dimension_numbers``, each character identifies by
  position:

  - the batch dimensions in ``lhs``, ``rhs``, and the output with the character
    'N',
  - the feature dimensions in `lhs` and the output with the character 'C',
  - the input and output feature dimensions in rhs with the characters 'I'
    and 'O' respectively, and
  - spatial dimension correspondences between lhs, rhs, and the output using
    any distinct characters.

  For example, to indicate dimension numbers consistent with the ``conv``
  function with two spatial dimensions, one could use ``('NCHW', 'OIHW',
  'NCHW')``. As another example, to indicate dimension numbers consistent with
  the TensorFlow Conv2D operation, one could use ``('NHWC', 'HWIO', 'NHWC')``.
  When using the latter form of convolution dimension specification, window
  strides are associated with spatial dimension character labels according to
  the order in which the labels appear in the ``rhs_spec`` string, so that
  ``window_strides[0]`` is matched with the dimension corresponding to the first
  character appearing in rhs_spec that is not ``'I'`` or ``'O'``.

  If ``dimension_numbers`` is ``None``, the default is ``('NCHW', 'OIHW',
  'NCHW')`` (for a 2D convolution).
  Nr       r    zString padding is not implemented for transposed convolution using this op. Please either exactly specify the required padding or use conv_transpose.c                >    g | ]\  }}t          j        ||          S r   r   
dilate_dim).0krs      r   
<listcomp>z(conv_general_dilated.<locals>.<listcomp>   s(    ZZZTQ4?1a00ZZZr   c              3  l   K   | ]/\  }}t          j        |          t          j        |          fV  0d S N)operatorindex)r9   lohis      r   	<genexpr>z'conv_general_dilated.<locals>.<genexpr>   sS       - - "b  ~b))8>"+=+=> - - - - - -r   zdpadding argument to conv_general_dilated should be a string or a sequence of (low, high) pairs, got 	r#   r$   r&   r(   r)   r+   r-   r.   r0   )conv_dimension_numbersshapendim
isinstancestrlencount
ValueErrornptakezipr   padtype_to_padstuple	TypeErrorr	   canonicalize_dtypedtypeconv_general_dilated_pbindcanonicalize_precision)r!   r"   r#   r$   r&   r(   r)   r+   r-   r.   r0   dnumslhs_permrhs_perm_	rhs_shapeeffective_rhs_shapees                     r   conv_general_dilatedr_   8   s6   X !CI7H
I
I%38a<(LL'3 L(9(9\=O=OPQ=R=R(R(R
	   38a<(L @!Hh	8,,QRR0IZZSL=Y=YZZZ!
	8$$QRR(*=! !GG@ - -$+- - - - -gg	" @ @ @	8.5	8 	89 9>?@@ %,dd)? @ @AA  
 	$	$	3u^44eGnn&&U<5H5H-)*9553 
% 
5 
5 5s   D/ /E EErI   c                ,    t          | |||||          S )a  Convenience wrapper around `conv_general_dilated`.

  Args:
    lhs: a rank `n+2` dimensional input array.
    rhs: a rank `n+2` dimensional array of kernel weights.
    window_strides: a sequence of `n` integers, representing the inter-window
      strides.
    padding: either the string `'SAME'`, the string `'VALID'`.
    precision: Optional. Either ``None``, which means the default precision for
      the backend, a :class:`~jax.lax.Precision` enum value (``Precision.DEFAULT``,
      ``Precision.HIGH`` or ``Precision.HIGHEST``) or a tuple of two
      :class:`~jax.lax.Precision` enums indicating precision of ``lhs``` and ``rhs``.
    preferred_element_type: Optional. Either ``None``, which means the default
      accumulation type for the input types, or a datatype, indicating to
      accumulate results to and return a result with that datatype.

  Returns:
    An array containing the convolution result.
  r.   r0   r_   )r!   r"   r#   r$   r.   r0   s         r   convrc      s-    , 
c3(15K
M 
M 
M Mr   c           
     0    t          | |||||||          S )a  Convenience wrapper around `conv_general_dilated`.

  Args:
    lhs: a rank `n+2` dimensional input array.
    rhs: a rank `n+2` dimensional array of kernel weights.
    window_strides: a sequence of `n` integers, representing the inter-window
      strides.
    padding: either the string `'SAME'`, the string `'VALID'`, or a sequence of
      `n` `(low, high)` integer pairs that give the padding to apply before and
      after each spatial dimension.
    lhs_dilation: `None`, or a sequence of `n` integers, giving the
      dilation factor to apply in each spatial dimension of `lhs`. LHS dilation
      is also known as transposed convolution.
    rhs_dilation: `None`, or a sequence of `n` integers, giving the
      dilation factor to apply in each spatial dimension of `rhs`. RHS dilation
      is also known as atrous convolution.
    precision: Optional. Either ``None``, which means the default precision for
      the backend, a :class:`~jax.lax.Precision` enum value (``Precision.DEFAULT``,
      ``Precision.HIGH`` or ``Precision.HIGHEST``) or a tuple of two
      :class:`~jax.lax.Precision` enums indicating precision of ``lhs``` and ``rhs``.
    preferred_element_type: Optional. Either ``None``, which means the default
      accumulation type for the input types, or a datatype, indicating to
      accumulate results to and return a result with that datatype.

  Returns:
    An array containing the convolution result.
  )r&   r(   r.   r0   rb   )r!   r"   r#   r$   r&   r(   r.   r0   s           r   conv_with_general_paddingre      s/    D 
	3l93
5 
5 
5 5r   c                   |dk    r<| |z   dz
  }|| dz
  k    r| dz
  }n\t          t          j        |dz                      }n7|dk    r"| |z   dz
  t          | |z
  d          z   }| dz
  }nt	          d          ||z
  }||fS )a0  Calculate before and after padding for a dim of transposed convolution.

  Args:
    k: int: kernel dimension.
    s: int: dimension stride value.
    padding: 'same' or 'valid' padding mode for original forward conv.

  Returns:
    2-tuple: ints: before and after padding for transposed convolution.
  SAMEr5   r    VALIDr   z'Padding mode must be `SAME` or `VALID`.)r,   rM   ceilmaxrL   )r:   sr$   pad_lenpad_apad_bs         r   _conv_transpose_paddingro      s     !eaiG1q5yy!eee"''A+&&''ee'!eai#a!eQ--'GEEE
>
?
??
E/%	r   c                :    |D ]}t          j        | |          } | S )z9Flip ndarray 'x' along each axis specified in axes tuple.)rM   flip)xaxesaxiss      r   
_flip_axesru   
  s)      d
4AA	
(r   Fstridestranspose_kernelboolc	                R   t          | j                  t          |j                  k    rt          | j                  dk    sJ t          | j                  }	d|	dz
  z  }
|3|	dk    rd}n*|	dk    rd}n!|	dk    rd}n|	d	k    rd
}nt          d          t          | j        |j        |          }t	          j        |j        |j                  }|dd         }t          t                    rBdv r>|d|j	        dz
  z  }t          d ||          }fdt          ||          D             }n}|r[t          |t	          j        |j                  dd                   }|                    |j        d         |j        d                   }t          | ||
||||||	  	        S )a  Convenience wrapper for calculating the N-d convolution "transpose".

  This function directly calculates a fractionally strided conv rather than
  indirectly calculating the gradient (transpose) of a forward convolution.

  Args:
    lhs: a rank `n+2` dimensional input array.
    rhs: a rank `n+2` dimensional array of kernel weights.
    strides: sequence of `n` integers, sets fractional stride.
    padding: 'SAME', 'VALID' will set as transpose of corresponding forward
      conv, or a sequence of `n` integer 2-tuples describing before-and-after
      padding for each `n` spatial dimension.
    rhs_dilation: `None`, or a sequence of `n` integers, giving the
      dilation factor to apply in each spatial dimension of `rhs`. RHS dilation
      is also known as atrous convolution.
    dimension_numbers: tuple of dimension descriptors as in
      lax.conv_general_dilated. Defaults to tensorflow convention.
    transpose_kernel: if True flips spatial axes and swaps the input/output
      channel axes of the kernel. This makes the output of this function identical
      to the gradient-derived functions like keras.layers.Conv2DTranspose
      applied to the same kernel. For typical use in neural nets this is completely
      pointless and just makes input/output channel specification confusing.
    precision: Optional. Either ``None``, which means the default precision for
      the backend, a :class:`~jax.lax.Precision` enum value (``Precision.DEFAULT``,
      ``Precision.HIGH`` or ``Precision.HIGHEST``) or a tuple of two
      :class:`~jax.lax.Precision` enums indicating precision of ``lhs``` and ``rhs``.
    preferred_element_type: Optional. Either ``None``, which means the default
      accumulation type for the input types, or a datatype, indicating to
      accumulate results to and return a result with that datatype.

  Returns:
    Transposed N-d convolution, with output padding following the conventions of
    keras.layers.Conv2DTranspose.
  r5   r4   N)NCIOrz      )NHCHIOr}      )NHWCHWIOr      )NHWDCHWDIOr   z,No 4+ dimensional dimension_number defaults.>   rg   rh   c                ,    t          j        | |          S r>   r7   )r:   r;   s     r   <lambda>z conv_transpose.<locals>.<lambda>Q  s    1(=(= r   c                8    g | ]\  }}t          ||          S r   ro   r9   r:   rk   r$   s      r   r<   z"conv_transpose.<locals>.<listcomp>R  s9     7 7 7! $Aq'22 7 7 7r   r   r    ra   )rJ   rF   rL   rE   rM   rN   r   rH   rI   rG   maprO   ru   arrayswapaxesr_   )r!   r"   rv   r$   r(   r)   rw   r.   r0   ndimsonednk_shapek_sdimseffective_k_sizepadss      `            r   conv_transposer     s   R 
SY3sy>>	)	)c#)nn.A.A.A.A
ci..%	#zz,	!/	!2	!5EFFFci4EFF"GCIr{++'ABBK'  '->">">SX\*l==wUU7 7 7 7+W557 7 7DD D 7
S"(2;//3
4
4C
,,r{1~r{1~
6
6C	c3T7L"(15K
M 
M 
M Mr   core.ShapedArraytuple[int, ...]c          	        t          |          t          u sJ t          | j                  t          |j                  k    r/d}
t	          |
                    | j        |j                            |dk    s$d}
t	          |
                    |                    | j        |j        d                  }t          ||          \  }}|r%d}
t	          |
                    ||                    t          j	        ||j        |j
        d                            s<d}
t	          |
                    |||j        |j
        d                                      |j        |j
        d                  |z  r;d}
t	          |
                    |j        |j
        d                  |                    |dk    s$d}
t	          |
                    |                    | j        |j        d                  }|dk    r.||z  dk    r%d	}
t	          |
                    ||                    |j        |j
        d                  |z  r;d
}
t	          |
                    |j        |j
        d                  |                    |dk    r+|dk    r%d}
t	          |
                    ||                    t          t          |j
                            t          |          k    rQd}
t	          |
                    t          t          |j
                            t          |                              |\  }}}t          j        t          j        | j        |          |          }t          j        t          j        |j        |          |          }t!          |||||          }t#          t          j        |t          j        |                              S )Nz\conv_general_dilated lhs and rhs must have the same number of dimensions, but got {} and {}.r   zLconv_general_dilated feature_group_count must be a positive integer, got {}.r    zkconv_general_dilated feature_group_count must divide lhs feature dimension size, but {} does not divide {}.zconv_general_dilated lhs feature dimension size divided by feature_group_count must equal the rhs input feature dimension size, but {} // {} != {}.zconv_general_dilated rhs output feature dimension size must be a multiple of feature_group_count, but {} is not a multiple of {}.zJconv_general_dilated batch_group_count must be a positive integer, got {}.zgconv_general_dilated batch_group_count must divide lhs batch dimension size, but {} does not divide {}.zconv_general_dilated rhs output feature dimension size must be a multiple of batch_group_count, but {} is not a multiple of {}.zxAt most one of batch_group_count and feature_group_count may be > 1, got batch_group_count={} and feature_group_count={}ziconv_general_dilated window and window_strides must have the same number of dimensions, but got {} and {})typer   rJ   rF   rL   formatr   divmodr   definitely_equalr   _conv_sdimsr   _dilate_shaperM   rN   conv_shape_tuplerQ   argsort)r!   r"   r#   r$   r&   r(   r)   r+   r-   unused_kwargsmsglhs_feature_countquotremlhs_batch_countrY   rZ   out_perm	lhs_trans	rhs_trans	out_transs                        r    _conv_general_dilated_shape_ruler   _  s    
	 	 $8	8	8	8	8^^s39~~%%,C
SZZ	3955
6
66	q	 	 1C
SZZ 344
5
55i 1 :1 =>&(;<<)$ I8C
SZZ 35FGG
H
HH		tSY/@/I!/L%M	N	N K'C SZZ 13F #	*;*DQ*G HJ J K K KY )!,-0CC 6NC
SZZ	*;*DQ*G H 35 5 6 6 6 
Q		1C
SZZ 122
3
33I/8;</1BBaGG8C
SZZ 1?CC
D
DDY )!,-0AA 4LC
SZZ	*;*DQ*G H 13 3 4 4 4 2Q66DC
SZZ 13FGG
H
HH&/	0	011S5H5HHH>C


3{#4#=>>??^ATATUUW W W "3(Hh	8 < <lKK)	8 < <lKK)y)^W02 2)	rwy"*X"6"677	8	88r   c                   t          j        t           j        t           j        t           j        gd| |          }	||	S t          j        |	|           |S )Nr_   )r   naryop_dtype_rule_input_dtype_any _validate_preferred_element_type)
r!   r"   r#   r$   r&   r(   r)   r0   r   result_dtypes
             r    _conv_general_dilated_dtype_ruler     sU     &s'7#(CH9M'=sCI I,#&|5KLLL	r   c                8    | d         | d         f| dd          z   S )Nr    r   r5   r   specs    r   r   r     s     T!Wd1g$6abb$A r   c                    | dd          S )Nr5   r   r   s    r   r   r     s    48 r   c       	        \   t          |          t          u sJ |	dk    s|dk    sJ |j        }|j        j        }t	          t
          |          \  }}}|\  }}}t          |          }|dk    r5t          |d         ||          }t          |d         |d         |          }n<|	dk    r6t          |d         |	|          }t          |d         |d         |          }|	}t          |||          }t          t          j        ||          t          j        ||          |t          j        | j        |          |||          }t          j        ||          }t          | |||||||d|
|          }|	dk    r4t          |d         |	|          }t          |d         |d         |          }|S )Nr    r   rD   )r   r   rF   avalr   r   _conv_spec_transpose_reshape_axis_out_of_reshape_axis_into_conv_general_vjp_lhs_paddingrM   rN   r   revr_   )gr!   r"   r#   r$   r&   r(   r)   r+   r-   r.   r0   r\   	lhs_shape	lhs_sdims	rhs_sdims	out_sdimsr   r   r   
t_rhs_spectrans_dimension_numbersrevd_weightsouts                           r   #_conv_general_dilated_transpose_lhsr     s    
	 	 $8	8	8	8	8	a		#6!#;#;#;#;i)hn)$'5F$G$G!)Y	!2(Hh#H--*1 x{,?
E
EC
Xa[(1+s
;
;CC1
x{,=s
C
CC
Xa[(1+s
;
;C+0:xPP)gi##RWY	%B%Bbgagy117L ' i((,lG!/-Y3	5 	5 	5# 
x{,=s
C
CC
Xa[(1+s
;
;C	*r   c       	        `   t          |          t          u sJ t          j        |           dk    rt	          j        |j                  S |j        }|j        j        }t          t          |          \  }}}t          t          |          \  }}}|	dk    s|dk    sJ |	dk    r|	}d}	n
|dk    r|}	d}t          |||          }t          t          j        ||          t          j        ||          |t          j        | j        |          |||          }t          || |||||||	|
|          S )Nr   r    rD   )r   r   rM   sizer   Zeror   rF   r   r   r   _conv_general_vjp_rhs_paddingrN   r_   )r   r!   r"   r#   r$   r&   r(   r)   r+   r-   r.   r0   r   r\   r   r   r   r   r   r   r   s                        r   #_conv_general_dilated_transpose_rhsr     s[    
	 	 $8	8	8	8	8WQZZ1__738i)hn)$'5F$G$G!)Y	$'(<>O$P$P!)Y		a		#6!#;#;#;#;+Q+0IyQQ)gi##RWY	%B%Bbgagy117L ' 
	1\7n/-)Y3
5 
5 
5 5r   c       	        	   |dk    s|dk    sJ | \  }}|\  }}|\  }}}||j         |         dk    s||j         |         dk    rt          |j                   t          |j                   }}||                    |           ||                    |           t          t	          j        ||j                  t	          j        ||j                  |||||||	  	        }t          j        d|z   d|
|j        n|
          dfS |||j         |         |j         |         k    sJ |dk    r(t          ||d         |          }||j         |         z  }n't          ||d         |          }||j         |         z  }t          ||d         |          }t          ||||||||||	|
          }t          |d         |j         |         |          }||d         fS |*|dk    r\t          ||d         |          }t          |||||||||	|

  
        }t          |d         |j         |         |          }||d         fS t          |d         t          ||d         k              z   ||          }t          |t          |d         |k               z   |d         dz   |          }t          |d         |d         |          }t          ||||||||||	|
          }t          |d         |j         |         |          }||d         fS |u|dk    rc|dk    r]t          ||d         |          }t          ||||||||||	|
          }t          |d         |j         |         |          }||d         fS |dk    r|n|}t          |d         t          ||d         k              z   ||          }t          |t          |d         |k               z   |d         dz   |          }t          |d         |d         |          }t          ||||||||||	|
          }t          |d         ||          }t          |d         dz   |j         |         |          }t          |d         |d         dz   |          }||d         fS d S )Nr    r   )r#   r$   r&   r(   r)   r+   r-   )r   rT   )r+   r-   r.   r0   ra   )rF   listpopr   r   ShapedArrayrT   r   fullr   r_   r   r,   )batched_args
batch_dimsr#   r$   r&   r(   r)   r+   r-   r.   r0   r   r!   r"   lhs_bdimrhs_bdimr   r   r   lhs_shape_unbatchedrhs_shape_unbatchedrF   new_lhsnew_rhsr   group_counts                             r    _conv_general_dilated_batch_ruler     sk   
 
a		#6!#;#;#;#;(#s!(H!2(Hh
 	( 3q 8 8	( 3q 8 8/3CISY,h'''h''',
*CI66
*CI66#W<3D-)+ + +E 8
UlA/7CII') ) ) +,, , h29X#)H"555551"8Xa[#>>g39X.."8Xa[#>>gSYx00 8A;<<G
w|-@)Y3	5 5 5C
 x{CIh,?
E
ECA"8Xa[#>>g #~w!-|=N!4	8NP P Pc !!ci.A3GGc(1+$Xa[3x8A;7N3O3O%O%6= =g"8c(1+2H.I.I#I#+A;?#*, ,g #8A;WEEg #~w!-|=N!46G+48N	P P Pc
 !!ci.A3GGc(1+a$5$:$:"8Xa[#>>g g~w!-|=N!46G+48N	P P Pc
 !!ci.A3GGc(1+ -@!,C,C((+ $Xa[3x8A;7N3O3O%O%0#7 7g"8c(1+2H.I.I#I#+A;?G= =g"8A;WEEg g~w!-|=N!46G+48N	P P Pc
 !!k3??c !q#)H2EsKKcx{HQK!OSAAc(1+? r   r_   c                   t          j        |          t          j        |          }}t          j        |          t          j        |          }} | t          j        ||          |          } | |t          j        ||                    } | |t          j        ||                    }	t          j        t          j        ||	          t          j        ||                    S r>   )r   realimagaddsubcomplex)
mulrr   yx_rex_imy_rey_imk1k2k3s
             r   _complex_mulr     s     x{{CHQKK$x{{CHQKK$
s374%%"
s4t$$%%"
s4t$$%%"	SWR__cgb"oo	6	66r   c                4    t          j        |           j        S r>   )rM   finforT   r   s    r   r   r     s    BHUOO1 r   )expand_complex_convolutionsc       
        :     j         \  }} j        \  }t          |t                    sJ |j        }|rt          j        |t
          j                  r|0t          j        |t
          j                  sJ t          |          }t          j
        t          t          t          t          |||||||	|
|
  
                  d          } | ||          S |\  }}}t          j                            |d         |d         t!          |dd                    |d         |d         t!          |dd                    |d         |d         t!          |dd                    	  	        }t#          |          dz
  }t#          |          dk    r t          j        dt
          j        	          }t          j        dg|z            }t+          j        |          rPt+          j        |          r<t+          j        |          r(t+          j        |          rt+          j        |	          st1          d
          t3          d |D                       rt          j        t          j        |          |||t          j        |          t          j        |	          t          j        |          t          j        |          t          j        |          t          j        |          |t?          j         |
                    gS t          j        t+          j!        dt
          j"                            d fd}t          j#        t!          tI          ||                    t          j        d                    }t          j%        t          j        |          ||||t          j        |          t          j        |	          t          j        |          t          j        |          t          j        |          |t?          j         |
                    gS )NrD   F)multiple_resultsr   r    r5   )	input_batch_dimensioninput_feature_dimensioninput_spatial_dimensionskernel_output_feature_dimensionkernel_input_feature_dimensionkernel_spatial_dimensionsoutput_batch_dimensionoutput_feature_dimensionoutput_spatial_dimensions)r   r5   r   zYConvolutions with non-static strides, dilation, feature_group_count, or batch_group_countc              3  >   K   | ]}t          j        |          V  d S r>   )r   is_constant_shape)r9   ps     r   rC   z._conv_general_dilated_lower.<locals>.<genexpr>  s-      44q		"	"444444r   )	r)   r+   r-   r#   r$   r&   r(   window_reversalprecision_configr    r5   	pad_lo_hi!tuple[core.DimSize, core.DimSize]c                X    t          j        |           }t          j        |          S r>   )r   eval_dynamic_shape_as_tensorr   	ReshapeOp)r   pad1ctxint2ds     r   prep_one_padz1_conv_general_dilated_lower.<locals>.prep_one_pad  s'    .sI>>d]5$'''r   )r)   r+   r-   r#   r&   r(   r   r   )r   r  )&avals_in	avals_outrH   r   rT   rM   
issubdtypecomplexfloating_real_dtyper   	lower_funr   r   r_   r   getr   rJ   zerosint64dense_bool_arrayr   r   is_constant_dimNotImplementedErrorallconvolutionaval_to_ir_typei64_attrdense_int_arraydense_int_elementsr   precision_attrr   int32ConcatenateOpr   dynamic_conv)r  r!   r"   r#   r$   r&   r(   r)   r+   r-   r.   r0   r   r   lhs_avalrhs_avalaval_outrT   complex_convr   r   r   rX   num_spatial_dimsr   r  	d_paddingr  s   `                          @r   _conv_general_dilated_lowerr%    s   
 |(Hm)(	%';	<	<<<<
.%  'R]5":L%M%M ')]123EFFFFF*+ABB>$^l)=N$7"3y'=	? 	? 	?@ @ 	 	 	L <S#&&&!2(Hh

"
&
&"1+$QK!(122,//$,QK#+A;"8ABB<00#A;%a["8ABB<00 ' 	2 	2% ]]Q&\\QhvRX...G)5'4D*DEE/

 
0
0 {

 
.
.{

 
.
.{ 
2
3
3{ 
0
1
1	{ y
z
zz44G44444 '

x
(
(

!"m,?@@ M*;<<-n==)'22+L99+L99)-i88	: 	: 	: $  !1&"(!C!CDDE( ( ( ( ( ( ( !$s<'A'A"B"B"&-"2"24 4I 	

x
(
(


!"m,?@@ M*;<<-n==+L99+L99)-i88	: 	: 	: r   Tcpu)platformgpuc                      fdt          |j                  D             }|                    |            t          t	          j        |j                             }||xx         |j                  z  cc<   t          j        |||          S )Nc                     g | ]
}|k    |S r   r   )r9   isrcs     r   r<   z&_reshape_axis_into.<locals>.<listcomp>  s    	/	/	/a3hh!hhhr   )	rangerG   insertr   rM   deleterF   r   reshape)r,  dstrr   perm	new_shapes   `    r   r   r      s    
 
0	/	/	/U16]]	/	/	/$++c329QWc**++)C...AGCL ...	Q	4	(	((r   c                    t          |j                  }t          ||          |          \  }}|rJ ||g|| | dz   <   t          j        ||          S )Nr    )r   rF   r   r   r0  )r,  size1rr   rF   size2raggeds         r   r   r     sZ    
qw--%sU++-%U^%CE		Q		r   c           	     f   t          |t                    r't          j        | dd         |dd         ||          }t	          |          t	          |           dz
  k    rBd}t          |                    t	          |           dz
  t	          |                              t          j        | dd         t          j	        t          j
        |                              dd          d                    }t          j        |dk               rt          d| d	| dd                    t          t          t           j        ||dd         |                    }|dk    r| d         |z  dk    sJ | d         |z  }n| d         }||d         f}	t          |	t          |          z             S )
zHCompute the shape tuple of a conv given input shapes in canonical order.r5   NzCWrong number of explicit pads for convolution: expected {}, got {}.r    rt   r   zUNegative padding is larger than the size of the corresponding dimension: got padding=z for lhs_shape[2:]=)rH   rI   r   rP   rJ   rR   r   rM   r   sumr   r0  anyrL   rQ   r   r   
stride_dim)
r   r\   rv   r   r-   r   
lhs_padded	out_spaceout_shape_0	out_shapes
             r   r   r     s   c Ly}imWdKKDYY#i..1$$$
OC
CJJs9~~13t99==
>
>>vimRVBHTNN,B,B2q,I,I34&6 &6 &6 7 7*VJN N
 M$(M M=Fqrr]M M N N NCYqrr]GLLMM)Q<++q0000A,"33KKA,KIaL))	y5+++	,	,,r   c                   t          |          \  }}}t          j        | |          }t          j        ||          }	t          ||	||          }
t	          t          j        |
t          j        |                              S r>   )conv_general_permutationsrM   rN   r   rQ   r   )r   r\   r#   r$   r)   rY   rZ   r   r   r   r   s              r   conv_general_shape_tuplerD  *  sp    !:;L!M!M(Hhgi**)gi**)y)^WMM)	rwy"*X"6"677	8	88r   c                   t          |          \  }}}t          j        | |          }t          j        ||          }	t          t                    r$fdt          |	dd          |          D             t          t          t          j                            d t          |dd          |	dd          |          D             }
t          j        |
gd          	                                }t          |d         |	d         ft          |          z             }t          t          j        |t          j        |                              S )Nc                8    g | ]\  }}t          ||          S r   r   r   s      r   r<   z.conv_transpose_shape_tuple.<locals>.<listcomp>9  s9     > > >1Q 'q!W55 > > >r   r5   c                2    g | ]\  }}}|d z
  |z  |z
  dz   S r   r   )r9   r+  r:   rk   s       r   r<   z.conv_transpose_shape_tuple.<locals>.<listcomp><  s?     9 9 9 Aq cQY]Q& 9 9 9r   r   r:  )rC  rM   rN   rH   rI   rO   r   r   r;  tolistrQ   r   )r   r\   r#   r$   r)   rY   rZ   r   r   r   unpad_out_spacer?  r   s      `         r   conv_transpose_shape_tuplerJ  3  sQ   !:;L!M!M(Hhgi**)gi**) >> > > >im^<<> > >GRVW%%&&'9 9$'	!""(1!""(6%8 %89 9 9/ fow/a888??AA)Yq\9Q<053C3CCDD)	rwy"*X"6"677	8	88r   c           
     ^   t          |t                    r|S t          |           t          |          k    r?d}t          |                    t          |           t          |                              |:t          t          t          |                               }t          |||          S t          |t          t
          f          r.t          |          dk    r1d}t          |                    t          |                              t          d |D                       sDd}t          |                    t          t          t          |                                        d}t          |          D ]W\  }}t          |          t          |           k    r2t          |                    |t          |          | |                    Xt          |          \  }}}	t          |||	          S d}t          |                    t          |                              )	a)  Converts convolution `dimension_numbers` to a `ConvDimensionNumbers`.

  Args:
    lhs_shape: tuple of nonnegative integers, shape of the convolution input.
    rhs_shape: tuple of nonnegative integers, shape of the convolution kernel.
    dimension_numbers: None or a tuple/list of strings or a ConvDimensionNumbers
      object following the convolution dimension number specification format in
      xla_client.py.

  Returns:
    A `ConvDimensionNumbers` object that represents `dimension_numbers` in the
    canonical form used by lax functions.
  zAconvolution requires lhs and rhs ndim to be equal, got {} and {}.Nr|   zBconvolution dimension_numbers list/tuple must be length 3, got {}.c              3  @   K   | ]}t          |t                    V  d S r>   )rH   rI   )r9   elts     r   rC   z)conv_dimension_numbers.<locals>.<genexpr>`  s,      AAz#s##AAAAAAr   z?convolution dimension_numbers elements must be strings, got {}.zzconvolution dimension_numbers[{}] must have len equal to the ndim of lhs and rhs, got {} for lhs and rhs shapes {} and {}.zAconvolution dimension_numbers must be tuple/list or None, got {}.)rH   r   rJ   rR   r   rQ   r-  r   r  r   r   	enumeraterC  )
r   r\   r)   r   iotar+  rM  r   r   r   s
             r   rE   rE   D  s    !#788 ^^s9~~%%
MC
CJJs9~~s9~~>>
?
??s9~~&&''DdD111#dE]33 9
""Pccjj%6!7!788999AA/@AAAAA GMccjjs41B'C'C!D!DEEFFFFC-.. G G3	SS^^	#	#

1c#hh	9EEFFF 
$ $==N#O#O Hh(H===
MC
CJJt$56677
8
88r   c           
     F   | \  }}dx\  }}}}t          |          D ]\  }\  }}	| |                             |          | |                             |	          cxk    rdk    s/n d}
t          |
                    |||	| |                             t	          | |                   t	          t          | |                             k    r+d}
t          |
                    || |                             t          |          t          |          z
  t                    t          |          z
  cxk    r#t          |          t          |          z
  k    s&n d}
t          |
                    |                     fd}t          || |          \  }}}|||fS )zDUtility for convolution dimension permutations relative to Conv HLO.)NC)OIrQ  r    zaconvolution dimension_numbers[{}] must contain the characters '{}' and '{}' exactly once, got {}.zKconvolution dimension_numbers[{}] cannot have duplicate characters, got {}.zaconvolution dimension_numbers elements must each have the same set of spatial characters, got {}.c                     fdt                     D             } urt          | fd          }                     d                                        d                   ft          |          z   S )Nc              3  *   K   | ]\  }}|v	|V  d S r>   r   )r9   r+  ccharpairs      r   rC   z=conv_general_permutations.<locals>.getperm.<locals>.<genexpr>  s1      BBTQ0A0Aq0A0A0A0ABBr   c                :                         |                    S r>   )r@   )r+  r   r   s    r   r   z<conv_general_permutations.<locals>.getperm.<locals>.<lambda>  s    hnnT!W.E.E r   )keyr   r    )rN  sortedr@   rQ   )r   rY  spatialr   s   `` r   getpermz*conv_general_permutations.<locals>.getperm  s    BBBBYt__BBBG8w$E$E$E$E$EFFFgJJx{##TZZ%<%<=gNNr   )rN  rK   rR   r   rJ   setr   )r)   r   r   lhs_charrhs_charout_char	charpairsr+  abr   r^  rY   rZ   r   r   s                  @r   rC  rC  p  s   !2(Hh-OO(HhY'' ; ;ia!QQ%%a((,=a,@,F,Fq,I,INNNNQNNNN3ccjjAq*;A*>??@@@
Q  C,=a,@(A(A$B$BBB#ccjj$5a$899::: C h--#h--
'3x==3x==+H ( ( ( (
h--#h--
'( ( ( (0C
CJJ011
2
22O O O O O "%W.?!K!K(Hh	8X	%%r   list[tuple[int, int]]c                *   t          j        | |          }t          j        ||          }t          j        ||          }	t          j        |d |D                       dz
  }
t          j        ||          dz
  |	z
  |
z
  }t          j        |
|          S )Nc                    g | ]\  }}|S r   r   )r9   rA   r[   s      r   r<   z1_conv_general_vjp_lhs_padding.<locals>.<listcomp>  s    .G.G.Geb!r.G.G.Gr   r    )r   r   rM   subtractr   r
   safe_zip)in_shapewindow_dimensionsr#   rA  r$   r&   r(   lhs_dilated_shaperhs_dilated_shapeout_dilated_shape
pad_before	pad_afters               r   r   r     s     ',??'(9<HH'	>BB{,.G.Gw.G.G.GHH1L*v'):;;a?"#%/0)	z9	-	--r   c                   t          |           dk    rg S t          j        | |          }t          j        ||          }t          j        ||          }	t          j        |          \  }
}t          t          j        |	|          }t          d t          ||
          D                       }t          t          t          j
        ||                    }t          t          |
|                    S )Nr   c              3  ,   K   | ]\  }}||z
  d z
  V  dS )r    Nr   )r9   rdpds      r   rC   z0_conv_general_vjp_rhs_padding.<locals>.<genexpr>  s.      RRBR!RRRRRRr   )rJ   r   r   r
   unzip2r   r?   r   rQ   rO   r   r   )rk  rl  r#   rA  r$   r&   r(   rm  rn  ro  pads_lor[   pads_from_lhspads_from_rhspads_his                  r   r   r     s     	]]aI',??'(9<HH'	>BB{7##*'1hl$57HII-RR#6G2Q2QRRRRR-#hlM=AABB'	c'7##	$	$$r   )NNNr    r    NN)r!   r   r"   r   r#   r   r$   r%   r&   r'   r(   r'   r)   r*   r+   r,   r-   r,   r.   r/   r0   r1   r2   r   )NN)r!   r   r"   r   r#   r   r$   rI   r.   r/   r0   r1   r2   r   )r!   r   r"   r   r#   r   r$   r%   r&   r'   r(   r'   r.   r/   r0   r1   r2   r   )NNFNN)r!   r   r"   r   rv   r   r$   r%   r(   r'   r)   r*   rw   rx   r.   r/   r0   r1   r2   r   )r!   r   r"   r   r2   r   )r)   r   r+   r,   r-   r,   r4   )r2   r   )r2   rf  )=
__future__r   collections.abcr   	functoolsr   r?   typingr   r   numpyrM   jax._srcr   r	   r
   jax._src.interpretersr   r   r   jax._src.laxr   jax._src.lib.mlir.dialectsr   jax._src.typingr   r   r   rQ   rI   r*   r_   rc   re   ro   ru   r   r   r   r   r   r   r   r   standard_primitiverU   defbilinearprimitive_batchersr   r  r%  register_loweringr   r   r   rD  rJ  rE   rC  r   r   r   r   r   <module>r     sZ   # " " " " " $ $ $ $ $ $        $ $ $ $ $ $ $ $                       $ $ $ $ $ $ * * * * * * & & & & & &       * * * * * * , , , , , , , ,    :    &+	#sC-
& " (,'+;?9:!%-1p5 p5 p5 p5 p5n 7;48M M M M M> >BIM%5 %5 %5 %5 %5P  4   9=KO,126>BKM KM KM KM KM\?9 ?9 ?9 ?9D      BA ##:$ $ $L5 5 5 5@i i iV 0/$&F   %224 4 4 % 	 2 37 7 7& 21 !&	W W W W Wr  -/J K K K  G'TJJJ     G'TJJJ   	) 	) 	)  - - - -.9 9 99 9 9")9 )9 )9 )9X& & &:	. 	. 	. 	.% % % % %r   