o
    i 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.TTshapes   Reshape   inputsattrsctx)_datatype_enumr   args_to_matching_eagerr   int32int64)r   shaper   attr_tattr_tshapeinputs_flatr   result r   V/var/www/myenv/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   
index_types   Fillr   r   )dtypeas_datatype_enumconvert_to_eager_tensorr   r   r   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   as_dtypeensure_initialized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   namer:   r   r   r    constant_v1i   s   =r?   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.
  FTr9   r<   )r(   r#   r   r>   r   r   r    r6      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   executing_eagerlyr   enabledTrace_constant_eager_implr   _create_graph_constant)r(   r#   r   r>   r:   r;   r   const_tensorr   r   r    r=     s    r=   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
   as_shaper   r1   tuplenum_elementsr!   as_listr#   r   boolr   devicer)   r*   )r   r(   r#   r   r:   tnum_txr   r   r    rC     sB   





rC   c                 C   s"   t | tjr
| j}n| }|jdkS )Nr8   )r,   
tensor_libTensoroptype)tensor_or_oprR   r   r   r    is_constant=  s   
rU   c                 C   s   |}t | ||dS )Nr#   r>   )r6   )vr#   r>   as_ref_r   r   r    $_constant_tensor_conversion_functionE  s   rZ   d      c                 C   s   |}|   std|  d|  }d}|D ]
}|dkr |} n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_tensorrV   )is_fully_defined
ValueErrorrJ   r   r   r   r1   r6   )sr#   r>   rX   rY   s_listint64_valuedimr   r   r    (_tensor_shape_tensor_conversion_functionW  s,   
rg   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 r]   zCannot convert Dimension r^   r_   r`   rV   )r(   rb   r   r   r   r1   r6   )rF   r#   r>   rX   rY   r   r   r    %_dimension_tensor_conversion_functiony  s   
rh   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,   rP   rQ   self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`.r8   r(   zNo encoder for object z	 of type r+   )r   StructuredValuer,   r   r0   tensor_valueCopyFromr   make_tensor_protonumpyrR   rS   get_attrr   NotEncodableErrorstr)rn   rs   	encode_fnencoded_tensorr   r   r    	do_encode  s   z_ConstantTensorCodec.do_encodec                 C   
   | dS )Nrs   HasFieldrn   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`.)rs   r6   r   MakeNdarray)rn   r(   	decode_fntensor_protor   r   r   r    	do_decode  s   z_ConstantTensorCodec.do_decodeN__name__
__module____qualname____doc__rp   r|   r   r   r   r   r   r    rj     s    rj   c                   @   ri   )_NumpyCodeczCodec for Numpy.c                 C   rk   rl   )r,   r-   r.   rm   r   r   r    rp     rq   z_NumpyCodec.can_encodec                 C   s    ~t  }|jt| |S )z2Returns an encoded `TensorProto` for `np.ndarray`.)r   rr   numpy_valuert   r   ru   )rn   r   rz   encoded_numpyr   r   r    r|     s   z_NumpyCodec.do_encodec                 C   r}   )Nr   r~   r   r   r   r    r     r   z_NumpyCodec.can_decodec                 C   s   ~|j }t|}|S )z6Returns the `np.ndarray` encoded by the proto `value`.)r   r   r   )rn   r(   r   r   rv   r   r   r    r     s   
z_NumpyCodec.do_decodeNr   r   r   r   r    r     s    	r   rl   )NNr8   F)NNr8   )NNF)/r   rv   r-   tensorflow.core.frameworkr   tensorflow.core.protobufr   tensorflow.python.eagerr   r   tensorflow.python.frameworkr   r   r   rP   r	   r
   r   tensorflow.python.profilerr   tensorflow.python.saved_modelr    tensorflow.python.util.tf_exportr   r!   r)   r*   r%   r?   r6   r=   rC   rU   rZ   ,register_tensor_conversion_function_internal_CONSTANT_OP_CONVERTIBLES#register_tensor_conversion_functionlistrH   objectrg   TensorShaperh   	Dimensionrj   register_codecr   r   r   r   r    <module>   sv   

$
@d



#