o
    2hY                     @   st  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lmZ ddlmZ ddlmZ ddlmZ dZdZ e!dgZ"e!g dZ#ededdddd.ddZ$G dd dej%Z&d.d d!Z'd"d# Z(d$d% Z)d&d' Z*ej+d(d) Z,G d*d+ d+e-Z.d,d- Z/dS )/z>xla is an experimental library that provides XLA support APIs.    N)xla_ops)xla_ops_grad)attr_value_pb2)summary_op_util)context)def_function)ops)	array_ops)control_flow_ops)variable_scope)
tf_logging)compat)nest)
tf_inspect)collections_abc)
deprecated)	tf_export_xla_compile_id   Placeholder)	AudioSummaryAudioSummaryV2HistogramSummaryImageSummaryMergeSummaryPrintScalarSummaryTensorSummaryTensorSummaryV2zxla.experimental.compilezXxla.experimental.compile is deprecated. Consider using `@tf.function(jit_compile=True)`.T)	warn_oncec                    s,   t  rtj fdd}| S t S )a  Builds an operator that compiles and runs `computation` with XLA.

  NOTE: In eager mode, `computation` will have `@tf.function` semantics.

  Args:
    computation: A Python function that builds a computation to apply to the
      input. If the function takes n inputs, 'inputs' should be a list of n
      `Tensor`s.

      `computation` may return a list of `Tensor`s and `Operation`s.
      `Tensor`s must come before `Operation`s in the returned list.

      All `Operation`s returned from `computation` will be executed when
      evaluating any of the returned output tensors.
    inputs: A list of inputs or `None` (equivalent to an empty list). Each input
      can be a nested structure containing values that can be converted to
      `Tensor`s. Note that passing an N-dimension list of compatible values will
      result in an N-dimension list of scalar `Tensor`s rather than a single
      Rank-N `Tensor`. If you need a different behavior, convert parts of
      `inputs` to `Tensor`s with `tf.convert_to_tensor`.

  Returns:
    List of `Tensor`s corresponding to the `Tensor`s from
      the output of `computation` i.e. the same return value as if
      computation(*inputs) is called directly, with the following exceptions:
      * None output: a NoOp would be returned with a control dependency on
         `computation`.
      * Single value output: a tuple containing the value would be returned.
      * Operation-only outputs: a NoOp would be returned with a control
      dependency on `computation`.
      TODO(b/121383831): Investigate into removing these special cases.

  Raises:
    RuntimeError: When eager execution is enabled.

  Known issues:
    When a tf.random operation is built with XLA, the implementation doesn't
      pass the user provided seed to the XLA compiler. As such, the XLA compiler
      generates a random number and uses it as a seed when compiling the
      operation. This implementation causes a violation of the Tensorflow
      defined semantics in two aspects. First, changing the value of the user
      defined seed doesn't change the numbers generated by the operation.
      Second, when a seed is not specified, running the program multiple times
      will generate the same numbers.
  c                      s
   t  S N)_compile_internal computationinputsr"   ]/var/www/html/chatgem/venv/lib/python3.10/site-packages/tensorflow/python/compiler/xla/xla.pyxla_compile_wrappers   s   
z$compile.<locals>.xla_compile_wrapper)r   executing_eagerlyr   functionr!   )r$   r%   r'   r"   r#   r&   compile>   s
   3
r*   c                       sx   e Zd ZdZ fddZdd ZdejfddZdejfd	d
Z	dd Z
dejfddZedd Zedd Z  ZS )XLACompileContexta  A `ControlFlowContext` for nodes inside an XLA computation cluster.

  THIS IS ONLY FOR TENSORFLOW INTERNAL IMPLEMENTATION, DO NO USE DIRECTLY.

  The primary role of `XLACompileContext` is to mark operators inside a
  xla.compile() computation with attribute "_xla_compile_id=XYZ", where XYZ is
  a unique name.

  `ControlFlowContext` is used to perform the annotation since it integrates
  with Tensorflow constructs like ResourceVariables. For example, if a
  `ResourceVariable` is constructed inside a xla.compile() block, the
  `ResourceVariable` implementation can use
  `with ops.control_dependencies(None)` to build the variable's definition
  outside the compiled computation.
  c                    s0   t t|   || _t|| _g | _|| _dS )a  Builds a new XLACompileContext.

    Args:
      name: a unique name for the context, used to populate the
        `_xla_compile_id` attribute.
      pivot: a pivot node. Nodes in the XLACompileContext that do not have any
        inputs will have a control dependency on the pivot node. This ensures
        that nodes are correctly included in any enclosing control flow
        contexts.
    N)	superr+   __init___namer   as_bytes_name_as_bytes_unsupported_ops_pivot)selfnamepivot	__class__r"   r&   r-      s
   
