
    AVhM                    H   d 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 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 ddlmZ ddlmZ  eej8                  ej:                  ej<                  ej>                  ej@                  ejB                  ejD                  ejF                  ejH                  ejJ                  ejL                  ejN                  ejP                  ejR                  ejT                  ejV                  ejX                  ejZ                  ej\                  g      Z/g dZ0d Z1d Z2d Z3d Z4d Z5d Z6d Z7d Z8d Z9 edddg       ejt                   ejv                  d      d!                      Z< ed"g        ejt                  dd#              Z= ed"d$g       ejt                   ejv                  d$       e4d%d&      dd'                            Z> ed(g        ejt                  dd)              Z? ed(d*g       ejt                   ejv                  d*       e4d+d,      dd-                            Z@ ed.g        ejt                  dd/              ZA ed.d0g       ejt                   ejv                  d0       e4d1d2      dd3                            ZB ed4g        ejt                  dd5              ZC ed4d6g       ejt                   ejv                  d6       e4d7d8      dd9                            ZD ed:d;g        ej                  ejt                   e6d<d;d=      dd>                            ZF ed:d;g       ej                  ejt                   e5d<d?      dd@                            ZG edAg        ej                  ejt                   e6dBdCdD      ddE                            ZH edAdCg       ej                  ejt                   ejv                  dC       e5dBdF      	 ddG                                   ZI edHg        ej                  ejt                  	 	 ddI                     ZJ edHdJg       ej                  ejt                   ejv                  dJ      	 	 ddK                            ZK edLdMg        ej                  ejt                   e6dNdMd=      ddO                            ZL edLdMg       ej                  ejt                   e5dNdP      ddQ                            ZM edRg        ej                  ejt                   e6dSdTd=      ddU                            ZN edRdTg       ej                  ejt                   ejv                  dT       e5dSdV      ddW                                   ZO edXdYg        ej                  ejt                   e6dZdYd[      dd\                            ZP edXdYg       ej                  ejt                   e5dZd]      dd^                            ZQ ed_g        ej                  ejt                   e6d`dad[      ddb                            ZR ed_dag       ej                  ejt                   ejv                  da       e5d`dc      	 	 ddd                                   ZSde ZT edfdgg        ejt                  ddh              ZU edfdgg       ejt                  ddi              ZV edjg        ejt                  ddk              ZW edjdlg       ejt                   ejv                  dl      	 ddm                     ZXdn ZYdo ZZdp Z[ edqg        ejt                  ddr              Z\ edqdsg       ejt                   ejv                  ds      	 ddt                     Z] edug        ejt                  ddv              Z^ edudwg       ejt                   ejv                  dw      ddx                     Z_ edyg        ejt                  ddz              Z` edyd{g       ejt                   ejv                  d{      dd|                     Zad} Zbd~ Zcd Zdd Ze ej                  dg d      Zg edg        ejt                  	 	 dd              Zh edg       ejt                  dd              Zid Zj edddg        ejv                  d      d               Zk edg d       ejt                   ejv                  dd      dd                     Zl edg d       ejt                   ejv                  dd      dd                     ZmddZn edddg       ejt                   ejv                  d      dd                     Zo edg        ejt                  dd              Zp eddg       ejt                   ejv                  d      dd                     Zqd Zr ed      ejt                  dd              Zs e	j                  d      d        Zuy)zAsserts and Boolean Checks.    N)context)dtypes)errors)ops)sparse_tensortensor)tensor_shape)tensor_util)	array_ops)cond)control_flow_assert)control_flow_ops)math_ops)compat)deprecation)dispatch)	tf_export)assert_negativeassert_positiveassert_proper_iterableassert_non_negativeassert_non_positiveassert_equalassert_none_equalassert_nearassert_integerassert_lessassert_less_equalassert_greaterassert_greater_equalassert_rankassert_rank_at_leastassert_rank_inassert_same_float_dtypeassert_scalarassert_typeassert_shapesis_non_decreasingis_numeric_tensoris_strictly_increasingc                     t        | t        j                        st        |       S t	        j
                  |       }|t        |      S | S N)
isinstance
tensor_libTensorstrr   constant_value)tconst_ts     O/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/ops/check_ops.py_maybe_constant_value_stringr6   J   s@    	Az((	)q6M&&q)'w<	
(    c                     | s?|D cg c]  }t        |       }}t        j                  dddj                  |            yc c}w )zCRaises a InvalidArgumentError with as much information as possible.N
node_defopmessage)r6   r   InvalidArgumentErrorjoin)	conditiondataxdata_statics       r5   _assert_staticrD   S   sK    	<@Aq/2AKA

%
%t.2ii.DF F 
As   Ac                 N    d| j                   d| j                  j                  S )z5Returns a string containing tensor's shape and dtype.zshape=z dtype=)shapedtypenamer   s    r5   _shape_and_dtype_strrI   [   s     &fll.?.?	@@r7   c                       fd}|S )ab  Common docstring for assert_* ops that evaluate a unary predicate over every element of a tensor.

  Args:
    sym: Mathematical symbol for the check performed on each element, i.e. "> 0"
    sym_name: English-language name for the op described by sym

  Returns:
    Decorator that adds the appropriate docstring to the function for symbol
    `sym`.
  c                 r    | j                   }j                         }dj                  ||      | _        | S )zGenerated decorator that adds the appropriate docstring to the function for symbol `sym`.

    Args:
      func: Function for a TensorFlow op

    Returns:
      Version of `func` with documentation attached.
    a  
    Assert the condition `x {sym}` holds element-wise.

    When running in graph mode, you should add a dependency on this operation
    to ensure that it runs. Example of adding a dependency to an operation:

    ```python
    with tf.control_dependencies([tf.debugging.{opname}(x, y)]):
      output = tf.reduce_sum(x)
    ```

    {sym_name} means, for every element `x[i]` of `x`, we have `x[i] {sym}`.
    If `x` is empty this is trivially satisfied.

    Args:
      x:  Numeric `Tensor`.
      data:  The tensors to print out if the condition is False.  Defaults to
        error message and first few entries of `x`.
      summarize: Print this many entries of each tensor.
      message: A string to prefix to the default message.
      name: A name for this operation (optional).  Defaults to "{opname}".

    Returns:
      Op that raises `InvalidArgumentError` if `x {sym}` is False.
      @compatibility(eager)
        returns None
      @end_compatibility

    Raises:
      InvalidArgumentError: if the check can be performed immediately and
        `x {sym}` is False. The check can be performed immediately during
        eager execution or if `x` is statically known.
    )symsym_nameopname)__name__
capitalizeformat__doc__)funcrN   cap_sym_namerL   rM   s      r5   
_decoratorz%_unary_assert_doc.<locals>._decoratorl   sJ     ]]F&&(L @ 	,v 	 	7A 	LD Kr7    )rL   rM   rU   s   `` r5   _unary_assert_docrW   `   s    .` 
r7   c                       fd}|S )af  Common docstring for most of the v1 assert_* ops that compare two tensors element-wise.

  Args:
    sym: Binary operation symbol, i.e. "=="
    test_var: a string that represents the variable in the right-hand side of
      binary operator of the test case

  Returns:
    Decorator that adds the appropriate docstring to the function for
  symbol `sym`.
  c                 R    | j                   }dj                  |      | _        | S )zGenerated decorator that adds the appropriate docstring to the function for symbol `sym`.

    Args:
      func: Function for a TensorFlow op

    Returns:
      A version of `func` with documentation attached.
    a  
    Assert the condition `x {sym} y` holds element-wise.

    This condition holds if for every pair of (possibly broadcast) elements
    `x[i]`, `y[i]`, we have `x[i] {sym} y[i]`.
    If both `x` and `y` are empty, this is trivially satisfied.

    When running in graph mode, you should add a dependency on this operation
    to ensure that it runs. Example of adding a dependency to an operation:

    ```python
    with tf.control_dependencies([tf.compat.v1.{opname}(x, y)]):
      output = tf.reduce_sum(x)
    ```

    Args:
      x:  Numeric `Tensor`.
      y:  Numeric `Tensor`, same dtype as and broadcastable to `x`.
      data:  The tensors to print out if the condition is False.  Defaults to
        error message and first few entries of `x`, `y`.
      summarize: Print this many entries of each tensor.
      message: A string to prefix to the default message.
      name: A name for this operation (optional).  Defaults to "{opname}".

    Returns:
      Op that raises `InvalidArgumentError` if `x {sym} y` is False.

    Raises:
      InvalidArgumentError: if the check can be performed immediately and
        `x {sym} y` is False. The check can be performed immediately during
        eager execution or if `x` and `y` are statically known.

    @compatibility(TF2)
    `tf.compat.v1.{opname}` is compatible with eager execution and
    `tf.function`.
    Please use `tf.debugging.{opname}` instead when migrating to TF2. Apart
    from `data`, all arguments are supported with the same argument name.

    If you want to ensure the assert statements run before the
    potentially-invalid computation, please use `tf.control_dependencies`,
    as tf.function auto-control dependencies are insufficient for assert
    statements.

    #### Structural Mapping to Native TF2

    Before:

    ```python
    tf.compat.v1.{opname}(
      x=x, y=y, data=data, summarize=summarize,
      message=message, name=name)
    ```

    After:

    ```python
    tf.debugging.{opname}(
      x=x, y=y, message=message,
      summarize=summarize, name=name)
    ```

    #### TF1 & TF2 Usage Example

    TF1:

    >>> g = tf.Graph()
    >>> with g.as_default():
    ...   a = tf.compat.v1.placeholder(tf.float32, [2])
    ...   b = tf.compat.v1.placeholder(tf.float32, [2])
    ...   result = tf.compat.v1.{opname}(a, b,
    ...     message='"a {sym} b" does not hold for the given inputs')
    ...   with tf.compat.v1.control_dependencies([result]):
    ...     sum_node = a + b
    >>> sess = tf.compat.v1.Session(graph=g)
    >>> val = sess.run(sum_node, feed_dict={{a: [1, 2], b:{test_var}}})


    TF2:

    >>> a = tf.Variable([1, 2], dtype=tf.float32)
    >>> b = tf.Variable({test_var}, dtype=tf.float32)
    >>> assert_op = tf.debugging.{opname}(a, b, message=
    ...   '"a {sym} b" does not hold for the given inputs')
    >>> # When working with tf.control_dependencies
    >>> with tf.control_dependencies([assert_op]):
    ...   val = a + b

    @end_compatibility
    rL   rN   test_var)rO   rQ   rR   rS   rN   rL   r[   s     r5   rU   z&_binary_assert_doc.<locals>._decorator   s=     ]]FXp 	 	 	3q 	Lt Kr7   rV   )rL   r[   rU   s   `` r5   _binary_assert_docr]      s    eN 
