o
    ?ed                     @   sx   d Z ddlmZ ddlmZ ddlm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dZdd ZdS )zDContains layer utilities for input validation and format conversion.    )
smart_cond)cond)	variablesc                 C   s   | dkr|dkr
dS |dkrdS |dkrdS t d| d	| d
kr<|dkr(dS |dkr.dS |dkr4dS t d| d	t d|  d)Nchannels_last   ZNWC   ZNHWC   ZNDHWCzInput rank: z5 not supported. We only support input rank 3, 4 or 5.channels_firstZNCWZNCHWZNCDHWzInvalid data_format: z5. We only support "channels_first" or "channels_last")
ValueError)data_formatndim r   _/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/tensorflow/python/layers/utils.pyconvert_data_format   s"   r   c                 C   s   t | tr
| f| S zt| }W n ty(   td| dt| dt|  w t||kr@td| dt| dt|  |D ].}zt| W qB ttfyp   td| dt| dt|  dt| dtt| 
w |S )a  Transforms a single integer or iterable of integers into an integer tuple.

  Args:
    value: The value to validate and convert. Could an int, or any iterable
      of ints.
    n: The size of the tuple to be returned.
    name: The name of the argument being validated, e.g. "strides" or
      "kernel_size". This is only used to format error messages.

  Returns:
    A tuple of n integers.

  Raises:
    ValueError: If something else than an int/long or iterable thereof was
      passed.
  z
Argument `z` must be a tuple of z integers. Received: z including element z	 of type )
isinstanceinttuple	TypeErrorr
   strlentype)valuennameZvalue_tupleZsingle_valuer   r   r   normalize_tuple0   s4   


r   c                 C   s(   |   }|dvrtdt|  d|S )N>   r   r	   zWThe `data_format` argument must be one of "channels_first", "channels_last". Received: .lowerr
   r   )r   r   r   r   r   normalize_data_formatW   s   
r   c                 C   s(   |   }|dvrtdt| d|S )N>   samevalidzAThe `padding` argument must be one of "valid", "same". Received: r   r   )r   paddingr   r   r   normalize_padding`   s   
r"      c                 C   st   | du rdS |dv sJ ||d |d   }|dkr| }n|dkr(| | d }n
|dkr2| | d }|| d | S )a  Determines output length of a convolution given input length.

  Args:
      input_length: integer.
      filter_size: integer.
      padding: one of "same", "valid", "full".
      stride: integer.
      dilation: dilation rate, integer.

  Returns:
      The output length (integer).
  N>   fullr   r    r#   r   r    r$   r   )input_lengthfilter_sizer!   strideZdilationZdilated_filter_sizeoutput_lengthr   r   r   conv_output_lengthh   s   r)   c                 C   s`   | du rdS |dv sJ |dkr|d }n|dkrd}n|dkr$|d }| d | d|  | S )	zDetermines input length of a convolution given output length.

  Args:
      output_length: integer.
      filter_size: integer.
      padding: one of "same", "valid", "full".
      stride: integer.

  Returns:
      The input length (integer).
  N>   r$   r   r    r      r    r   r$   r#   r   )r(   r&   r!   r'   padr   r   r   conv_input_length   s   
r,   c                 C   sN   | du rdS | |9 } |dkr| t || d7 } | S |dkr%| || d 8 } | S )a  Determines output length of a transposed convolution given input length.

  Args:
      input_length: integer.
      filter_size: integer.
      padding: one of "same", "valid", "full".
      stride: integer.

  Returns:
      The output length (integer).
  Nr    r   r$   r*   )max)r%   r&   r!   r'   r   r   r   deconv_output_length   s   r.   Nc                 C   s0   t | tjrtj| |||dS tj| |||dS )a  Return either `true_fn()` if predicate `pred` is true else `false_fn()`.

  If `pred` is a bool or has a constant value, we return either `true_fn()`
  or `false_fn()`, otherwise we use `tf.cond` to dynamically route to both.

  Args:
    pred: A scalar determining whether to return the result of `true_fn` or
      `false_fn`.
    true_fn: The callable to be performed if pred is true.
    false_fn: The callable to be performed if pred is false.
    name: Optional name prefix when using `tf.cond`.

  Returns:
    Tensors returned by the call to either `true_fn` or `false_fn`.

  Raises:
    TypeError: If `true_fn` or `false_fn` is not callable.
  )true_fnfalse_fnr   )r   r   Variabler   smart_moduler   )predr/   r0   r   r   r   r   r      s   r   c                 C   s>   t | tr| dkrd} n| dkrd} t | tjrdS t| S )a  Return the bool value for `pred`, or None if `pred` had a dynamic value.

    Args:
      pred: A scalar, either a Python bool or a TensorFlow boolean variable
        or tensor, or the Python integer 1 or 0.

    Returns:
      True or False if `pred` has a constant boolean value, None otherwise.

    Raises:
      TypeError: If `pred` is not a Variable, Tensor or bool, or Python
        integer 1 or 0.
    r#   Tr   FN)r   r   r   r1   r2   Zsmart_constant_value)r3   r   r   r   constant_value   s   

r4   )r#   )NNN)__doc__Ztensorflow.python.frameworkr   r2   Ztensorflow.python.opsr   r   r   r   r   r"   r)   r,   r.   r4   r   r   r   r   <module>   s   '	

