o
    2hUD                     @   s   d dl Z d dlZd dlZd dlZdd Zdd Zdd Zdd	 Zd
d Z			d,ddZ	dd Z
dd Zdd ZdZdeZde dZdeZdeZdd Zd-dd Zd!d" Zd#d$ Zd%d& Zddd'd(d)Zd.d*d+ZdS )/    Nc                 C   s   |  dv sJ | d | d } |  dkr1|du r!t| ||  n|}| d }| d | }||fS |du r<||  d }n
| | d  d | }t|d |d  | d }|| }||fS )a  Convert the padding arguments from Keras to the ones used by JAX.
    JAX starts with an shape of size `(input-1) * stride - kernel_size + 2`,
    then adds `left_pad` on the left, and `right_pad` on the right.
    In Keras, the `padding` argument determines a base shape, to which
    `output_padding` is added on the right. If `output_padding` is None, it will
    be given a default value.
       samevalid   r   N   )lowermaxmin)kernel_sizestridedilation_ratepaddingoutput_paddingleft_pad	right_padpad_len r   a/var/www/html/chatgem/venv/lib/python3.10/site-packages/keras/src/backend/common/backend_utils.py6_convert_conv_transpose_padding_args_from_keras_to_jax   s    r   c                 C   s  |  dv sJ | }| d | d } |  dkr*|du r#t| ||  n|}d}|}n&|du r4|| d  n|}t| d |  | d  d}d| | d  |  | }|dkrm|dkrmtd| d| d	| d
| d| d ||krtd| d| d| d| d	||fS )a  Convert the padding arguments from Keras to the ones used by Torch.
    Torch starts with an output shape of `(input-1) * stride + kernel_size`,
    then removes `torch_padding` from both sides, and adds
    `torch_output_padding` on the right.
    Because in Torch the output_padding can only be added to the right,
    consistency with Tensorflow is not always possible. In particular this is
    the case when both the Torch padding and output_padding values are
    strictly positive.
    r   r   r   Nr   r   zbYou might experience inconsistencies across backends when calling conv transpose with kernel_size=z	, stride=z, dilation_rate=z
, padding=z, output_padding=.zThe padding arguments (padding=z) and output_padding=z") lead to a Torch output_padding (z ) that is greater than strides (zm). This is not supported. You can change the padding arguments, kernel or stride, or run on another backend. )r   r   warningswarn
ValueError)r
   r   r   r   r   original_kernel_sizetorch_paddingtorch_output_paddingr   r   r   8_convert_conv_transpose_padding_args_from_keras_to_torch0   sX   r   c                 C   s   t | d }|d d }g }t|D ];}	|d u st|tr|n||	 }
t|tr*|n||	 }t|tr5|n||	 }t||	 ||||
d\}}|||f q|S Nr   )r
   r   r   r   r   )lenrange
isinstanceintr   append)input_shapekernel_shapestridesr   r   r   num_spatial_dimskernel_spatial_shapejax_paddingioutput_padding_i	strides_idilation_rate_ipad_left	pad_rightr   r   r   +compute_conv_transpose_padding_args_for_jaxn   s2   r0   c                 C   s   t | d }|d d }g }g }	t|D ]>}
|d u st|tr!|n||
 }t|tr,|n||
 }t|tr7|n||
 }t||
 ||||d\}}|| |	| q||	fS r   )r   r    r!   r"   r   r#   )r$   r%   r&   r   r   r   r'   r(   torch_paddingstorch_output_paddingsr*   r+   r,   r-   r   r   r   r   r   -compute_conv_transpose_padding_args_for_torch   s6   
r3   c                 C   s   | d u rd S |  dv sJ |d | d }|  dkr3|d u r't||| n|}| d | | | S |d u r;| | S | d | |d  | S )Nr   r   r   r   )r   r   
input_sizer
   r&   r   r   r   r   r   r   "_get_output_shape_given_tf_padding   s   r6   channels_lastr   c              	   C   s   t | d }|}	t|tr|ft |	 }t|tr|f| }t|tr(|f| }|dkr3| dd }