r7   c                       fd}|S )aO  Common docstring for v2 assert_* ops that compare two tensors element-wise.

  Args:
    sym: Binary operation symbol, i.e. "=="
    opname: Name for the symbol, i.e. "assert_equal"
    test_var: A number used in the docstring example

  Returns:
    Decorator that adds the appropriate docstring to the function for
  symbol `sym`.
  c                 :    dj                        | _        | S )zDecorator that adds docstring to the function for symbol `sym`.

    Args:
      func: Function for a TensorFlow op

    Returns:
      A version of `func` with documentation attached.
    a  
    Assert the condition `x {sym} y` holds element-wise.

    This Op checks that `x[i] {sym} y[i]` holds for every pair of (possibly
    broadcast) elements of `x` and `y`. If both `x` and `y` are empty, this is
    trivially satisfied.

    If `x` {sym} `y` does not hold, `message`, as well as the first `summarize`
    entries of `x` and `y` are printed, and `InvalidArgumentError` is raised.

    When using inside `tf.function`, this API takes effects during execution.
    It's recommended to use this API with `tf.control_dependencies` to
    ensure the correct execution order.

    In the following example, without `tf.control_dependencies`, errors may
    not be raised at all.
    Check `tf.control_dependencies` for more details.

    >>> def check_size(x):
    ...   with tf.control_dependencies([
    ...       tf.debugging.{opname}(tf.size(x), {test_var},
    ...                       message='Bad tensor size')]):
    ...     return x

    >>> check_size(tf.ones([2, 3], tf.float32))
    Traceback (most recent call last):
       ...
    InvalidArgumentError: ...

    Args:
      x:  Numeric `Tensor`.
      y:  Numeric `Tensor`, same dtype as and broadcastable to `x`.
      message: A string to prefix to the default message. (optional)
      summarize: Print this many entries of each tensor. (optional)
      name: A name for this operation (optional).  Defaults to "{opname}".

    Returns:
      Op that raises `InvalidArgumentError` if `x {sym} y` is False. This can
        be used with `tf.control_dependencies` inside of `tf.function`s to
        block followup computation until the check has executed.
      @compatibility(eager)
      returns None
      @end_compatibility

    Raises:
      InvalidArgumentError: if the check can be performed immediately and
        `x == y` is False. The check can be performed immediately during eager
        execution or if `x` and `y` are statically known.
    rZ   )rQ   rR   r\   s    r5   rU   z)_binary_assert_doc_v2.<locals>._decorator#  s1    0` 	 	 	3a 	Ld Kr7   rV   )rL   rN   r[   rU   s   ``` r5   _binary_assert_doc_v2r`     s    <| 
r7   c                 r   g }|j                  d| z         |dkD  r|j                  |j                  k(  rF|j                  j                         r+t        j                  |      }t        j                  |      }|j                         }t        j                  ||      }	t        j                  ||      }
t        ||j                  d         }|j                  d|z         |j                  |d|        |j                  d       |j                  |	j                         j                  d      d|        |j                  d       |j                  |
j                         j                  d      d|        |j                         j                  d      }|j                         j                  d      }t        |j                  |      }t        |j                  |      }|j                  d|z         |j                  |d|        |j                  d	|z         |j                  |d|        |S )
a  Subroutine of _binary_assert that generates the components of the default error message when running in eager mode.

  Args:
    sym: Mathematical symbol for the test to apply to pairs of tensor elements,
      i.e. "=="
    x: First input to the assertion after applying `convert_to_tensor()`
    y: Second input to the assertion
    summarize: Value of the "summarize" parameter to the original assert_* call;
      tells how many elements of each tensor to print.
    test_op: TensorFlow op that returns a Boolean tensor with True in each
      position where the assertion is satisfied.

  Returns:
    List of tensors and scalars that, when stringified and concatenated,
    will produce the error message string.
  zCondition x %s y did not hold.r   z%Indices of first %d different values:NzCorresponding x values:zCorresponding y values:zFirst %d elements of x:zFirst %d elements of y:)appendrF   as_listr   logical_notr   wherenumpyboolean_maskminreshapesize)rL   rB   y	summarizetest_oprA   maskindices
indices_npx_valsy_valsnum_valsx_npy_npx_sumy_sums                   r5   _make_assert_msg_datarz   d  s   $ 
$++.45]ww!''aggoo/
 !!'*d%g==?j%%a.f%%a.fY
 0 0 34h
kk9HDE
kk*Yh'(
kk+,
kk&,,.((/	:;
kk+,
kk&,,.((/	:; 779U#D779U#D		9%E		9%EKK)E12KKVeKK)E12KKVe	+r7   c                 v   t        | t        j                        r| j                         }t	        j
                  |      rt        |      S |j                  d      }|d| D cg c]  }t        |       }}t        |      |j                  k  r|j                  d       t        |      S t        |       S c c}w )aT  Format a data item for use in an error message in eager mode.

  Args:
    data_item: One of the items in the "data" argument to an assert_* function.
      Can be a Tensor or a scalar value.
    summarize: How many elements to retain of each tensor-valued entry in data.

  Returns:
    An appropriate string representation of data_item
  rb   Nz...)r.   r/   r0   rh   npisscalarr1   rk   lenrl   rd   )	data_itemrn   arrflatrB   lsts         r5   _pretty_printr     s     	:,,-
//
C	{{3Xo[[d!*9-.SV.c.	SDII	

5Xoy> /s   #B6c
           	      z   t        j                  |	||||g      5  t        j                  |d      }t        j                  |d      }t        j                         r |||      }
t        j                  |
      }|r
	 ddd       ydndk  rd|t        | |||
      }||gt        |      z   }t        j                  dddj                  fd	|D              
      |$d| z  d|j                  z  |d|j                  z  |g}||gt        |      z   }t        j                   |||            }t        j                  |      }t        j                  |      }|*|(t        j                    |||            }t#        ||       t%        j&                  ||      cddd       S # 1 sw Y   yxY w)a  Generic binary elementwise assertion.

  Implements the behavior described in _binary_assert_doc() above.
  Args:
    sym: Mathematical symbol for the test to apply to pairs of tensor elements,
      i.e. "=="
    opname: Name of the assert op in the public API, i.e. "assert_equal"
    op_func: Function that, if passed the two Tensor inputs to the assertion (x
      and y), will return the test to be passed to reduce_all() i.e.
    static_func: Function that, if passed numpy ndarray versions of the two
      inputs to the assertion, will return a Boolean ndarray with containing
      True in all positions where the assertion PASSES.
      i.e. np.equal for assert_equal()
    x:  Numeric `Tensor`.
    y:  Numeric `Tensor`, same dtype as and broadcastable to `x`.
    data:  The tensors to print out if the condition is False.  Defaults to
      error message and first few entries of `x`, `y`.
    summarize: Print this many entries of each tensor.
    message: A string to prefix to the default message.
    name: A name for this operation (optional).  Defaults to the value of
      `opname`.

  Returns:
    See docstring template in _binary_assert_doc().
  rB   rH   rm   N   r   g    eAr9   c              3   6   K   | ]  }t        |        y wr-   )r   ).0drn   s     r5   	<genexpr>z!_binary_assert.<locals>.<genexpr>  s     GQ]1i8Gs   r:   z+Condition x %s y did not hold element-wise:	x (%s) = 	y (%s) = rn   )r   
