o
    ?eA                     @   s  d 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 Zdd Zdd Zd1ddZedgd	d2ddZedg dd3ddZdd  Zd!d" Zd#d$ Z 		d4d%d&Z!e"ej#e!d e$e%e&fe!d' e$e'e!d( 			d4d)d*Z(e$ej)e(d' 			d4d+d,Z*e$ej+e*d' G d-d. d.Z,e-e,  G d/d0 d0Z.e-e.  dS )5zvOperations that generate constants.

See the [constants guide](https://tensorflow.org/api_guides/python/constant_op).
    N)	types_pb2)
struct_pb2)context)execute)dtypes)ops)tensor)tensor_conversion_registry)tensor_shape)tensor_util)trace)nested_structure_coder)	tf_exportc                 C   sX   |   }t|g|tjtjgtj\}\}| |g}d|d|f}tjdd|||d\}|S )zEEager-only version of Reshape op; requires tensor is an eager Tensor.TZTshapes   Reshape   Zinputsattrsctx)Z_datatype_enumr   Zargs_to_matching_eagerr   int32int64)r   shaper   attr_tZattr_tshapeinputs_flatr   result r   h/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/tensorflow/python/framework/constant_op.py_eager_reshape&   s   

r   c                 C   sF   |j j}t| |tj} | |g}d|dtjf}tjdd|||d\}|S )zAEager-only version of Fill op; requires value is an eager Tensor.r   Z
index_types   Fillr   r   )dtypeas_datatype_enumconvert_to_eager_tensorr   r   r   ZDT_INT32r   )dimsvaluer   r   r   r   r   r   r   r   _eager_fill2   s   
r"   c                 C   s(   d| j jf}tjdd| g||d\}|S )zFEager-only version of Identity op; requires tensor is an eager Tensor.r   s   Identityr   r   )r   r   r   )r   r   r   r   r   r   r   _eager_identity=   s
   r#   c                 C   s   t | tjr
|  } t | tjr*|dur(| j|kr(td|  d|d| jd| S |durCz|j}W n t	yB   t
|j}Y nw |  t| |j|S )a  Converts the given `value` to an `EagerTensor`.

  Note that this function could return cached copies of created constants for
  performance reasons.

  Args:
    value: value to convert to EagerTensor.
    ctx: value of context.context().
    dtype: optional desired dtype of the converted EagerTensor.

  Returns:
    EagerTensor created from value.

  Raises:
    TypeError: if `dtype` is not compatible with the type of t.
  NzExpected tensor z with dtype z, but got dtype .)
isinstancenpndarraycopyr   EagerTensorr   	TypeErrorr   AttributeErrorr   Zas_dtypeZensure_initializedZdevice_name)r!   r   r   r   r   r   r   E   s    