n| dd  }
g }t|D ]#}|d u rGd n|| }t|
| |	| || |||| d}|| q?|dkrs| d g| |g }|S | d |g| }|S )Nr   r7   r   r4   r   )r   r!   r"   r    r6   r#   )r$   r
   filtersr&   r   r   data_formatr   r'   r(   input_spatial_shapeoutput_shaper*   current_output_paddingshape_ir   r   r   #compute_conv_transpose_output_shape   s:   





r?   c                 C   sL   t | } | |   kr|k sn td|  d| d| dk r$| | } | S )z?Canonicalize an axis in [-num_dims, num_dims) to [0, num_dims).zaxis z. is out of bounds for an array with dimension r   r   )operatorindexr   )axisnum_dimsr   r   r   canonicalize_axis  s   
rD   c                 C   s   t | tr	t| S | S )zDStandardize an axis to a tuple if it is a list in the numpy backend.)r!   listtuplerB   r   r   r   standardize_axis_for_numpy  s   rH   c                 C   s>   | du r| S t | tttfstd|  t | tr| fS | S )z9Convert the non-`None` value to either a tuple or a list.Nz;`value` must be an integer, tuple or list. Received: value=)r!   r"   rF   rE   r   )valuer   r   r   to_tuple_or_list  s   
rJ   z\w+z(?:{0:}(?:,{0:})*)?z\(z\)z{0:}(?:,{0:})*z^{0:}->{0:}$c                 C   s:   t t| std|  dd | dD \}}||fS )Nznot a valid gufunc signature: c                 s   s&    | ]}d d t t|D V  qdS )c                 S   s   g | ]
}t tt|qS r   )rF   refindall_DIMENSION_NAME).0argr   r   r   
<listcomp>7  s    z?_vectorize_parse_gufunc_signature.<locals>.<genexpr>.<listcomp>N)rK   rL   	_ARGUMENT)rN   arg_listr   r   r   	<genexpr>6  s    

z4_vectorize_parse_gufunc_signature.<locals>.<genexpr>z->)rK   match
_SIGNATUREr   split)	signatureargsretvalsr   r   r   !_vectorize_parse_gufunc_signature1  s   
rZ   Tc              	   C   s   t |}|rt ||k rtd| d| nt ||kr'td| d| |r0|| d  nd}t||D ]"\}}|| vrD|| |< q7|| | krYtd| d| d| |  q7d S )	Nzinput with shape z9 does not have enough dimensions for all core dimensions zoutput shape z  does not match core dimensions r   z%inconsistent size for core dimension z: z vs )r   r   zip)	dim_sizesshape	core_dimsis_inputnum_core_dims
core_shapedimsizer   r   r   _vectorize_update_dim_sizes@  s:   
rd   c           
      C   s   ddl m} t| t|krtdt| dt|  g }i }t| |D ]\}}t||j|dd |jt| }||jd |  q%|d }|D ]}	|	||	}qJ||fS )Nr   opsz/wrong number of positional arguments: expected , got Tr_   )
	keras.srcrf   r   	TypeErrorr[   rd   r]   ndimr#   broadcast_shapes)
rX   input_core_dimsrf   shapesr\   rO   r^   rk   broadcast_shapesr   r   r   !_vectorize_parse_input_dimensions[  s*   
rq   c                    s"   ddl m  fdd}|S )Nr   re   c                     s   |  }t |ttfrfdd|D }n|jg}d u r%dgt| }n*}t|dkr9t |ts9td| t|t|krOtdt| dt| t }t||D ]\}}t|||dd	 qX|S )
Nc                    s   g | ]}  |qS r   )r]   )rN   xre   r   r   rP   ~  s    zA_vectorize_check_output_dims.<locals>.wrapped.<locals>.<listcomp>r   r   z@output must be a tuple when multiple outputs are expected, got: z+wrong number of output arguments: expected rg   Frh   )	r!   rE   rF   r]   r   rj   dictr[   rd   )rX   out
out_shapesoutput_core_dimssizesr]   r^   r\   expected_output_core_dimsfuncrf   r   r   wrapped{  s2   z-_vectorize_check_output_dims.<locals>.wrapped)ri   rf   )rz   r\   ry   r{   r   rx   r   _vectorize_check_output_dimst  s   r|   c                    s   s |fS fddt  D }fdd| D } fddtdd D D fdd| D fd	d
}|||fS )Nc                       g | ]
\}}| vr|qS r   r   rN   r*   rO   excludedr   r   rP         z-_vectorize_apply_excluded.<locals>.<listcomp>c                    s   i | ]\}}| vr||qS r   r   rN   keyvalr   r   r   
<dictcomp>  s    z-_vectorize_apply_excluded.<locals>.<dictcomp>c                    s$   g | ]}|t  k r| | fqS r   )r   rN   r*   )rX   r   r   rP     s
    