name_scopeconvert_to_tensorr   executing_eagerlyr   
reduce_allrz   listr   r>   r?   rH   r   r2   r|   allrD   r   Assert)rL   rN   op_funcstatic_funcrB   rm   rA   rn   r=   rH   ro   r@   x_staticy_staticcondition_statics          `       r5   _binary_assertr     s   6 ~~dFQ4L1 -Nac*Aac*A  "1g%%g.i	-N -N 
		q=		$S!Q	7C		y4:%''99G$GGJ J 
9C?!&& !!&& !

 
	y4:%%%gam4i++A.h++A.h		("666+h"AB'. ''	49M[-N -N -Ns   A$F1	DF11F:z debugging.assert_proper_iterabler   )v1c                    t         j                  t        j                  t        j
                  ft        j                  z   }t        | |      rt        dt        |       z        t        | d      st        dt        |       z        y)a  Static assert that values is a "proper" iterable.

  `Ops` that expect iterables of `Tensor` can call this to validate input.
  Useful since `Tensor`, `ndarray`, byte/text type are all iterables themselves.

  Args:
    values:  Object to be checked.

  Raises:
    TypeError:  If `values` is not iterable or is one of
      `Tensor`, `SparseTensor`, `np.array`, `tf.compat.bytes_or_text_types`.
  z@Expected argument "values" to be a "proper" iterable.  Found: %s__iter__z5Expected argument "values" to be iterable.  Found: %sN)r/   r0   r   SparseTensorr|   ndarrayr   bytes_or_text_typesr.   	TypeErrortypehasattr)valuesunintentional_iterabless     r5   r   r     s    & -44bjjA""#  /0
JV	  
	$
?$v,NP P 
%r7   zdebugging.assert_negativec                      t        | |||      S )a  Assert the condition `x < 0` holds element-wise.

  This Op checks that `x[i] < 0` holds for every element of `x`. If `x` is
  empty, this is trivially satisfied.

  If `x` is not negative everywhere, `message`, as well as the first `summarize`
  entries of `x` are printed, and `InvalidArgumentError` is raised.

  Args:
    x:  Numeric `Tensor`.
    message: A string to prefix to the default message.
    summarize: Print this many entries of each tensor.
    name: A name for this operation (optional).  Defaults to "assert_negative".

  Returns:
    Op raising `InvalidArgumentError` unless `x` is all negative. This can be
      used with `tf.control_dependencies` inside of `tf.function`s to block
      followup computation until the check has executed.
    @compatibility(eager)
    returns None
    @end_compatibility

  Raises:
    InvalidArgumentError: if the check can be performed immediately and
      `x[i] < 0` is False. The check can be performed immediately during eager
      execution or if `x` is statically known.
  rB   r=   rn   rH   )r   r   s       r5   assert_negative_v2r     s    < 
1g	NNr7   r   z< 0negativec                 r   t        |      }t        j                  |d| |g      5  t        j                  | d      } |5t	        j
                         rt        |       }n| j                  }|dd|z  | g}t        j                  d| j                        }t        | |||      cd d d        S # 1 sw Y   y xY w)	Nr   rB   r   z*Condition x < 0 did not hold element-wise:r   r   rG   rA   rn   
_message_prefixr   r   r   r   r   rI   rH   rG   r   rB   rA   rn   r=   rH   zeros         r5   r   r   @  s    
 G$'
~~d-4y9 @ac*A|		"	"	$#A&vv

6

a!d   !''2Dq$TY?@ @ @   A>B--B6zdebugging.assert_positivec                      t        | |||      S )a  Assert the condition `x > 0` holds element-wise.

  This Op checks that `x[i] > 0` holds for every element of `x`. If `x` is
  empty, this is trivially satisfied.

  If `x` is not positive everywhere, `message`, as well as the first `summarize`
  entries of `x` are printed, and `InvalidArgumentError` is raised.

  Args:
    x:  Numeric `Tensor`.
    message: A string to prefix to the default message.
    summarize: Print this many entries of each tensor.
    name: A name for this operation (optional). Defaults to "assert_positive".

  Returns:
    Op raising `InvalidArgumentError` unless `x` is all positive. This can be
      used with `tf.control_dependencies` inside of `tf.function`s to block
      followup computation until the check has executed.
    @compatibility(eager)
    returns None
    @end_compatibility

  Raises:
    InvalidArgumentError: if the check can be performed immediately and
      `x[i] > 0` is False. The check can be performed immediately during eager
      execution or if `x` is statically known.
  rB   rn   r=   rH   )r   r   s       r5   assert_positive_v2r   U  s    < 
1	7	NNr7   r   z> 0positivec                 r   t        |      }t        j                  |d| |g      5  t        j                  | d      } |5t	        j
                         rt        |       }n| j                  }|dd|z  | g}t        j                  d| j                        }t        || ||      cd d d        S # 1 sw Y   y xY w)	Nr   rB   r   z*Condition x > 0 did not hold element-wise:r   r   r   r   r   r   s         r5   r   r   v  s    
 G$'
~~d-4y9 @ac*A|		"	"	$#A&vv
?

a!d   !''2DtQTY?@ @ @r   zdebugging.assert_non_negativec                      t        | |||      S )a  Assert the condition `x >= 0` holds element-wise.

  This Op checks that `x[i] >= 0` holds for every element of `x`. If `x` is
  empty, this is trivially satisfied.

  If `x` is not >= 0 everywhere, `message`, as well as the first `summarize`
  entries of `x` are printed, and `InvalidArgumentError` is raised.

  Args:
    x:  Numeric `Tensor`.
    message: A string to prefix to the default message.
    summarize: Print this many entries of each tensor.
    name: A name for this operation (optional).  Defaults to
      "assert_non_negative".

  Returns:
    Op raising `InvalidArgumentError` unless `x` is all non-negative. This can
      be used with `tf.control_dependencies` inside of `tf.function`s to block
      followup computation until the check has executed.
    @compatibility(eager)
    returns None
    @end_compatibility

  Raises:
    InvalidArgumentError: if the check can be performed immediately and
      `x[i] >= 0` is False. The check can be performed immediately during eager
      execution or if `x` is statically known.
  r   )r   r   s       r5   assert_non_negative_v2r         > 
qIw"&
( (r7   r   z>= 0znon-negativec                 r   t        |      }t        j                  |d| |g      5  t        j                  | d      } |5t	        j
                         rt        |       }n| j                  }|dd|z  | g}t        j                  d| j                        }t        || ||      cd d d        S # 1 sw Y   y xY w)	Nr   rB   r   z+Condition x >= 0 did not hold element-wise:r   r   r   r   
r   r   r   r   r   r   rI   rH   rG   r   r   s         r5   r   r     s    
 G$'
~~d1At9= Fac*A|		"	"	$#A&vv

7

a!d   !''2DT149EF F Fr   zdebugging.assert_non_positivec                      t        | |||      S )a  Assert the condition `x <= 0` holds element-wise.

  This Op checks that `x[i] <= 0` holds for every element of `x`. If `x` is
  empty, this is trivially satisfied.

  If `x` is not <= 0 everywhere, `message`, as well as the first `summarize`
  entries of `x` are printed, and `InvalidArgumentError` is raised.

  Args:
    x:  Numeric `Tensor`.
    message: A string to prefix to the default message.
    summarize: Print this many entries of each tensor.
    name: A name for this operation (optional).  Defaults to
      "assert_non_positive".

  Returns:
    Op raising `InvalidArgumentError` unless `x` is all non-positive. This can
      be used with `tf.control_dependencies` inside of `tf.function`s to block
      followup computation until the check has executed.
    @compatibility(eager)
    returns None
    @end_compatibility

  Raises:
    InvalidArgumentError: if the check can be performed immediately and
      `x[i] <= 0` is False. The check can be performed immediately during eager
      execution or if `x` is statically known.
  r   )r   r   s       r5   assert_non_positive_v2r     r   r7   r   z<= 0znon-positivec                 p   t        |      }t        j                  |d| |g      5  t        j                  | d      } |4t	        j
                         rt        |       }n| j                  }|d|z  | g}t        j                  d| j                        }t        | |||      cd d d        S # 1 sw Y   y xY w)Nr   rB   r   z4Condition x <= 0 did not hold element-wise:x (%s) = r   r   r   r   r   s         r5   r   r     s    
 G$'
~~d1At9= Fac*A|		"	"	$#A&vv
!d   !''2DQ49EF F Fs   A=B,,B5zdebugging.assert_equalr   ==r   c                 "    t        | ||||      S NrB   rm   rn   r=   rH   )r   rB   rm   r=   rn   rH   s        r5   assert_equal_v2r     s    
 
Q)W4	PPr7   z[1, 2]c                 0   t        j                  |d| ||g      5  | |u r3t        j                         rd nt	        j
                         cd d d        S 	 d d d        t        ddt        j                  t        j                  | |||||
      S # 1 sw Y   9xY w)Nr   r   )
r   r   r   r   r   no_opr   r   equalr|   rB   rm   rA   rn   r=   rH   s         r5   r   r     s    
 ~~dNQ4L9 OAv..0T6F6L6L6NO OO 
nhnnbhh1i$
8 8	O Os   .BBzdebugging.assert_none_equal!=r      c                 "    t        | ||||      S r   )r   r   s        r5   assert_none_equal_v2r     s    
 
Q!y' $
& &r7   z[2, 1]c                 b    t        ddt        j                  t        j                  | |||||
      S )Nr   r   )r   r   	not_equalr|   r   s         r5   r   r     s3     
183E3EaD)Wd
L Lr7   zdebugging.assert_nearc           	      &    t        | ||||||      S )a  Assert the condition `x` and `y` are close element-wise.

  This Op checks that `x[i] - y[i] < atol + rtol * tf.abs(y[i])` holds for every
  pair of (possibly broadcast) elements of `x` and `y`. If both `x` and `y` are
  empty, this is trivially satisfied.

  If any elements of `x` and `y` are not close, `message`, as well as the first
  `summarize` entries of `x` and `y` are printed, and `InvalidArgumentError`
  is raised.

  The default `atol` and `rtol` is `10 * eps`, where `eps` is the smallest
  representable positive number such that `1 + eps != 1`.  This is about
  `1.2e-6` in `32bit`, `2.22e-15` in `64bit`, and `0.00977` in `16bit`.
  See `numpy.finfo`.

  Args:
    x: Float or complex `Tensor`.
    y: Float or complex `Tensor`, same dtype as and broadcastable to `x`.
    rtol:  `Tensor`.  Same `dtype` as, and broadcastable to, `x`.
      The relative tolerance.  Default is `10 * eps`.
    atol:  `Tensor`.  Same `dtype` as, and broadcastable to, `x`.
      The absolute tolerance.  Default is `10 * eps`.
    message: A string to prefix to the default message.
    summarize: Print this many entries of each tensor.
    name: A name for this operation (optional).  Defaults to "assert_near".

  Returns:
    Op that raises `InvalidArgumentError` if `x` and `y` are not close enough.
      This can be used with `tf.control_dependencies` inside of `tf.function`s
      to block followup computation until the check has executed.
    @compatibility(eager)
    returns None
    @end_compatibility

  Raises:
    InvalidArgumentError: if the check can be performed immediately and
      `x != y` is False for any pair of elements in `x` and `y`. The check can
      be performed immediately during eager execution or if `x` and `y` are
      statically known.

  @compatibility(numpy)
  Similar to `numpy.testing.assert_allclose`, except tolerance depends on data
  type. This is due to the fact that `TensorFlow` is often used with `32bit`,
  `64bit`, and even `16bit` data.
  @end_compatibility
  )rB   rm   rtolatolrn   r=   rH   )r   )rB   rm   r   r   r=   rn   rH   s          r5   assert_near_v2r   #  s!    f 
qADty$4
1 1r7   r   c           	         t        |      }t        j                  |d| ||||g      5  t        j                  | d      } t        j                  |d| j                        }| j                  }|j
                  r|j                  }t        j                  |j                        j                  }	|d|	z  n|}|d|	z  n|}t        j                  |d|      }t        j                  |d	|      }t        j                         rt        |       }
t        |      }n| j                  }
|j                  }||d
|d|d|
z  | d|z  |g}||t        j                   |      z  z   }t        j                   | |z
        }t        j"                  t        j$                  ||            }t'        j(                  |||      cddd       S # 1 sw Y   yxY w)a  Assert the condition `x` and `y` are close element-wise.

  Example of adding a dependency to an operation:

  ```python
  with tf.control_dependencies([tf.compat.v1.assert_near(x, y)]):
    output = tf.reduce_sum(x)
  ```

  This condition holds if for every pair of (possibly broadcast) elements
  `x[i]`, `y[i]`, we have

  ```tf.abs(x[i] - y[i]) <= atol + rtol * tf.abs(y[i])```.

  If both `x` and `y` are empty, this is trivially satisfied.

  The default `atol` and `rtol` is `10 * eps`, where `eps` is the smallest
  representable positive number such that `1 + eps != 1`.  This is about
  `1.2e-6` in `32bit`, `2.22e-15` in `64bit`, and `0.00977` in `16bit`.
  See `numpy.finfo`.

  Args:
    x:  Float or complex `Tensor`.
    y:  Float or complex `Tensor`, same `dtype` as, and broadcastable to, `x`.
    rtol:  `Tensor`.  Same `dtype` as, and broadcastable to, `x`.
      The relative tolerance.  Default is `10 * eps`.
    atol:  `Tensor`.  Same `dtype` as, and broadcastable to, `x`.
      The absolute tolerance.  Default is `10 * eps`.
    data:  The tensors to print out if the condition is False.  Defaults to
      error message and first few entries of `x`, `y`.
    summarize: Print this many entries of each tensor.
    message: A string to prefix to the default message.
    name: A name for this operation (optional).  Defaults to "assert_near".

  Returns:
    Op that raises `InvalidArgumentError` if `x` and `y` are not close enough.

  @compatibility(numpy)
  Similar to `numpy.testing.assert_allclose`, except tolerance depends on data
  type. This is due to the fact that `TensorFlow` is often used with `32bit`,
  `64bit`, and even `16bit` data.
  @end_compatibility
  r   rB   r   rm   )rH   rG   N
   r   r   z&x and y not equal to tolerance rtol = z	, atol = r   r   r   )r   r   r   r   rG   
is_complex
real_dtyper|   finfoas_numpy_dtypeepsr   r   rI   rH   r   absr   lessr   r   )rB   rm   r   r   rA   rn   r=   rH   rG   r   x_namey_nametoldiffr@   s                  r5   r   r   Z  s   d G$'
~~dMAq$d+CD Lac*Aac9AGGEe
((5''
(
,
,C|28D|28D  F%@D  F%@D  "#A&f#A&fvvfvvf|
CG
N

;#7d
 Q'
'C<<AD##HMM$$<=I%%iK=L L Ls   FGGzdebugging.assert_lessr   <c                 "    t        | ||||      S r   )r   r   s        r5   assert_less_v2r     s    
 
qAG$	OOr7   z[2, 3]c                 b    t        ddt        j                  t        j                  | |||||
      S )Nr   r   )r   r   r   r|   r   s         r5   r   r     s.    
 
]HMM277Aq$!7D
2 2r7   zdebugging.assert_less_equal<=r   c                 "    t        | ||||      S r   )r   r   s        r5   assert_less_equal_v2r     s    
 
Q!%.d
L Lr7   z[1, 3]c                 b    t        ddt        j                  t        j                  | |||||
      S )Nr   r   )r   r   
less_equalr|   r   s         r5   r   r     s3     
183F3Fq!T9gt
M Mr7   zdebugging.assert_greaterr    >	   c                 "    t        | ||||      S r   )r    r   s        r5   assert_greater_v2r     s    
 
!qIw!
# #r7   z[0, 1]c                 b    t        ddt        j                  t        j                  | |||||
      S )Nr   r    )r   r   greaterr|   r   s         r5   r    r      s1    
 
-x/?/?Q4GT
; ;r7   zdebugging.assert_greater_equal>=r!   c                 "    t        | ||||      S r   )r!   r   s        r5   assert_greater_equal_v2r     s    
 
Q)W#'
) )r7   z[1, 0]c                 b    t        ddt        j                  t        j                  | |||||
      S )Nr   r!   )r   r   greater_equalr|   r   s         r5   r!   r!     s5     
4h6L6L((!Qi$
P Pr7   c                    t        |t        j                         t        j                  |      }|b|j
                  dk7  rt        d      | j                         j                  }|, |||      st        d||      t        j                  d      S  |t        j                  |       |      }|)d|g}	t        |d|	      }
t        j                  |
g|      }t        j                   |||      S )	a  Assert `x` has a rank that satisfies a given condition.

  Args:
    x:  Numeric `Tensor`.
    rank:  Scalar `Tensor`.
    static_condition:   A python function that takes `[actual_rank, given_rank]`
      and returns `True` if the condition is satisfied, `False` otherwise.
    dynamic_condition:  An `op` that takes [actual_rank, given_rank] and return
      `True` if the condition is satisfied, `False` otherwise.
    data:  The tensors to print out if the condition is false.  Defaults to
      error message and first few entries of `x`.
    summarize: Print this many entries of each tensor.

  Returns:
    Op raising `InvalidArgumentError` if `x` fails dynamic_condition.

  Raises:
    ValueError:  If static checks determine `x` fails static_condition.
  r   Rank must be a scalar.Static rank condition failedstatic_checks_determined_all_okr   &Rank must be a scalar. Received rank: rA   r   )r'   r   int32r   r2   ndim
ValueError	get_shapendimsr   r   r   rankr"   with_dependenciesr   r   )rB   r   static_conditiondynamic_conditionrA   rn   rank_staticx_rank_staticr@   	this_data
rank_checks              r5   _assert_rank_conditionr    s    * dFLL! **40+1/00KKM''M m[9*M;H 	H##)JKK	q 148) 94@IT195J 22J<KI		#	#Ity	IIr7   zdebugging.assert_rankr"   c                      t        | |||      S )a  Assert that `x` has rank equal to `rank`.

  This Op checks that the rank of `x` is equal to `rank`.

  If `x` has a different rank, `message`, as well as the shape of `x` are
  printed, and `InvalidArgumentError` is raised.

  Args:
    x: `Tensor`.
    rank: Scalar integer `Tensor`.
    message: A string to prefix to the default message.
    name: A name for this operation (optional). Defaults to
      "assert_rank".

  Returns:
    Op raising `InvalidArgumentError` unless `x` has specified rank.
    If static checks determine `x` has correct rank, a `no_op` is returned.
    This can be used with `tf.control_dependencies` inside of `tf.function`s
    to block followup computation until the check has executed.
    @compatibility(eager)
    returns None
    @end_compatibility

  Raises:
    InvalidArgumentError: if the check can be performed immediately and
      `x` does not have rank `rank`. The check can be performed immediately
      during eager execution or if the shape of `x` is statically known.
  rB   r   r=   rH   )r"   r	  s       r5   assert_rank_v2r
  (  s    > 
qtW4	@@r7   c                    t        j                  |d| |ft        |xs g       z         5  t        | t        j
                        st        j                  | d      } t        j                  |d      }t        |      }d }t        j                  }t        j                         st        | t        j
                        rd}n| j                  }||d|z  |d	t        j                  |       g}	 t        | |||||      }	 ddd       |S # t         $ rj}	|	j"                  d
   dk(  r;t!        d|||	j"                  d   |	j"                  d   | j%                         fz        t!        |	j"                  d
         d}	~	ww xY w# 1 sw Y   S xY w)a-  Assert `x` has rank equal to `rank`.

  Example of adding a dependency to an operation:

  ```python
  with tf.control_dependencies([tf.compat.v1.assert_rank(x, 2)]):
    output = tf.reduce_sum(x)
  ```

  Args:
    x:  Numeric `Tensor`.
    rank:  Scalar integer `Tensor`.
    data:  The tensors to print out if the condition is False.  Defaults to
      error message and the shape of `x`.
    summarize: Print this many entries of each tensor.
    message: A string to prefix to the default message.
    name: A name for this operation (optional).  Defaults to "assert_rank".

  Returns:
    Op raising `InvalidArgumentError` unless `x` has specified rank.
    If static checks determine `x` has correct rank, a `no_op` is returned.

  Raises:
    ValueError:  If static checks determine `x` has wrong rank.
  r"   rB   r   r   c                     | |k(  S r-   rV   actual_rank
given_ranks     r5   <lambda>zassert_rank.<locals>.<lambda>l      {j7P r7    NzTensor %s must have rankReceived shape: r   r   z:%sTensor %s must have rank %d.  Received rank %d, shape %s      )r   r   tupler.   r   r   r   r   r   r   r   r   rH   r   rF   r  r   argsr   
rB   r   rA   rn   r=   rH   r  r  	assert_opes
             r5   r"   r"   J  sy   8 ~~dMAt9uTZR7H+HI $a334



,a  F3Dg&GP   "jM4N4N&OdVVd|

$t
+T3E
//!
d
$(D2B):D)Mi-$B 
  $	
4	4HdAFF1Iqvvay!++-@AB 	B ##$3$B 
s+   CE?.D			E<A%E77E<<E??F	zdebugging.assert_rank_at_leastc                      t        | |||      S )a  Assert that `x` has rank of at least `rank`.

  This Op checks that the rank of `x` is greater or equal to `rank`.

  If `x` has a rank lower than `rank`, `message`, as well as the shape of `x`
  are printed, and `InvalidArgumentError` is raised.

  Args:
    x: `Tensor`.
    rank: Scalar integer `Tensor`.
    message: A string to prefix to the default message.
    name: A name for this operation (optional).  Defaults to
      "assert_rank_at_least".

  Returns:
    Op raising `InvalidArgumentError` unless `x` has specified rank or higher.
    If static checks determine `x` has correct rank, a `no_op` is returned.
    This can be used with `tf.control_dependencies` inside of `tf.function`s
    to block followup computation until the check has executed.
    @compatibility(eager)
    returns None
    @end_compatibility

  Raises:
    InvalidArgumentError: `x` does not have rank at least `rank`, but the rank
      cannot be statically determined.
    ValueError: If static checks determine `x` has mismatched rank.
  r	  )r#   r	  s       r5   assert_rank_at_least_v2r    s    > 
gD	IIr7   r#   c                    t        j                  |d| |ft        |xs g       z         5  t        j                  | d      } t        j                  |d      }t	        |      }d }t
        j                  }t        j                         rd}n| j                  }||d|z  |d	t        j                  |       g}	 t        | |||||      }	 ddd       |S # t        $ rS}	|	j                  d
   dk(  r;t        d|||	j                  d   |	j                  d   | j                         fz         d}	~	ww xY w# 1 sw Y   S xY w)aX  Assert `x` has rank equal to `rank` or higher.

  Example of adding a dependency to an operation:

  ```python
  with tf.control_dependencies([tf.compat.v1.assert_rank_at_least(x, 2)]):
    output = tf.reduce_sum(x)
  ```

  Args:
    x:  Numeric `Tensor`.
    rank:  Scalar `Tensor`.
    data:  The tensors to print out if the condition is False.  Defaults to
      error message and first few entries of `x`.
    summarize: Print this many entries of each tensor.
    message: A string to prefix to the default message.
    name: A name for this operation (optional).
      Defaults to "assert_rank_at_least".

  Returns:
    Op raising `InvalidArgumentError` unless `x` has specified rank or higher.
    If static checks determine `x` has correct rank, a `no_op` is returned.

  Raises:
    ValueError:  If static checks determine `x` has wrong rank.
  r#   rB   r   r   c                     | |k\  S r-   rV   r  s     r5   r  z&assert_rank_at_least.<locals>.<lambda>  r  r7   r  Nz!Tensor %s must have rank at leastr  r   r   zC%sTensor %s must have rank at least %d.  Received rank %d, shape %sr  r  )r   r   r  r   r   r   r   r   r   rH   r   rF   r  r   r  r   r  s
             r5   r#   r#     sR   > ~~
"QIdjb0A$AC ac*A  F3Dg&GP ..  "dVVd|

-
4d
iooa0d
(D2B):D)Mi-B 
  	
4	4!4AFF1Iq{{}MNO 	O 	3B 
s+   BD4:C	D1AD,,D11D44D>c                 
    | |v S r-   rV   )r  given_rankss     r5   _static_rank_inr!    s    		##r7   c                     t        |      dk  rt        j                  d      S t        j                  |d   |       }|dd  D ],  }t        j
                  |t        j                  ||             }. |S )Nr  Fr   )r~   r   r   r   r   
logical_or)r  r   resultr  s       r5   _dynamic_rank_inr%    sp      ''>>+a.+6&O 9j  z;79F9 
-r7   c                    |D ]  }t        |t        j                          t        |D cg c]  }t	        j
                  |       c}      }t        d |D              si|D ]  }|j                  dk7  st        d       | j                         j                  }	|	, ||	|      st        d|	|      t        j                  d      S  |t        j                  |       |      }
t        ||      D ]1  \  }}|	d|g}t!        |d|      }t        j"                  |g|
      }
3 t%        j&                  |
||	      S c c}w )
a  Assert `x` has a rank that satisfies a given condition.

  Args:
    x:  Numeric `Tensor`.
    ranks:  Scalar `Tensor`.
    static_condition:   A python function that takes
      `[actual_rank, given_ranks]` and returns `True` if the condition is
      satisfied, `False` otherwise.
    dynamic_condition:  An `op` that takes [actual_rank, given_ranks]
      and return `True` if the condition is satisfied, `False` otherwise.
    data:  The tensors to print out if the condition is false.  Defaults to
      error message and first few entries of `x`.
    summarize: Print this many entries of each tensor.

  Returns:
    Op raising `InvalidArgumentError` if `x` fails dynamic_condition.

  Raises:
    ValueError:  If static checks determine `x` fails static_condition.
  c              3   $   K   | ]  }|d u  
 y wr-   rV   r   rs     r5   r   z*_assert_ranks_condition.<locals>.<genexpr>  s     -1Q$Y-s   r   r   r   r   r   r   r   r   )r'   r   r   r  r   r2   anyr   r   r   r   r   r   r   r   zipr"   r   r   r   )rB   ranksr  r  rA   rn   r   ranks_staticr  r  r@   r  r  s                r5   _assert_ranks_conditionr.    sH   ,  $dfll#$ UKT2248KL,	--	-# 3			Q	1223 KKM''M m\:*M<I 	I##)JKK	q 159) ul3 NdK;TBitQY7j"44j\9Mi	N 
	#	#Ity	II/ Ls   D=zdebugging.assert_rank_inc                      t        | |||      S )a  Assert that `x` has a rank in `ranks`.

  This Op checks that the rank of `x` is in `ranks`.

  If `x` has a different rank, `message`, as well as the shape of `x` are
  printed, and `InvalidArgumentError` is raised.

  Args:
    x: `Tensor`.
    ranks: `Iterable` of scalar `Tensor` objects.
    message: A string to prefix to the default message.
    name: A name for this operation (optional). Defaults to "assert_rank_in".

  Returns:
    Op raising `InvalidArgumentError` unless rank of `x` is in `ranks`.
    If static checks determine `x` has matching rank, a `no_op` is returned.
    This can be used with `tf.control_dependencies` inside of `tf.function`s
    to block followup computation until the check has executed.
    @compatibility(eager)
    returns None
    @end_compatibility

  Raises:
    InvalidArgumentError: `x` does not have rank in `ranks`, but the rank cannot
      be statically determined.
    ValueError: If static checks determine `x` has mismatched rank.
  rB   r,  r=   rH   )r$   r0  s       r5   assert_rank_in_v2r1  1  s    < 
!5'	EEr7   r$   c                 ^   t        j                  |d| ft        |      z   t        |xs g       z         5  t        | t        j
                        st        j                  | d      } t        |D cg c]  }t        j                  |d       c}      }t        |      }t        j                         st        | t        j
                        rd}n| j                  }|+|d|z  gt        |      z   dt        j                  |       gz   }	 t        | |t        t         ||      }	 ddd       |S c c}w # t"        $ rc}|j$                  d	   d
k(  rKt#        d||t        d |j$                  d   D              |j$                  d   | j'                         fz         d}~ww xY w# 1 sw Y   S xY w)aV  Assert `x` has rank in `ranks`.

  Example of adding a dependency to an operation:

  ```python
  with tf.control_dependencies([tf.compat.v1.assert_rank_in(x, (2, 4))]):
    output = tf.reduce_sum(x)
  ```

  Args:
    x:  Numeric `Tensor`.
    ranks:  Iterable of scalar `Tensor` objects.
    data:  The tensors to print out if the condition is False.  Defaults to
      error message and first few entries of `x`.
    summarize: Print this many entries of each tensor.
    message: A string to prefix to the default message.
    name: A name for this operation (optional).
      Defaults to "assert_rank_in".

  Returns:
    Op raising `InvalidArgumentError` unless rank of `x` is in `ranks`.
    If static checks determine `x` has matching rank, a `no_op` is returned.

  Raises:
    ValueError:  If static checks determine `x` has mismatched rank.
  r$   rB   r   r   r  NzTensor %s must have rank inr  r   r   z=%sTensor %s must have rank in %s.  Received rank %d, shape %sc              3   <   K   | ]  }|j                           y wr-   )itemr(  s     r5   r   z!assert_rank_in.<locals>.<genexpr>  s     21affh2s   r  r  )r   r   r  r.   r   r   r   r   r   r   rH   r   r   rF   r.  r!  r%  r   r  r   )	rB   r,  rA   rn   r=   rH   r   r  r  s	            r5   r$   r$   R  s   > ~~
qdU5\1E$*"4EEG $a334



,aN3((F;NOEg&G  "jM4N4N&OdVVd|
047
u+ iooa0d)!UO*:D)Mi)$L 
E O&  	
4	4K2q	22q		
 		
 	/$L 
s=   ;F"0D.
A<F"D3.F"3	F<AFFF""F,zdebugging.assert_integerc                      t        | ||       y)a  Assert that `x` is of integer dtype.

  If `x` has a non-integer type, `message`, as well as the dtype of `x` are
  printed, and `InvalidArgumentError` is raised.

  This can always be checked statically, so this method returns nothing.

  Args:
    x: A `Tensor`.
    message: A string to prefix to the default message.
    name: A name for this operation (optional). Defaults to "assert_integer".

  Raises:
    TypeError:  If `x.dtype` is not a non-quantized integer type.
  rB   r=   rH   N)r   r6  s      r5   assert_integer_v2r7    s    $ 1gD1r7   r   c                 x   t        j                  |d| g      5  t        j                  | d      } | j                  j                  sKt        j                         rd}n| j                  }t        |      d|d| j                  }t        |      t        j                  d      cddd       S # 1 sw Y   yxY w)	aD  Assert that `x` is of integer dtype.

  Example of adding a dependency to an operation:

  ```python
  with tf.control_dependencies([tf.compat.v1.assert_integer(x)]):
    output = tf.reduce_sum(x)
  ```

  Args:
    x: `Tensor` whose basetype is integer and is not quantized.
    message: A string to prefix to the default message.
    name: A name for this operation (optional).  Defaults to "assert_integer".

  Raises:
    TypeError:  If `x.dtype` is anything other than non-quantized integer.

  Returns:
    A `no_op` that does nothing.  Type can be determined statically.
  r   rB   r   r	   z)Expected "x" to be integer type.  Found: z
 of dtype !statically_determined_was_integerN)r   r   r   rG   
is_integerr   r   rH   r   r   r   r   )rB   r=   rH   err_msgs       r5   r   r     s    0 ~~d,qc2 Gac*A77		"	"	$vv W%tQWW6  g!!"EFG G Gs   BB00B9zdebugging.assert_typec                 "    t        | |||       y)ad  Asserts that the given `Tensor` is of the specified type.

  This can always be checked statically, so this method returns nothing.

  Example:

  >>> a = tf.Variable(1.0)
  >>> tf.debugging.assert_type(a, tf_type= tf.float32)

  >>> b = tf.constant(21)
  >>> tf.debugging.assert_type(b, tf_type=tf.bool)
  Traceback (most recent call last):
  ...
  TypeError: ...

  >>> c = tf.SparseTensor(indices=[[0, 0], [1, 2]], values=[1, 2],
  ...  dense_shape=[3, 4])
  >>> tf.debugging.assert_type(c, tf_type= tf.int32)

  Args:
    tensor: A `Tensor`, `SparseTensor` or `tf.Variable` .
    tf_type: A tensorflow type (`dtypes.float32`, `tf.int64`, `dtypes.bool`,
      etc).
    message: A string to prefix to the default message.
    name:  A name for this operation. Defaults to "assert_type"

  Raises:
    TypeError: If the tensor's data type doesn't match `tf_type`.
  r	   tf_typer=   rH   N)r'   r=  s       r5   assert_type_v2r?    s    @ VWgDIr7   r'   c           	         t        j                  |      }t        j                  |d| g      5  t	        | t
        j                        st        j                  | d      } | j                  |k7  r3t        t        |       t        | dd       d|d| j                        t        j                  d      cddd       S # 1 sw Y   yxY w)	a  Statically asserts that the given `Tensor` is of the specified type.

  Args:
    tensor: A `Tensor` or `SparseTensor`.
    tf_type: A tensorflow type (`dtypes.float32`, `tf.int64`, `dtypes.bool`,
      etc).
    message: A string to prefix to the default message.
    name:  A name to give this `Op`.  Defaults to "assert_type"

  Raises:
    TypeError: If the tensors data type doesn't match `tf_type`.

  Returns:
    A `no_op` that does nothing.  Type can be determined statically.
  r'   r	   r   rH   z must be of type z; got "statically_determined_correct_typeN)r   as_dtyper   r   r.   r   r   r   rG   r   r   getattrr   r   r=  s       r5   r'   r'     s    & OOG$'
~~dMF84 Hfm889$$V(;f||wW%&wvvx'H&Ig[v||.>@A A !!"FGH H Hs   BC  C	c                    t        j                  |       | j                         j                  }|du}|r|dk(  ry|rR|dkD  rM| j                         j	                         }t        |      D cg c]  \  }}|t        |      n|    }}}|S t        j                  t        j                  |       d      }t        j                  |d fd      S c c}}w )a   Gets the dimension sizes of a tensor `x`.

  If a size can be determined statically it is returned as an integer,
  otherwise as a tensor.

  If `x` is a scalar it is treated as rank 1 size 1.

  Args:
    x: A `Tensor`.

  Returns:
    Dimension sizes.
  Nr   )r  c                  .    t        j                  dg      S Nr  )r   constantrV   r7   r5   r  z"_dimension_sizes.<locals>.<lambda>4  s    Y//4 r7   c                       S r-   rV   )dynamic_shapes   r5   r  z"_dimension_sizes.<locals>.<lambda>4  s    m r7   )
r   rF   r   r   re   	enumerateintr   r   r   )	rB   r   rank_is_knownstatic_shapeirl   sizeshas_rank_zerorI  s	           @r5   _dimension_sizesrQ    s     //!$-	
		$d"-tqytax;;=((*L !.At %D	=+;;E  L..!2A6-	46K
M Ms   0Cc                 "    | st        dg      S | S rF  )r  )symbolic_shapes    r5   _symbolic_dimension_sizesrT  7  s    	!:	r7   c                 `    | d u}	 t        |        d}|xr |S # t        t        f$ r d}Y w xY w)NTF)rK  r   r   )dimension_sizenot_nonecan_be_parsed_as_ints      r5   _has_known_valuerY  ?  sI    4'(! 
	*** i	  ! !s    --c                 
    | dv S )N)N.rV   )symbols    r5   _is_symbol_for_any_sizer]  I  s    	;	r7   _TensorDimSizes)rB   unspecified_dimactual_sizessymbolic_sizeszdebugging.assert_shapesc                 $    t        | ||||       y)a  Assert tensor shapes and dimension size relationships between tensors.

  This Op checks that a collection of tensors shape relationships
  satisfies given constraints.

  Example:

  >>> n = 10
  >>> q = 3
  >>> d = 7
  >>> x = tf.zeros([n,q])
  >>> y = tf.ones([n,d])
  >>> param = tf.Variable([1.0, 2.0, 3.0])
  >>> scalar = 1.0
  >>> tf.debugging.assert_shapes([
  ...  (x, ('N', 'Q')),
  ...  (y, ('N', 'D')),
  ...  (param, ('Q',)),
  ...  (scalar, ()),
  ... ])

  >>> tf.debugging.assert_shapes([
  ...   (x, ('N', 'D')),
  ...   (y, ('N', 'D'))
  ... ])
  Traceback (most recent call last):
  ...
  ValueError: ...

  If `x`, `y`, `param` or `scalar` does not have a shape that satisfies
  all specified constraints, `message`, as well as the first `summarize` entries
  of the first encountered violating tensor are printed, and
  `InvalidArgumentError` is raised.

  Size entries in the specified shapes are checked against other entries by
  their __hash__, except:
    - a size entry is interpreted as an explicit size if it can be parsed as an
      integer primitive.
    - a size entry is interpreted as *any* size if it is None or '.'.

  If the first entry of a shape is `...` (type `Ellipsis`) or '*' that indicates
  a variable number of outer dimensions of unspecified size, i.e. the constraint
  applies to the inner-most dimensions only.

  Scalar tensors and specified shapes of length zero (excluding the 'inner-most'
  prefix) are both treated as having a single dimension of size one.

  Args:
    shapes: dictionary with (`Tensor` to shape) items, or a list of
      (`Tensor`, shape) tuples. A shape must be an iterable.
    data: The tensors to print out if the condition is False.  Defaults to error
      message and first few entries of the violating tensor.
    summarize: Print this many entries of the tensor.
    message: A string to prefix to the default message.
    name: A name for this operation (optional).  Defaults to "assert_shapes".

  Raises:
    ValueError:  If static checks determine any shape constraint is violated.
  )rA   rn   r=   rH   N)r(   )shapesrA   rn   r=   rH   s        r5   assert_shapes_v2rd  R  s    ~ 49gDJr7   c                 	  $ t        | t              r| j                         } t        |      }t	        j
                  |d| |g      5  | D cg c]:  \  }}|3t        |t        j                        r|nt	        j                  |      |f< }}}t        j                         $$fd}	g }