r   constant)v1ConstFc                 C   s   t | ||||ddS )a{  Creates a constant tensor.

  The resulting tensor is populated with values of type `dtype`, as
  specified by arguments `value` and (optionally) `shape` (see examples
  below).

  The argument `value` can be a constant value, or a list of values of type
  `dtype`. If `value` is a list, then the length of the list must be less
  than or equal to the number of elements implied by the `shape` argument (if
  specified). In the case where the list length is less than the number of
  elements specified by `shape`, the last element in the list will be used
  to fill the remaining entries.

  The argument `shape` is optional. If present, it specifies the dimensions of
  the resulting tensor. If not present, the shape of `value` is used.

  If the argument `dtype` is not specified, then the type is inferred from
  the type of `value`.

  For example:

  ```python
  # Constant 1-D Tensor populated with value list.
  tensor = tf.constant([1, 2, 3, 4, 5, 6, 7]) => [1 2 3 4 5 6 7]

  # Constant 2-D tensor populated with scalar value -1.
  tensor = tf.constant(-1.0, shape=[2, 3]) => [[-1. -1. -1.]
                                               [-1. -1. -1.]]
  ```

  `tf.constant` differs from `tf.fill` in a few ways:

  *   `tf.constant` supports arbitrary constants, not just uniform scalar
      Tensors like `tf.fill`.
  *   `tf.constant` creates a `Const` node in the computation graph with the
      exact value at graph construction time. On the other hand, `tf.fill`
      creates an Op in the graph that is expanded at runtime.
  *   Because `tf.constant` only embeds constant values in the graph, it does
      not support dynamic shapes based on other runtime Tensors, whereas
      `tf.fill` does.

  Args:
    value:          A constant value (or list) of output type `dtype`.

    dtype:          The type of the elements of the resulting tensor.

    shape:          Optional dimensions of resulting tensor.

    name:           Optional name for the tensor.

    verify_shape:   Boolean that enables verification of a shape of values.

  Returns:
    A Constant Tensor.

  Raises:
    TypeError: if shape is incorrectly specified or unsupported.
  Fverify_shapeallow_broadcast_constant_impl)r!   r   r   namer0   r   r   r   constant_v1i   s   =r5   c                 C   s   t | |||dddS )a#  Creates a constant tensor from a tensor-like object.

  Note: All eager `tf.Tensor` values are immutable (in contrast to
  `tf.Variable`). There is nothing especially _constant_ about the value
  returned from `tf.constant`. This function is not fundamentally different from
  `tf.convert_to_tensor`. The name `tf.constant` comes from the `value` being
  embedded in a `Const` node in the `tf.Graph`. `tf.constant` is useful
  for asserting that the value can be embedded that way.

  If the argument `dtype` is not specified, then the type is inferred from
  the type of `value`.

  >>> # Constant 1-D Tensor from a python list.
  >>> tf.constant([1, 2, 3, 4, 5, 6])
  <tf.Tensor: shape=(6,), dtype=int32,
      numpy=array([1, 2, 3, 4, 5, 6], dtype=int32)>
  >>> # Or a numpy array
  >>> a = np.array([[1, 2, 3], [4, 5, 6]])
  >>> tf.constant(a)
  <tf.Tensor: shape=(2, 3), dtype=int64, numpy=
    array([[1, 2, 3],
           [4, 5, 6]])>

  If `dtype` is specified, the resulting tensor values are cast to the requested
  `dtype`.

  >>> tf.constant([1, 2, 3, 4, 5, 6], dtype=tf.float64)
  <tf.Tensor: shape=(6,), dtype=float64,
      numpy=array([1., 2., 3., 4., 5., 6.])>

  If `shape` is set, the `value` is reshaped to match. Scalars are expanded to
  fill the `shape`:

  >>> tf.constant(0, shape=(2, 3))
    <tf.Tensor: shape=(2, 3), dtype=int32, numpy=
    array([[0, 0, 0],
           [0, 0, 0]], dtype=int32)>
  >>> tf.constant([1, 2, 3, 4, 5, 6], shape=[2, 3])
  <tf.Tensor: shape=(2, 3), dtype=int32, numpy=
    array([[1, 2, 3],
           [4, 5, 6]], dtype=int32)>

  `tf.constant` has no effect if an eager Tensor is passed as the `value`, it
  even transmits gradients:

  >>> v = tf.Variable([0.0])
  >>> with tf.GradientTape() as g:
  ...     loss = tf.constant(v + v)
  >>> g.gradient(loss, v).numpy()
  array([2.], dtype=float32)

  But, since `tf.constant` embeds the value in the `tf.Graph` this fails for
  symbolic tensors:

  >>> with tf.compat.v1.Graph().as_default():
  ...   i = tf.compat.v1.placeholder(shape=[None, None], dtype=tf.float32)
  ...   t = tf.constant(i)
  Traceback (most recent call last):
  ...
  TypeError: ...

  `tf.constant` will create tensors on the current device. Inputs which are
  already tensors maintain their placements unchanged.

  Related Ops:

  * `tf.convert_to_tensor` is similar but:
    * It has no `shape` argument.
    * Symbolic tensors are allowed to pass through.

    >>> with tf.compat.v1.Graph().as_default():
    ...   i = tf.compat.v1.placeholder(shape=[None, None], dtype=tf.float32)
    ...   t = tf.convert_to_tensor(i)

  * `tf.fill`: differs in a few ways:
    *   `tf.constant` supports arbitrary constants, not just uniform scalar
        Tensors like `tf.fill`.
    *   `tf.fill` creates an Op in the graph that is expanded at runtime, so it
        can efficiently represent large tensors.
    *   Since `tf.fill` does not embed the value, it can produce dynamically
        sized outputs.

  Args:
    value: A constant value (or list) of output type `dtype`.
    dtype: The type of the elements of the resulting tensor.
    shape: Optional dimensions of resulting tensor.
    name: Optional name for the tensor.

  Returns:
    A Constant Tensor.

  Raises:
    TypeError: if shape is incorrectly specified or unsupported.
    ValueError: if called on a symbolic tensor.
  FTr/   r2   )r!   r   r   r4   r   r   r   r,      s   ac                 C   sx   t   }| r0tjr(td t|| |||W  d   S 1 s#w   Y  t|| |||S t| |||||}|S )zImplementation of constant.ztf.constantN)r   Zexecuting_eagerlyr   enabledTrace_constant_eager_implr   Z_create_graph_constant)r!   r   r   r4   r0   r1   r   Zconst_tensorr   r   r   r3     s    r3   c                 C   s"  t || |}|du r|S t|}||jkr|S |r0td| d| dt| dt|j d	|j }|| krCt|| | S |dkrz|j	t
jkrrtd t| t|| | }W d   n1 shw   Y  t|| S t| || S td	| d| d
|dd| d|  d)z)Creates a constant on the current device.NzExpected Tensor z (converted from z) with shape z, but got shape r$   r   z/device:CPU:0z>Eager execution of tf.constant with unsupported shape. Tensor z) has dz elements, but got `shape` z with z elements).)r   r
   Zas_shaper   r*   tupleZnum_elementsr   as_listr   r   boolr   Zdevicer"   r#   )r   r!   r   r   r0   tZnum_txr   r   r   r8     sB   