zXLACompileContext.__init__c                 C   sh   | j r0ddd | j d t D }tdt| j | t| j tkr2tdt| j t  d S d S d S )N
c                 S   s   g | ]
}d |j |jf qS )z	  %s (%s))typer4   ).0opr"   r"   r&   
<listcomp>   s    zCXLACompileContext.report_unsupported_operations.<locals>.<listcomp>z$%d unsupported operations found: 
%sz... and %d more)r1   join_MAX_WARNING_LINESloggingwarninglen)r3   op_strr"   r"   r&   report_unsupported_operations   s   

z/XLACompileContext.report_unsupported_operationsr;   c                 C   sx   g }g }|j D ]'}d}| }|dur!|| krd}n|j}|dus|r)|| q|| q|  || ||fS )z2Remove any external control dependency on this op.FNT)control_inputs_get_control_flow_context_outer_contextappend_remove_all_control_inputs_add_control_inputs)r3   r;   internal_control_inputsexternal_control_inputsxis_internal_opctxtr"   r"   r&   _RemoveExternalControlEdges   s"   

z-XLACompileContext._RemoveExternalControlEdgesc           	      C   s  |j tv rtd|j |j |j tv r| j| tdd |j	D r*t
d|j t|jjv r7td|j |ttj| jd |j| |j| | |\}}|j	sa|s`|| j ntt|j	D ]}|j	| }| |}||ur~||| qh|rtd |   dd	 |D }|    W d   n1 sw   Y  |!| d
d	 |j"D }| }|dur|j#$| |j%}|dus| j%r| j%&| dS dS )zFCreate op in XLACompileContext and notifies outer context recursively.zhOperation of type %s (%s) is not supported in XLA. Execution will fail if this op is used in the graph. c                 s   s    | ]}|j jV  qd S r    )dtype_is_ref_dtyper:   rL   r"   r"   r&   	<genexpr>   s    z*XLACompileContext.AddOp.<locals>.<genexpr>zTNon-resource Variables are not supported inside XLA computations (operator name: %s)z?XLA compiled computations cannot be nested, (operator name: %s))sNc                 S   s$   g | ]}|j rt|j d  jqS )r   )outputsr	   identityr;   rR   r"   r"   r&   r<      s    z+XLACompileContext.AddOp.<locals>.<listcomp>c                 S   s   g | ]}|j qS r"   r4   rR   r"   r"   r&   r<      s    )'r9   _DENYLISTED_OPSr?   errorr4   _UNSUPPORTED_OPSr1   rG   anyr%   NotImplementedError_XLA_COMPILE_ATTRnode_defattr
ValueError	_set_attrr   	AttrValuer0   graphprevent_feedingprevent_fetchingrO   _add_control_inputr2   rangerA   AddValue_update_inputr   control_dependenciesEnterExitrI   rU   _valuesupdaterF   
AddInnerOp)	r3   r;   rJ   rK   indexrL   real_xoutput_namesr   r"   r"   r&   AddOp   sj   





	zXLACompileContext.AddOpc                 C   sl   |j | jv r| j|j }|du r|S |S |}| j|j  | jr.| j|}| j|j  || j|j < |S )zCAdd `val` to the current context and its outer context recursively.N)r4   rm   _external_valuesgetaddrF   rh   )r3   valresultr"   r"   r&   rh     s   zXLACompileContext.AddValuec                 C   s$   |  | | jr| j| d S d S r    )rs   rF   ro   )r3   r;   r"   r"   r&   ro     s   
zXLACompileContext.AddInnerOpc                 C   s   d S r    r"   r3   r"   r"   r&   
grad_state!  s   zXLACompileContext.grad_statec                 C   s   |   r	|   jS dS )z0Forwards to the enclosing while context, if any.F)GetWhileContext	back_propry   r"   r"   r&   r|   )  s   
zXLACompileContext.back_prop)__name__
__module____qualname____doc__r-   rC   r   	OperationrO   rs   rh   ro   propertyrz   r|   __classcell__r"   r"   r6   r&   r+   |   s    I
r+   c                 C   s  |du rg }t |tjstdt|}dd |D }t d}t	j
|d d}t||d}z^|  d	d t|D }tj||d
}t }|j}|d t  | | }	W d   n1 sdw   Y  || t|	}
|
r{t|	\}}nt|	\}}|| W |  |  n	|  |  w |st	j|ddS dd t|D }t| dd t|D }W d   n1 sw   Y  |
stj|	|d
}|S )aE  Builds graph operators that compiles and symbolically executes computation.

  Args:
    computation: A Python function that builds the computation to compile and
      execute.
    inputs: A list of inputs or `None` (equivalent to an empty list). Each input
      can be a nested structure containing values that are convertible to
      tensors. Note that passing an N-dimension list of compatible values will
      result in a N-dimension list of scalar tensors rather than a single Rank-N
      tensors. If you need different behavior, convert part of inputs to tensors
      with `tf.convert_to_tensor`.

  Returns:
    Same data structure as if computation(*inputs) is called directly with some
    exceptions for correctness. Exceptions include: 1) None output 2) Single
    value output 3) Operation-only outputs
  Raises:
    ValueError: If any element in computation outputs is neither an operations
      or a value that can be converted to tensor.
    ValueError: If computation outputs is non-flat and contains any Operations.
    TypeError: If `inputs` is not a list or tuple.
  Nzinputs must be a listc                 S   s   g | ]}t |qS r"   )r   convert_to_tensorrR   r"   r"   r&   r<   Q  s    z%_compile_internal.<locals>.<listcomp>clusterz/pivotrW   )r4   r5   c                 S   $   g | ]\}}t j|d |dqS )zinput_{}rW   )r	   rV   format)r:   irL   r"   r"   r&   r<   [      )	structureflat_sequenceToutput_0c                 S   r   )zoutput{}rW   )r   xla_cluster_outputr   r:   r   or"   r"   r&   r<     r   c                 S   s"   g | ]\}}t j|d | dqS )z	output_%drW   )r	   rV   r   r"   r"   r&   r<     s    )
isinstancer   Sequence	TypeErrorr   flattenr   get_default_graphunique_namer
   no_opr+   rk   	enumeratepack_sequence_asr   get_variable_scopeuse_resourceset_use_resource_disable_summary_contextis_flat_postprocess_flat_outputs_postprocess_non_flat_outputs
ExitResultrC   rl   grouprj   )r$   r%   flat_inputscluster_namer5   r   computation_inputsvscopesaved_use_resourcerU   outputs_is_flatoutput_tensorscontrol_depsr"   r"   r&   r!   1  s`   






