o
    ?e$                     @   s.  d Z ddlmZmZmZmZmZ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edef dedef deee  deej dedefddZ			ddededeejef f deeej  deej dedeej fddZdS )z<Library for constructing a training loop, suitable for TPUs.    )AnyCallableIterableListOptionalUnion)xla)ops)	array_ops)control_flow_ops)
while_loop)tensor_tracer)tpu_feed)tpu_function)coreN	condition.bodyinputsinfeed_queuenamereturnc           	   	      sP  ~|du rg ndd |D }dd |D t |t }|durPdu r:td ddd |D  d| td dd	d |D  d
j d| td}|durdu rqtd ddd |D  d| td ddd |D  d| dfdd} fdd}dkrtdg}tj|||dddS )a  Builds a training loop for TPUs.

  The set of loop-carried tensors corresponds to `inputs`.  Both
  `condition` and `body` take the current value of the loop-carried
  tensors. 'body' additionally takes a tuple of infeed from
  infeed_queue if infeed_queue is not None. `condition` must return a
  single boolean value that determines whether iteration
  continues. `body` must return an updated list of values for the
  loop-carried tensors.

  Args:
    condition: a Python function that builds the loop condition.
    body: a Python function that builds the loop body.
    inputs: a list of initial values passed into the training loop, or None
      (equivalent to an empty list).
    infeed_queue: if not None, the infeed queue from which to append a tuple of
      arguments as inputs to condition.
    name: (Deprecated) Does nothing.

  Returns:
    The final values of the loop-carried tensors.

  Raises:
    TypeError: if body or condition has the wrong signature.
  Nc                 S   s   g | ]}t |qS  )r	   convert_to_tensor.0xr   r   d/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/tensorflow/python/tpu/training_loop.py
<listcomp>?   s    zwhile_loop.<locals>.<listcomp>c                 S      g | ]}|j qS r   Zdtyper   r   r   r   r   A       zVSupplied loop body function cannot be called with the specified inputs. You specified z	 inputs: c                 S   r   r   r   r   ir   r   r   r   J   r    z, but the loop body needs c                 S   r   r   r!   r"   r   r   r   r   O   r    z and z: additional inputs from infeed, but the computation needs z[Supplied loop condition function cannot be called with the specified inputs. You specified c                 S   r   r   r!   r"   r   r   r   r   W   r    z, but the loop condition needs c                 S   r   r   r!   r"   r   r   r   r   \   r    z7. Note that infeed is not passed to the loop condition.c                     s   dkrg }  |  S )Nr   r   )r   )r   input_arityr   r   condition_wrapper`   s   z%while_loop.<locals>.condition_wrapperc            	         s@  t | } dkr
g } r(t j}|du rtd| dd  D }ng } | |  }t|t tfs:|f}dd |D }dd |D }dd |D }||| krYtd	d
d |D }|krlt	d
|||7 }|swtd}|rtj||d}tj rt j}|du rd}t }|t |d|}|S )zBWrapper around `body` that handles infeed queues and control deps.r   NzCan't build training loop with infeed when there is no tpu_shard_context. Are you building a loop or graph directly rather than from inside tpu.rewrite, tpu.batch_parallel, tpu.shard, or tpu.replicate?c                 S   s   g | ]}|qS r   r   )r   dr   r   r   r   w   s    z4while_loop.<locals>.body_wrapper.<locals>.<listcomp>c                 S   s&   g | ]}t |tjr|nt|qS r   )
isinstancer	   	Operationr   r   or   r   r   r      s    c                 S   s   g | ]
}t |tjr|qS r   r'   r	   r(   r)   r   r   r   r      s    c                 S   s   g | ]
}t |tjs|qS r   r+   r)   r   r   r   r      s    

zbTPU training loop body must return zero or more Tensor values followed by zero or more Operations.c                 S   r   r   r   )r   opr   r   r   r      r    zNMismatch between input types and output types for training loop body: {} vs {})Zcontrol_inputs   )listr   Zget_tpu_contextnumber_of_shards
ValueErrorZset_number_of_shardsZgenerate_dequeue_opr'   tuple	TypeErrorformatr
   constantr   r   ZTensorTracer
is_enabledZ	trace_tpur	   Zget_default_graph)	r   r/   Zdequeue_opsoutputsZoutput_operationsZoutput_tensorsZoutput_typesZnum_replicastt)r   r   r$   input_typesr   r   body_wrapperf   sZ   





z while_loop.<locals>.body_wrapperr    r-   )r   Zparallel_iterations)	lenr   Zcheck_function_argument_countr2   Znumber_of_tuple_elementsr
   r4   while_loop_tfr   )	r   r   r   r   r   Zbody_arg_errorZcondition_arg_errorr%   r9   r   )r   r   r   r$   r8   r   r      sz   J
r   nc                    sz   dd  fdd} fdd}|du rdgndg | }t |||||d	} |}t|d
kr7|d jS |d
d S )a  Builds a training loop that executes a fixed number of iterations.

  The set of loop-carried tensors correspond to `inputs`.
  `body` must be a function that takes and returns the values of the
  loop-carried tensors.

  Args:
    n: the number of loop iterations
    body: a Python function that builds the loop body.
    inputs: a list of initial values passed into the training loop or None
      (equivalent to an empty list).
    infeed_queue: if not None, the infeed queue from which to append a tuple of
      arguments as inputs to condition.
    name: (Deprecated) Does nothing.

  Returns:
    The final values of the loop-carried tensors.
  Raises:
    ValueError: if there is a type error.
  c                 S   s   t | ttfs
| gS t| S N)r'   r.   r1   )Zxsr   r   r   _convert_to_list   s   z repeat.<locals>._convert_to_listc                    s
   ~|  k S r>   r   r#   args)r=   r   r   cond   s   zrepeat.<locals>.condc                    s   | d g |  S )Nr-   r   r@   )r?   r   r   r   r9      s   zrepeat.<locals>.body_wrapperNr   )r   r   r   r-   )r   r;   r,   )r=   r   r   r   r   rB   r9   r6   r   )r?   r   r=   r   repeat   s   

rC   )NNN)__doc__typingr   r   r   r   r   r   Ztensorflow.python.compiler.xlar   Ztensorflow.python.frameworkr	   Ztensorflow.python.opsr
   r   r   r<   Ztensorflow.python.tpur   r   r   Ztensorflow.python.typesr   Z
core_typesZInfeedQueueintZ
TensorLikerC   r   r   r   r   <module>   sT    


 