|D ]  \  }}t        |d      xs t        |d      }|st        |d |	|      d|      t        |      }d}t        |      D ].  \  }}|t        d	fvr|d
k7  rt        d| |	|      |fz        d}0 |
j!                  t#        ||t%        |      t'        |r|dd n|                    g }|
D ]  }t)        |j*                        }|dv }|j,                  r|r+t/        |j0                  |||||      }n;|rt3        |j0                  d
dg||||      }nt5        |j0                  |||||      }|j!                  |        g }i }|
D ]  }t        |j*                        D ]  \  }}t7        |      r|j,                  r|t)        |j*                        z
  }n|}||v st9        |      rkt9        |      rt;        |      }d}n||   \  }}}d |	|      |fz  }t	        j<                  |      5  |j>                  |   }ddd       t9              rat9        |      rVt;        |      t;        |      k7  r=t        d|| |	|j0                        ||||j0                  jA                         fz        tC        jD                  t	        j                  |      t	        j                  |            } |}!|:||d |	|j0                        z  |d|dtG        jH                  |j0                        g}!|j!                  tK        jL                  | |!|             t	        j<                  |      5  |j>                  |   }"ddd       "|j0                  |f||<     	 ddd       t	        j<                        5  tO        jP                        }#ddd       |#S c c}}w # 1 sw Y   xY w# 1 sw Y   rxY w# 1 sw Y   ]xY w# 1 sw Y   #S xY w)a  Assert tensor shapes and dimension size relationships between tensors.

  This Op checks that a collection of tensors shape relationships
  satisfies given constraints.

  Example:

  >>> n = 10
  >>> q = 3
  >>> d = 7
  >>> x = tf.zeros([n,q])
  >>> y = tf.ones([n,d])
  >>> param = tf.Variable([1.0, 2.0, 3.0])
  >>> scalar = 1.0
  >>> tf.debugging.assert_shapes([
  ...  (x, ('N', 'Q')),
  ...  (y, ('N', 'D')),
  ...  (param, ('Q',)),
  ...  (scalar, ()),
  ... ])

  >>> tf.debugging.assert_shapes([
  ...   (x, ('N', 'D')),
  ...   (y, ('N', 'D'))
  ... ])
  Traceback (most recent call last):
  ...
  ValueError: ...

  Example of adding a dependency to an operation:

  ```python
  with tf.control_dependencies([tf.assert_shapes(shapes)]):
    output = tf.matmul(x, y, transpose_a=True)
  ```

  If `x`, `y`, `param` or `scalar` does not have a shape that satisfies
  all specified constraints, `message`, as well as the first `summarize` entries
  of the first encountered violating tensor are printed, and
  `InvalidArgumentError` is raised.

  Size entries in the specified shapes are checked against other entries by
  their __hash__, except:
    - a size entry is interpreted as an explicit size if it can be parsed as an
      integer primitive.
    - a size entry is interpreted as *any* size if it is None or '.'.

  If the first entry of a shape is `...` (type `Ellipsis`) or '*' that indicates
  a variable number of outer dimensions of unspecified size, i.e. the constraint
  applies to the inner-most dimensions only.

  Scalar tensors and specified shapes of length zero (excluding the 'inner-most'
  prefix) are both treated as having a single dimension of size one.

  Args:
    shapes: A list of (`Tensor`, `shape`) tuples, wherein `shape` is the
      expected shape of `Tensor`. See the example code above. The `shape` must
      be an iterable. Each element of the iterable can be either a concrete
      integer value or a string that abstractly represents the dimension.
      For example,
        - `('N', 'Q')` specifies a 2D shape wherein the first and second
          dimensions of shape may or may not be equal.
        - `('N', 'N', 'Q')` specifies a 3D shape wherein the first and second
          dimensions are equal.
        - `(1, 'N')` specifies a 2D shape wherein the first dimension is
          exactly 1 and the second dimension can be any value.
      Note that the abstract dimension letters take effect across different
      tuple elements of the list. For example,
      `tf.debugging.assert_shapes([(x, ('N', 'A')), (y, ('N', 'B'))]` asserts
      that both `x` and `y` are rank-2 tensors and their first dimensions are
      equal (`N`).
      `shape` can also be a `tf.TensorShape`.
    data: The tensors to print out if the condition is False.  Defaults to error
      message and first few entries of the violating tensor.
    summarize: Print this many entries of the tensor.
    message: A string to prefix to the default message.
    name: A name for this operation (optional).  Defaults to "assert_shapes".

  Returns:
    Op raising `InvalidArgumentError` unless all shape constraints are
    satisfied.
    If static checks determine all constraints are satisfied, a `no_op` is
    returned.

  Raises:
    ValueError:  If static checks determine any shape constraint is violated.
  r(   Nc                 j    st        | t        j                        rt        |       S | j                  S r-   )r.   r   r   rI   rH   )rB   r   s    r5   tensor_namez"assert_shapes.<locals>.tensor_name  s)    	jM,F,FG#A&&VVmr7   r   __getitem__zTensor z.  Specified shape must be an iterable.  An iterable has the attribute `__iter__` or `__getitem__`.  Received specified shape: F*r   z%sTensor %s specified shape index %d.  Symbol `...` or `*` for a variable number of unspecified dimensions is only allowed as the first entryTr  )r   r  )rB   r   rA   rn   r=   rH   )rB   r,  rA   rn   r=   rH   zSpecified explicitlyz#Specified by tensor %s dimension %dzL%s%s.  Tensor %s dimension %s must have size %d.  Received size %d, shape %szTensor %s dimensionzmust have sizer  r   ))r.   dictitemsr   r   r   r   r   r   r   r   r   r   r  rJ  Ellipsisrd   r^  rQ  rT  r~   ra  r_  r#   rB   r$   r"   r]  rY  rK  control_dependenciesr`  r   r   r   r   rF   r   r   r   group)%rc  rA   rn   r=   rH   message_prefixrB   sshape_constraintsrg  tensor_dim_sizesr	   rS  is_iterablesymbolic_shape_tupletensors_specified_innermostrN  r\  rank_assertionsrO  r   rank_zero_or_one	assertionsize_assertionssize_specificationssize_symbol
tensor_dimspecified_sizesize_check_messagespecified_by_yspecified_at_dimactual_sizer@   data_rl   shapes_assertionr   s%                                       @r5   r(   r(     s&   x \\^F"7+.
~~dOfd^< WI &,>!Qq}  *!]-G-GH!//2A7 > >  113
 "3 &N
.*
- 1
.-
0  
 [0.	BC 	C #>2$)! !56 +)!V(C(
6J {62A6	78 8 '+#+  
13CF3K'0 'qr*6JLMNC&NP O! "(%%&d			 (gg	  #gga&	  gg	 Y'E"(H O! :I%e&:&:; 9I.![";/
  3u3344**--1A+1Nk* -N!7 $K0 =NN,< 6^,.>?@  ''8 9,,Z8K9k*/?/O;3~#66/!#5{5777K~{77$$&(() ) nn##K0##N35) %\ 2%EGG(<<j .2D(	E 
 
 !((EYOQ
 ''8 2%%j1D2.2EGGZ-H
k
*s9I:I{WIt 0 ?'--o>? 
w>l9 9:2 2kWI WIt? 
s\   Q6?QH"Q6-Q	=D,Q6)Q*	9 Q67RQ6Q'"Q6*Q3/Q66Q?Rc                 ,    t        j                   dg       t               st        d z        t	        j
                  t        j                         d      }d }t        j                         dz
   fd}t        j                  |||      S )z#Gets the difference x[1:] - x[:-1].rc   z+Expected x to be numeric, instead found: %sr  c                  8    t        j                  g t              S )Nr   )r   r   boolrV   r7   r5   r  z7_get_results_for_monotonic_comparison.<locals>.<lambda>  s    ..r> r7   r  c                  v      t        j                  dgdgz         t        j                  dg            S )Nr  r   )r   strided_slice)
compare_ops_lenrB   s   r5   r  z7_get_results_for_monotonic_comparison.<locals>.<lambda>  s:    a!qcEk2a!e, r7   )	r   rk   r*   r   r   r   rl   rF   r   )rB   r  is_shorter_than_twoshort_resultr   r  s   ``   @r5   %_get_results_for_monotonic_comparisonr    s    B4 !	1	
AAE
FF !innQ&7;>, //!
q
 %
$ 
&d	;;r7   zdebugging.is_numeric_tensorr*   c                 ^    t        | t        j                        xr | j                  t        v S )a)  Returns `True` if the elements of `tensor` are numbers.

  Specifically, returns `True` if the dtype of `tensor` is one of the following:

  * `tf.float16`
  * `tf.float32`
  * `tf.float64`
  * `tf.int8`
  * `tf.int16`
  * `tf.int32`
  * `tf.int64`
  * `tf.uint8`
  * `tf.uint16`
  * `tf.uint32`
  * `tf.uint64`
  * `tf.qint8`
  * `tf.qint16`
  * `tf.qint32`
  * `tf.quint8`
  * `tf.quint16`
  * `tf.complex64`
  * `tf.complex128`
  * `tf.bfloat16`

  Returns `False` if `tensor` is of a non-numeric type or if `tensor` is not
  a `tf.Tensor` object.
  )r.   r/   r0   rG   NUMERIC_TYPESr   s    r5   r*   r*     s&    @ 
FJ--	.	P6<<=3PPr7   math.is_non_decreasing)r  debugging.is_non_decreasingr)   r  r)   c                     t        j                  |d| g      5  t        | t        j                        }t        j
                  |      cddd       S # 1 sw Y   yxY w)a!  Returns `True` if `x` is non-decreasing.

  Elements of `x` are compared in row-major order.  The tensor `[x[0],...]`
  is non-decreasing if for every adjacent pair we have `x[i] <= x[i+1]`.
  If `x` has less than two elements, it is trivially non-decreasing.

  See also:  `is_strictly_increasing`

  >>> x1 = tf.constant([1.0, 1.0, 3.0])
  >>> tf.math.is_non_decreasing(x1)
  <tf.Tensor: shape=(), dtype=bool, numpy=True>
  >>> x2 = tf.constant([3.0, 1.0, 2.0])
  >>> tf.math.is_non_decreasing(x2)
  <tf.Tensor: shape=(), dtype=bool, numpy=False>

  Args:
    x: Numeric `Tensor`.
    name: A name for this operation (optional).  Defaults to "is_non_decreasing"

  Returns:
    Boolean `Tensor`, equal to `True` iff `x` is non-decreasing.

  Raises:
    TypeError: if `x` is not a numeric tensor.
  r)   N)r   r   r  r   r   r   rB   rH   r   s      r5   r)   r)     sM    F ~~d/!5 %0H4J4JKDt$% % %   /AAmath.is_strictly_increasing)r   debugging.is_strictly_increasingr+   r  r+   c                     t        j                  |d| g      5  t        | t        j                        }t        j
                  |      cddd       S # 1 sw Y   yxY w)aC  Returns `True` if `x` is strictly increasing.

  Elements of `x` are compared in row-major order.  The tensor `[x[0],...]`
  is strictly increasing if for every adjacent pair we have `x[i] < x[i+1]`.
  If `x` has less than two elements, it is trivially strictly increasing.

  See also:  `is_non_decreasing`

  >>> x1 = tf.constant([1.0, 2.0, 3.0])
  >>> tf.math.is_strictly_increasing(x1)
  <tf.Tensor: shape=(), dtype=bool, numpy=True>
  >>> x2 = tf.constant([3.0, 1.0, 2.0])
  >>> tf.math.is_strictly_increasing(x2)
  <tf.Tensor: shape=(), dtype=bool, numpy=False>

  Args:
    x: Numeric `Tensor`.
    name: A name for this operation (optional).
      Defaults to "is_strictly_increasing"

  Returns:
    Boolean `Tensor`, equal to `True` iff `x` is strictly increasing.

  Raises:
    TypeError: if `x` is not a numeric tensor.
  r+   N)r   r   r  r   r   r   r  s      r5   r+   r+     sM    H ~~d4qc: %0H4D4DEDt$% % %r  c                    |}d}| D ])  }||j                   j                  }|s|}!||k7  s'd} n |r|}d}| D ]  }||j                   j                  }|s&|}t        |d      r|j                  n
t	        |      }D||k7  sJt        t        |d      r|j                  n
t	        |      d|d|d|rd|z  nd	d
       |S |S )a  Asserts all items are of the same base type.

  Args:
    items: List of graph items (e.g., `Variable`, `Tensor`, `SparseTensor`,
        `Operation`, or `IndexedSlices`). Can include `None` elements, which
        will be ignored.
    expected_type: Expected type. If not specified, assert all items are
        of the same base type.

  Returns:
    Validated type, or none if neither expected_type nor items provided.

  Raises:
    ValueError: If any types do not match.
  FNTrH   z, type=z, must be of the same type ()z as %sr  r[  )rG   
base_dtyper   rH   r1   r   )rk  expected_typeoriginal_expected_typemismatchr4  	item_typeoriginal_item_strs          r5   _assert_same_base_typer    s      )( d**''i!I%  +M 
L		JJ))	#-+24+@diic$i
i'"40diic$i?0Ax++rIK L L
L r7   z!debugging.assert_same_float_dtyper%   c                 ~    | rt        | |      }|st        j                  }|S |j                  st	        d|z        |S )a  Validate and return float type based on `tensors` and `dtype`.

  For ops such as matrix multiplication, inputs and weights must be of the
  same float type. This function validates that all `tensors` are the same type,
  validates that type is `dtype` (if supplied), and returns the type. Type must
  be a floating point type. If neither `tensors` nor `dtype` is supplied,
  the function will return `dtypes.float32`.

  Args:
    tensors: Tensors of input values. Can include `None` elements, which will be
        ignored.
    dtype: Expected type.

  Returns:
    Validated type.

  Raises:
    ValueError: if neither `tensors` nor `dtype` is supplied, or result is not
        float, or the common type of the inputs is not a floating point type.
  z%Expected floating point type, got %s.)r  r   float32is_floatingr   )tensorsrG   s     r5   r%   r%   N  sG    4 "7E2E	NNE 
, 
<uD
EE	,r7   zdebugging.assert_scalarc                      t        | ||       y)a  Asserts that the given `tensor` is a scalar.

  This function raises `ValueError` unless it can be certain that the given
  `tensor` is a scalar. `ValueError` is also raised if the shape of `tensor` is
  unknown.

  This is always checked statically, so this method returns nothing.

  Args:
    tensor: A `Tensor`.
    message: A string to prefix to the default message.
    name:  A name for this operation. Defaults to "assert_scalar"

  Raises:
    ValueError: If the tensor is not scalar (rank 0), or if its shape is
      unknown.
  r	   r=   rH   N)r&   r  s      r5   assert_scalar_v2r  q  s    ( vwT:r7   r&   c           	      j   t        j                  |d| g      5 }t        j                  | |      } | j                         }t	        |      }|j
                  dk7  rCt        j                         rt        |d|d      t        |d| j                  d|d      | cddd       S # 1 sw Y   yxY w)	a5  Asserts that the given `tensor` is a scalar (i.e. zero-dimensional).

  This function raises `ValueError` unless it can be certain that the given
  `tensor` is a scalar. `ValueError` is also raised if the shape of `tensor` is
  unknown.

  Args:
    tensor: A `Tensor`.
    name:  A name for this operation. Defaults to "assert_scalar"
    message: A string to prefix to the default message.

  Returns:
    The input tensor (potentially converted to a `Tensor`).

  Raises:
    ValueError: If the tensor is not scalar (rank 0), or if its shape is
      unknown.
  r&   r   r   z"Expected scalar shape, saw shape: r[  zExpected scalar shape for z, saw shape: N)
r   r   r   r   r   r   r   r   r   rH   )r	   rH   r=   r   rF   s        r5   r&   r&     s    , ~~dOfX6 *""6
;FEg&G{{a		"	"	$#U- . 	. #V[[%9 : 	:  s   BB))B2c                     | rd| z  S y)Nz%s.  r  rV   )r=   s    r5   r   r     s    W	r7   ensure_shapec                     t        |t        j                        st        j                  |      }t        j                  | ||      S )a  Updates the shape of a tensor and checks at runtime that the shape holds.

  When executed, this operation asserts that the input tensor `x`'s shape
  is compatible with the `shape` argument.
  See `tf.TensorShape.is_compatible_with` for details.

  >>> x = tf.constant([[1, 2, 3],
  ...                  [4, 5, 6]])
  >>> x = tf.ensure_shape(x, [2, 3])

  Use `None` for unknown dimensions:

  >>> x = tf.ensure_shape(x, [None, 3])
  >>> x = tf.ensure_shape(x, [2, None])

  If the tensor's shape is not compatible with the `shape` argument, an error
  is raised:

  >>> x = tf.ensure_shape(x, [5])
  Traceback (most recent call last):
  ...
  tf.errors.InvalidArgumentError: Shape of tensor dummy_input [3] is not
    compatible with expected shape [5]. [Op:EnsureShape]

  During graph construction (typically tracing a `tf.function`),
  `tf.ensure_shape` updates the static-shape of the **result** tensor by
  merging the two shapes. See `tf.TensorShape.merge_with` for details.

  This is most useful when **you** know a shape that can't be determined
  statically by TensorFlow.

  The following trivial `tf.function` prints the input tensor's
  static-shape before and after `ensure_shape` is applied.

  >>> @tf.function
  ... def f(tensor):
  ...   print("Static-shape before:", tensor.shape)
  ...   tensor = tf.ensure_shape(tensor, [None, 3])
  ...   print("Static-shape after:", tensor.shape)
  ...   return tensor

  This lets you see the effect of `tf.ensure_shape` when the function is traced:
  >>> cf = f.get_concrete_function(tf.TensorSpec([None, None]))
  Static-shape before: (None, None)
  Static-shape after: (None, 3)

  >>> cf(tf.zeros([3, 3])) # Passes
  >>> cf(tf.constant([1, 2, 3])) # fails
  Traceback (most recent call last):
  ...
  InvalidArgumentError:  Shape of tensor x [3] is not compatible with expected shape [3,3].

  The above example raises `tf.errors.InvalidArgumentError`, because `x`'s
  shape, `(3,)`, is not compatible with the `shape` argument, `(None, 3)`

  Inside a `tf.function` or `v1.Graph` context it checks both the buildtime and
  runtime shapes. This is stricter than `tf.Tensor.set_shape` which only
  checks the buildtime shape.

  Note: This differs from `tf.Tensor.set_shape` in that it sets the static shape
  of the resulting tensor and enforces it at runtime, raising an error if the
  tensor's runtime shape is incompatible with the specified shape.
  `tf.Tensor.set_shape` sets the static shape of the tensor without enforcing it
  at runtime, which may result in inconsistencies between the statically-known
  shape of tensors and the runtime value of tensors.

  For example, of loading images of a known size:

  >>> @tf.function
  ... def decode_image(png):
  ...   image = tf.image.decode_png(png, channels=3)
  ...   # the `print` executes during tracing.
  ...   print("Initial shape: ", image.shape)
  ...   image = tf.ensure_shape(image,[28, 28, 3])
  ...   print("Final shape: ", image.shape)
  ...   return image

  When tracing a function, no ops are being executed, shapes may be unknown.
  See the [Concrete Functions Guide](https://www.tensorflow.org/guide/concrete_function)
  for details.

  >>> concrete_decode = decode_image.get_concrete_function(
  ...     tf.TensorSpec([], dtype=tf.string))
  Initial shape:  (None, None, 3)
  Final shape:  (28, 28, 3)

  >>> image = tf.random.uniform(maxval=255, shape=[28, 28, 3], dtype=tf.int32)
  >>> image = tf.cast(image,tf.uint8)
  >>> png = tf.image.encode_png(image)
  >>> image2 = concrete_decode(png)
  >>> print(image2.shape)
  (28, 28, 3)

  >>> image = tf.concat([image,image], axis=0)
  >>> print(image.shape)
  (56, 28, 3)
  >>> png = tf.image.encode_png(image)
  >>> image2 = concrete_decode(png)
  Traceback (most recent call last):
  ...
  tf.errors.InvalidArgumentError:  Shape of tensor DecodePng [56,28,3] is not
    compatible with expected shape [28,28,3].

  Caution: if you don't use the result of `tf.ensure_shape` the check may not
  run.

  >>> @tf.function
  ... def bad_decode_image(png):
  ...   image = tf.image.decode_png(png, channels=3)
  ...   # the `print` executes during tracing.
  ...   print("Initial shape: ", image.shape)
  ...   # BAD: forgot to use the returned tensor.
  ...   tf.ensure_shape(image,[28, 28, 3])
  ...   print("Final shape: ", image.shape)
  ...   return image

  >>> image = bad_decode_image(png)
  Initial shape:  (None, None, 3)
  Final shape:  (None, None, 3)
  >>> print(image.shape)
  (56, 28, 3)

  Args:
    x: A `Tensor`.
    shape: A `TensorShape` representing the shape of this tensor, a
      `TensorShapeProto`, a list, a tuple, or None.
    name: A name for this operation (optional). Defaults to "EnsureShape".

  Returns:
    A `Tensor`. Has the same type and contents as `x`.

  Raises:
    tf.errors.InvalidArgumentError: If `shape` is incompatible with the shape
    of `x`.
  r   )r.   r
   TensorShaper   r  )rB   rF   rH   s      r5   r  r    s:    T 
E<33	4$$U+E			5t	44r7   EnsureShapec                     ~ |S r-   rV   )r<   grads     r5   _ensure_shape_gradr  B	  s
    	+r7   )NNN)NNNN)NNNNN)NNNNNN)NNr-   )vrR   collectionsrh   r|   tensorflow.python.eagerr   tensorflow.python.frameworkr   r   r   r   r	   r/   r
   r   tensorflow.python.opsr   r   r   r   r   tensorflow.python.utilr   r   r    tensorflow.python.util.tf_exportr   	frozensetfloat16r  float64int8int16r   int64uint8uint16uint32uint64qint8qint16qint32quint8quint16	complex64
complex128bfloat16r  __all__r6   rD   rI   rW   r]   r`   rz   r   r   add_dispatch_supportdeprecated_endpointsr   r   r   r   r   r   r   r   r   &register_binary_elementwise_assert_apir   r   r   r   r   r   r   r   r   r   r   r    r   r!   r  r
  r"   r  r#   r!  r%  r.  r1  r$   r7  r   r?  r'   rQ  rT  rY  r]  