r!   c                 C   sd   t | tjr | D ]}t |tjst |tjst|jdr dS qt | tjr(dS t| jdr0dS dS )au  Checks if outputs is a flat structure.

    Following structures and values are considered flat:
    1) None
    2) A single object
    3) A list or tuple of Tensors/Operations

    The only structures that this function understands are sequences,
    dictionaries and types defined using the attrs library.  E.g. this means
    that if outputs contains a single user-defined Object, it is considered to
    be flat. Errors are raised later on if that Object cannot be converted to a
    Tensor.

  Args:
    outputs: Output from `computation` inside `xla.compile`.

  Returns:
    A boolean indicates whether outputs is flat.
  __attrs_attrs__FT)r   r   r   Mappinghasattrr7   )rU   r   r"   r"   r&   r     s   

r   c              
   C   s   | du rt  } t| tjs| f} | t f7 } z	dd | D } W n ty4 } ztdt| d}~ww dd | D }dd | D }| || krMtdg }|D ]%}t	
|j
r[|j
nd |t| W d   n1 sqw   Y  qQ||fS )	zValidates flat outputs and adds back device assignments.

  Args:
    outputs: Output from `computation` inside `xla.compile`.

  Returns:
    Tensors and Operations extracted from outputs.
  Nc                 S   s&   g | ]}t |tjr|nt|qS r"   )r   r   r   r   r:   r   r"   r"   r&   r<     s    z-_postprocess_flat_outputs.<locals>.<listcomp>oXLA computation function return values must all either be Operations or convertible to Tensors. Got error: "%s"c                 S   s   g | ]
}t |tjr|qS r"   r   r   r   r   r"   r"   r&   r<         c                 S   s   g | ]
}t |tjs|qS r"   r   r   r"   r"   r&   r<     r   zdXLA computation function must return zero or more Tensor values followed by zero or more Operations. )tupler   r   r   r
   r   	Exceptionr`   strr   devicerG   r	   rV   )rU   eoutput_operationsr   new_output_tensorstr"   r"   r&   r     s<   
r   c                 C   s   g }t | D ]N}t|tjrtd|j zt|}W n ty1 } ztdt	| d}~ww t
|j
r:|j
nd |t| W d   n1 sPw   Y  q|g fS )a  Validates non-flat outputs and adds back device assignments.

  Args:
    outputs: Output from `computation` inside `xla.compile`.

  Returns:
    Tensors extracted from outputs and an empty list because Operations are not
    allowed in non-flat outputs..
  zxla.compile does not support Operation as return value in non-flat output structure. You can set returned Operations as control dependencies of returned Tensors so Operations are triggered when Tensors are evaluated. Operation found: "%s"r   Nr   )r   r   r   r   r   r`   r4   r   r   r   r   rG   r	   rV   )rU   r   r   r   r"   r"   r&   r     s.   r   c                  c   s.    t j} dd t _z	dV  W | t _dS | t _w )a  Enters a context where all summary ops are skipped.

  Summaries are not yet supported in xla.compile(). So we provide this context
  manager that can skip creating summary ops. This is a temporary workaround due
  to XLA not supporting summary ops.

  Yields:
    None.
  c                   S   s   dS )NTr"   r"   r"   r"   r&   <lambda>%  s    z*_disable_summary_context.<locals>.<lambda>N)r   skip_summary)original_skip_summary_funcr"   r"   r&   r     s   