r8   c                 C   s"   t | tjr
| j}n| }|jdkS )Nr.   )r%   
tensor_libTensoroptype)Ztensor_or_oprA   r   r   r   is_constant=  s   
rC   c                 C   s   |}t | ||dS )Nr   r4   )r,   )vr   r4   as_ref_r   r   r   $_constant_tensor_conversion_functionE  s   rH   d      c                 C   s   |}|   std|  d|  }d}|D ]
}|dkr |} q!q|durH|tjtjfvr8td|  d| d|tjkrG|rGtd|  d	n|rMtjntj}|du rVd
}t|||dS )z*Function to convert TensorShape to Tensor.z-Cannot convert a partially known TensorShape  to a Tensor.r   l        NzCannot convert TensorShape 
 to dtype +. Allowed dtypes are tf.int32 and tf.int64.zC to dtype int32; a dimension is too large. Consider using tf.int64.shape_as_tensorrD   )Zis_fully_defined
ValueErrorr;   r   r   r   r*   r,   )sr   r4   rF   rG   Zs_listZint64_valuedimr   r   r   (_tensor_shape_tensor_conversion_functionW  s,   
rR   c                 C   sp   |}| j du rtd|  d|dur'|tjtjfvr&td|  d| dntj}|du r0d}t| j ||dS )	z(Function to convert Dimension to Tensor.Nz!Cannot convert unknown Dimension rK   zCannot convert Dimension rL   rM   rN   rD   )r!   rO   r   r   r   r*   r,   )r9   r   r4   rF   rG   r   r   r   %_dimension_tensor_conversion_functiony  s   
rS   c                   @   0   e Zd ZdZdd Zdd Zdd Zdd	 Zd
S )_ConstantTensorCodeczCodec for Tensor.c                 C      t |tjS N)r%   r?   r@   selfZpyobjr   r   r   
can_encode     z_ConstantTensorCodec.can_encodec                 C   st   ~t  }t|tjr|jt|	  |S |j
jdkr*|j|j
d |S tdt| dt| d)z;Returns an encoded `TensorProto` for the given `tf.Tensor`.r.   r!   zNo encoder for object z	 of type r$   )r   StructuredValuer%   r   r)   tensor_valueCopyFromr   make_tensor_protonumpyrA   rB   Zget_attrr   ZNotEncodableErrorstr)rY   r]   	encode_fnZencoded_tensorr   r   r   	do_encode  s   z_ConstantTensorCodec.do_encodec                 C   
   | dS )Nr]   ZHasFieldrY   r!   r   r   r   
can_decode     
z_ConstantTensorCodec.can_decodec                 C   s   ~|j }tt|}|S )z5Returns the `tf.Tensor` encoded by the proto `value`.)r]   r,   r   MakeNdarray)rY   r!   	decode_fntensor_protor   r   r   r   	do_decode  s   z_ConstantTensorCodec.do_decodeN__name__
__module____qualname____doc__rZ   rc   rg   rl   r   r   r   r   rU     s    rU   c                   @   rT   )_NumpyCodeczCodec for Numpy.c                 C   rV   rW   )r%   r&   r'   rX   r   r   r   rZ     r[   z_NumpyCodec.can_encodec                 C   s    ~t  }|jt| |S )z2Returns an encoded `TensorProto` for `np.ndarray`.)r   r\   numpy_valuer^   r   r_   )rY   rs   rb   Zencoded_numpyr   r   r   rc     s   z_NumpyCodec.do_encodec                 C   rd   )Nrs   re   rf   r   r   r   rg     rh   z_NumpyCodec.can_decodec                 C   s   ~|j }t|}|S )z6Returns the `np.ndarray` encoded by the proto `value`.)rs   r   ri   )rY   r!   rj   rk   r`   r   r   r   rl     s   
z_NumpyCodec.do_decodeNrm   r   r   r   r   rr     s    	rr   rW   )NNr.   F)NNr.   )NNF)/rq   r`   r&   Ztensorflow.core.frameworkr   Ztensorflow.core.protobufr   Ztensorflow.python.eagerr   r   Ztensorflow.python.frameworkr   r   r   r?   r	   r
   r   Ztensorflow.python.profilerr   Ztensorflow.python.saved_modelr   Z tensorflow.python.util.tf_exportr   r   r"   r#   r   r5   r,   r3   r8   rC   rH   Z,register_tensor_conversion_function_internalZ_CONSTANT_OP_CONVERTIBLESZ#register_tensor_conversion_functionlistr:   objectrR   ZTensorShaperS   Z	DimensionrU   Zregister_codecrr   r   r   r   r   <module>   sv   

$
@d



#