namedtupler^  rd  r(   r  r*   r)   r+   r  r%   r  r&   r   r  RegisterGradientr  rV   r7   r5   <module>r     s    "   + . . + 5 < 4 3 + & 5 2 * ) . + 6
NNFNNFNNFKK
LL&,,fmmV]]
MM6<<v}}
NNF$$f&7&7	 6FA
<~tnK\3l4HNV &*,DEG 
!!!":;P < G
P6 &2.	O  /O> *,=>?	!!!"345*%@ & 5  @@" &2.	O  /O> *,=>?	!!!"345*%@ & 5  @@  *r2	(  3(B .0EFG	!!!"786>*F + 9  HF" *r2	(  3(B .0EFG	!!!"786>*F + 9  HF" #^;	00	t^Q/Q 0  1 <Q '89	00	D(#8 $  1 :8 (R0	00	t0!4& 5  1 1&
 ,.ABC	00	!!!"56D(#8<L $ 7  1 D
L "r*	00	GK11  1 +11h &67	00	!!!-0CG	ML 1  1 8ML` "Mb9	00	sM1-P .  1 :P &67	00	C"2 #  1 82
 (R0	00	t0!4L 5  1 1L
 ,.ABC	00	!!!"56D(#M $ 7  1 D
M
 %'7B?	00	s,a0# 1  1 @#
 )+;<=	00	C"; #  1 >;
 +3	00	t3Q7) 8  1 4)
 /1GHI	00	!!!"89D(#BF"P $ :  1 J
P-J` "Mb9	A  :A@ &67	;  8;| +3	J  4J@ /1GHI	!!!"89;?= :  J=@$1Jh %"-	F  .F> )+;<=	!!!"23<@B 4  >BJ %"-	2  .2& )+;<=	!!!"23!G 4  >!GH "r*	J  +JB &67	!!!-0H 1  8H8M>+ )+((>@
 $,	@D>J  ->JB ()*	{  +{~<& !%':;= "!!"56Q 7=Q>  
!!!"?"57%7 %@ ! 
!!!"D":<%< %B,^ '+-FGI 
!!!";< = I
< $,	;  -;* (/:;	!!!/2 3  <B >	K5  K5\ m$ %r7   