r   c                   @   s(   e Zd ZdZdd Zdd Zdd ZdS )	_CapturedObjectz#A placeholder to capture an object.c                 C   s
   d | _ d S r    _objectry   r"   r"   r&   r-   0  s   
z_CapturedObject.__init__c                 C   s   | j rtd|| _ d S )NzFInternalError: _CapturedObject can capture only once. Please file bug.)r   RuntimeError)r3   r   r"   r"   r&   capture3  s
   
z_CapturedObject.capturec                 C   s   | j S r    r   ry   r"   r"   r&   ru   ;  s   z_CapturedObject.getN)r}   r~   r   r   r-   r   ru   r"   r"   r"   r&   r   -  s
    r   c           	      C   s   dd }|}|dur||j 7 }t| }t|j}|jdu r!d}nt|j}|| }||k rA|dkr<|jdu r<|d|S |d|S |jdu rX||krX|dkrS|d|S |d|S dS )a  Validate the number of input arguments to an XLA function.

  Args:
    func: the Python function that will be called to generate the body of an XLA
      computation graph.
    input_arity: the number of explicit arguments supplied by the caller.
    infeed_queue: if not None, the infeed queue that will supply
      additional arguments to the function.

  Returns:
    None if function can be called with the supplied number of
      arguments, or an error string if it cannot.
  c                 S   s   d| ||dkrdf S df S )Nz%s %d argument%s   r   rT   r"   )	complaintquantityr"   r"   r&   format_errorM  s
   z3check_function_argument_count.<locals>.format_errorNr   exactlyzat leastzat most)number_of_tuple_elementsr   
getargspecrA   argsdefaultsvarargs)	funcinput_arityinfeed_queuer   num_args_suppliedarg_specnum_func_argsnum_func_defaultsmin_func_argsr"   r"   r&   check_function_argument_count?  s&   








r   r    )0r   
contextlibtensorflow.compiler.jit.opsr   r   tensorflow.core.frameworkr   tensorflow.python.distributer   tensorflow.python.eagerr   r   tensorflow.python.frameworkr   tensorflow.python.opsr	   r
   r   tensorflow.python.platformr   r?   tensorflow.python.utilr   r   r   tensorflow.python.util.compatr   "tensorflow.python.util.deprecationr    tensorflow.python.util.tf_exportr   r]   r>   setrX   rZ   r*   XLAControlFlowContextr+   r!   r   r   r   contextmanagerr   objectr   r   r"   r"   r"   r&   <module>   sR   9 
6g*4#