c                 s   s    | ]
}t |tr|V  qd S N)r!   r"   )rN   er   r   r   rS     s    z,_vectorize_apply_excluded.<locals>.<genexpr>c                    s   i | ]\}}| v r||qS r   r   r   r   r   r   r     s    c                     s4   t | } D ]
\}}| || q | i |S r   )rE   insert)rX   kwargsr*   rO   )rz   static_argsstatic_kwargsr   r   new_func  s   z+_vectorize_apply_excluded.<locals>.new_func)	enumerateitemssorted)rz   r   rX   r   dynamic_argsdynamic_kwargsr   r   )rX   r   rz   r   r   r   _vectorize_apply_excluded  s   



r   )r   rW   c                   s4   ddl m t  t fdd}|S )z*Implementation adapted from JAX and NumPy.r   re   Nc                     s
  t | |\}} }d urt\}n	dgt|  d }dd t| D trUtfddD r@td d t || i \}} }fdd	tD ttj| } t	| \}}t
|||}g }g }	t| D ]?\}
}|
jd |
jt|  }t|t| }|d
 | }|	|d d d  tdd t|D }j|
|d}|| qs|}g  tt|	 D ]'\}}tdd |D }tdd |D r߈ t|d |  q||}q|| } s|S t|trt fdd|D S j| dS )Nr   c                 S   s   h | ]
\}}|d u r|qS r   r   r~   r   r   r   	<setcomp>  r   z2vectorize_impl.<locals>.wrapped.<locals>.<setcomp>c                 3   s    | ]	} | d kV  qdS )r   Nr   r   )rm   r   r   rS     s    z2vectorize_impl.<locals>.wrapped.<locals>.<genexpr>zCannot pass None at locations z with signature=c                    r}   r   r   )rN   r*   rb   )	none_argsr   r   rP     s
    z3vectorize_impl.<locals>.wrapped.<locals>.<listcomp>)r   r8   c                 s   s     | ]\}}|d kr|V  qdS )r   Nr   )rN   r*   rc   r   r   r   rS     s    rG   c                 s   s     | ]}|d kr
dndV  qdS )r   Nr   r   )rN   rc   r   r   r   rS     s    c                 s   s    | ]}|d u V  qd S r   r   )rN   rB   r   r   r   rS     s    r   c                 3   s    | ]
}j | d V  qdS )rG   N)expand_dims)rN   r)dims_to_expandrf   r   r   rS     s    
)r   rZ   r   r   anyr   rF   mapconvert_to_tensorrq   r|   r[   r]   rk   r#   squeezeallr!   r   )rX   r   excluded_funcrv   _ro   r\   checked_funcsqueezed_argsrev_filled_shapesrO   r^   noncore_shapepad_ndimfilled_shapesqueeze_indicessqueezed_argvectorized_funcnegdim
axis_sizesin_axesresultr   rf   pyfuncrW   vmap_fn)r   rm   r   r   r{     sp   



zvectorize_impl.<locals>.wrapped)ri   rf   set	functoolswraps)r   r   r   rW   r{   r   r   r   vectorize_impl  s
   Gr   c                 C   sT   |dkrt dg| t |||g }ntt |||gt dgd|   }| t| S )z$Slice a Tensor along the given axis.r   Nr8   )sliceEllipsisrF   )rr   startstopsteprB   slicesr   r   r   slice_along_axis  s   r   )Nr7   r   )T)r   Nr   r   )r   r@   rK   r   r   r   r0   r3   r6   r?   rD   rH   rJ   rM   format_CORE_DIMENSION_LISTrQ   _ARGUMENT_LISTrU   rZ   rd   rq   r|   r   r   r   r   r   r   r   <module>   s8    )>')
0



&R