o
    biUD                     @   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   Z/home/ubuntu/.local/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   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   r/   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   
r2   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 )N>   r   r   r   r   r   )r   r   
input_sizer	   r%   r   r   r   r   r   r   "_get_output_shape_given_tf_padding   s   r5   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   r6   r   r3   r   )r   r    r!   r   r5   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   
rC   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rA   r   r   r   standardize_axis_for_numpy  s   rG   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!   rE   rD   r   )valuer   r   r   to_tuple_or_list  s   
rI   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   )rE   refindall_DIMENSION_NAME).0argr   r   r   
<listcomp>7  s    z?_vectorize_parse_gufunc_signature.<locals>.<genexpr>.<listcomp>N)rJ   rK   	_ARGUMENT)rM   arg_listr   r   r   	<genexpr>6  s    

z4_vectorize_parse_gufunc_signature.<locals>.<genexpr>z->)rJ   match
_SIGNATUREr   split)	signatureargsretvalsr   r   r   !_vectorize_parse_gufunc_signature1  s   
rY   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:   
rc   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.srcre   r   	TypeErrorrZ   rc   r\   ndimr"   broadcast_shapes)
rW   input_core_dimsre   shapesr[   rN   r]   rj   broadcast_shapesr   r   r   !_vectorize_parse_input_dimensions[  s*   
rp   c                    s"   ddl m  fdd}|S )Nr   rd   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\   )rM   xrd   r   r   rO   ~  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 rf   Frg   )	r    rD   rE   r\   r   ri   dictrZ   rc   )rW   out
out_shapesoutput_core_dimssizesr\   r]   r[   expected_output_core_dimsfuncre   r   r   wrapped{  s2   z-_vectorize_check_output_dims.<locals>.wrapped)rh   re   )ry   r[   rx   rz   r   rw   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   rM   r)   rN   excludedr   r   rO         z-_vectorize_apply_excluded.<locals>.<listcomp>c                    s   i | ]\}}| vr||qS r   r   rM   keyvalr~   r   r   
<dictcomp>  s    z-_vectorize_apply_excluded.<locals>.<dictcomp>c                    s$   g | ]}|t  k r| | fqS r   )r   rM   r)   )rW   r   r   rO     s
    
c                 s   s    | ]
}t |tr|V  qd S N)r    r!   )rM   er   r   r   rR     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   )rD   insert)rW   kwargsr)   rN   )ry   static_argsstatic_kwargsr   r   new_func  s   z+_vectorize_apply_excluded.<locals>.new_func)	enumerateitemssorted)ry   r   rW   r   dynamic_argsdynamic_kwargsr   r   )rW   r   ry   r   r   r   _vectorize_apply_excluded  s   



r   )r   rV   c                   s4   ddl m t  t fdd}|S )z*Implementation adapted from JAX and NumPy.r   rd   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   )rl   r   r   rR     s    z2vectorize_impl.<locals>.wrapped.<locals>.<genexpr>zCannot pass None at locations z with signature=c                    r|   r   r   )rM   r)   ra   )	none_argsr   r   rO     s
    z3vectorize_impl.<locals>.wrapped.<locals>.<listcomp>)r   r7   c                 s   s     | ]\}}|d kr|V  qdS )r   Nr   )rM   r)   rb   r   r   r   rR     s    rF   c                 s   s     | ]}|d kr
dndV  qdS )r   Nr   r   )rM   rb   r   r   r   rR     s    c                 s   s    | ]}|d u V  qd S r   r   )rM   rA   r   r   r   rR     s    r   c                 3   s    | ]
}j | d V  qdS )rF   N)expand_dims)rM   r)dims_to_expandre   r   r   rR     s    
)r   rY   r   r   anyr   rE   mapconvert_to_tensorrp   r{   rZ   r\   rj   r"   squeezeallr    r   )rW   r   excluded_funcru   _rn   r[   checked_funcsqueezed_argsrev_filled_shapesrN   r]   noncore_shapepad_ndimfilled_shapesqueeze_indicessqueezed_argvectorized_funcnegdim
axis_sizesin_axesresultr   re   pyfuncrV   vmap_fn)r   rl   r   r   rz     sp   



zvectorize_impl.<locals>.wrapped)rh   re   set	functoolswraps)r   r   r   rV   rz   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   Nr7   )sliceEllipsisrE   )rq   startstopsteprA   slicesr   r   r   slice_along_axis  s   r   )Nr6   r   )T)r   Nr   r   )r   r?   rJ   r   r   r   r/   r2   r5   r>   rC   rG   rI   rL   format_CORE_DIMENSION_LISTrP   _ARGUMENT_LISTrT   rY   rc   rp   r{   r   r   r   r   r   r   r   <module>   s8    )>')
0



&R