o
    ?es                     @   s  d Z ddl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  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*dd  Z+d!d" Z,d#d$ Z-d%d& Z.G d'd( d(ej/Z0d)d* Z1			d>d+d,Z2d-d. Z3d/d0 Z4d1d2 Z5d3d4 Z6d5d6 Z7d7d8 Z8d9d: Z9d;ej: Z;d<d= Z<dS )?z$Tools for deserializing `Function`s.    N)logging)
trace_type)function_type)saved_object_graph_pb2)def_function)function)function_type_utils)
func_graph)function_def_to_graph)op_def_registry)ops)tensor)	type_spec)	array_ops)custom_gradient)default_gradient)resource_variable_ops)nested_structure_coder)compat)nest)tf_decorator)
tf_inspectc                 C   s   t | tjtjfS N)
isinstancer   ZTensorr   ZBaseResourceVariable)t r   w/home/www/facesmatcher.com/pyenv/lib/python3.10/site-packages/tensorflow/python/saved_model/function_deserialization.py
_is_tensor.   s   r   c           	      C   s   | j j}tj||dd}tj|dd}g }t||D ]"\}}t|tjr0|	t
j||jd qt|tjr<|	|j q| || j}t|t
jrLdS |S )a  Calls a restored Function with structured inputs.

  This differs from `function.__call__` in that inputs and outputs are
  structured and that it casts inputs to tensors if needed.

  Note: this does not checks that non-tensor inputs match. That should be
  done before via `_concrete_function_callable_with`.

  Args:
    function: ConcreteFunction to call.
    inputs: Structured inputs compatible with
      `function.graph.structured_input_signature`.

  Returns:
    The structured function output.
  T)Zexpand_composites
dtype_hintN)graphstructured_input_signaturer   flatten_up_toflattenzipr   r   
TensorSpecappendr   convert_to_tensordtyper   ZVariableSpechandleZ
_call_flatcaptured_inputsZ	Operation)	r   inputsexpected_structureflatten_inputsZflatten_expectedZtensor_inputsargexpectedresultr   r   r   _call_concrete_function5   s$   r1   c              	   C   sr   z,t jdd  tj| |d}tj|j|jdW  d   W S 1 s%w   Y  W dS  t	t
fy8   Y dS w )zDReturns None or TensorSpec obtained if `arg` is converted to tensor.Zguess_conversionnamer   )shaper(   N)func_graph_libZ	FuncGraph
as_defaultr   r'   r   r%   r4   r(   	TypeError
ValueError)r.   r   r0   r   r   r   _try_convert_to_tensor_specW   s   (r9   c              	   C   s   | j j}zt||}W n ttfy   Y dS w t|t|D ]Z\}}t|t	j
rU|r4t||jd}t|sAt|t	j
sA dS |j|jkrJ dS |j|jsT dS q!t|tjrd||sc dS q!t|rtt|t|krs dS q!||kr{ dS q!dS )z@Returns whether concrete `function` can be called with `inputs`.Fr   T)r    r!   r   r"   r7   r8   r$   r#   r   r   r%   r9   r(   r   r4   Zis_compatible_withr   ZTypeSpecid)r   r+   allow_conversionr,   r-   r.   r/   r   r   r    _concrete_function_callable_withb   s:   
r<   c              	   C   s   t | j}| js|jr"|jd dkr"|jstd|jdd }n|j}tj||j|j	|j
|j|j|jd}t | j}tjjjdtjjjdtjjjdi| j}tjj|||d	S )
z@Deserialize a FunctionSpec object from its proto representation.r   selfzECannot deserialize a method function without a named 'self' argument.   N)argsvarargsvarkwdefaults
kwonlyargskwonlydefaultsannotationsTF)fullargspecinput_signaturejit_compile)r   decode_protorF   Z	is_methodr?   NotImplementedErrorr   FullArgSpecr@   rA   rB   rC   rD   rE   rG   r   ZFunctionSpecZ
JitCompileDEFAULTONZOFFgetrH   r   Zfrom_fullargspec_and_signature)Zfunction_spec_protoZtypeless_fullargspecr?   rF   rG   rH   r   r   r   '_deserialize_function_spec_as_nonmethod   sJ   


rO   c           	      C   s   |du r	d| _ dS tdd |jj D }| j\}}t|dd | D |j	i |\}}t
| jj}tj|j |d}|| _ dS )z@Set the FunctionType of the ConcreteFunction using FunctionSpec.Nc                 S   s"   g | ]}t |j|j|jd qS r   )function_type_lib	Parameterr3   kindoptional).0pr   r   r   
<listcomp>   s    z4set_preinitialized_function_spec.<locals>.<listcomp>c                 S   s   i | ]
\}}t ||qS r   )rP   Zsanitize_arg_name)rT   kvr   r   r   
<dictcomp>   s    
z4set_preinitialized_function_spec.<locals>.<dictcomp>)return_annotation)_function_typerP   FunctionTyper   
parametersvaluesr!   Zcanonicalize_to_monomorphicitemsdefault_valuesr   
from_valuer    structured_outputs)	Zconcrete_fnspecZunconstrained_typeZ	arg_specsZkwarg_specsZinput_function_type_output_typer   r   r   r    set_preinitialized_function_spec   s0   


rf   c                 C   sD   || j  }| j|_| j|_| drt| j}t|| |	  |S )z1Makes a restored bare concrete function callable.function_spec)
concrete_function_nameZargument_keywords_arg_keywordsZallowed_positional_arguments_num_positional_argsZHasFieldrO   rg   rf   add_to_graph)Zsaved_bare_concrete_functionconcrete_functionsconcrete_functionrg   r   r   r   setup_bare_concrete_function   s   

rn   c                       s<   e Zd ZdZ fddZedd Zdd Zdd	 Z  Z	S )
RestoredFunctionzhWrapper class for a function that has been restored from saved state.

  See `def_function.Function`.
  c                    s:   t t| j||d|jd || _|j| _|j| _d| _	d S )NF)Z	autographrH   T)
superro   __init__rH   rl   r   r[   r`   Z_default_valuesZ_omit_frequent_tracing_warning)r=   Zpython_functionr3   rg   rl   	__class__r   r   rq      s   

zRestoredFunction.__init__c                 C      dS )NFr   r=   r   r   r   _run_functions_eagerly   s   z'RestoredFunction._run_functions_eagerlyc                 C      | j S r   rl   ru   r   r   r   _list_all_concrete_functions     z-RestoredFunction._list_all_concrete_functionsc                 C   rw   r   rx   ru   r   r   r   ._list_all_concrete_functions_for_serialization	  rz   z?RestoredFunction._list_all_concrete_functions_for_serialization)
__name__
__module____qualname____doc__rq   propertyrv   ry   r{   __classcell__r   r   rr   r   ro      s    
ro   c                    sl   t j} fdd}g }jD ]	}| |  q|D ]}t|| qt||j||}tj|||j	dS )aP  Creates a `Function` from a `SavedFunction`.

  Args:
    saved_function: `SavedFunction` proto.
    concrete_functions: map from function name to `ConcreteFunction`. As a side
      effect of this function, the `FunctionSpec` from `saved_function` is added
      to each `ConcreteFunction` in this map.

  Returns:
    A `Function`.
  c                     s   j std| |f}dD ])}j D ]#} | }tdd |jD r&tdt|||r5t||    S qqg }dd }tj D ]\}} | }	|	j\}
}|d	|d	 ||
| qBtd
||  d| dt
j  dtdtd | )zECalls a restored function or raises an error if no matching function.z2Found zero restored functions for caller function.)FTc                 S   s   g | ]}|d u qS r   r   rT   inpr   r   r   rV   8      zErecreate_function.<locals>.restored_function_body.<locals>.<listcomp>zLooks like you are trying to run a loaded non-Keras model that was trained using tf.distribute.experimental.ParameterServerStrategy with variable partitioning, which is not currently supported. Try using Keras to define your model if possible.c                 S   s    d t| ddd | D S )Nz)Positional arguments ({} total):
    * {}z
    * c                 s   s    | ]}t |V  qd S r   )pprintpformatrT   ar   r   r   	<genexpr>G      zgrecreate_function.<locals>.restored_function_body.<locals>._pretty_format_positional.<locals>.<genexpr>)formatlenjoin)
positionalr   r   r   _pretty_format_positionalD  s   zTrecreate_function.<locals>.restored_function_body.<locals>._pretty_format_positionalz'Option {}:
  {}
  Keyword arguments: {}r>   zUCould not find matching concrete function to call loaded from the SavedModel. Got:
  z
  Keyword arguments: z:

 Expected these arguments to match one of the following z option(s):


   )rl   r8   anyr*   r<   r1   	enumerater!   r&   r   r   chrr   )r?   kwargsr+   r;   Zfunction_namer   Zsignature_descriptionsr   indexrm   r   keywordrl   saved_functionr   r   restored_function_body*  sB   

z1recreate_function.<locals>.restored_function_body)Zdecorator_argspec)
rO   rg   rl   r&   rf   ro   r|   r   Zmake_decoratorrF   )r   rl   rg   r   Zconcrete_function_objectsrh   cfZrestored_functionr   r   r   recreate_function  s$   ,
r   c              	   C   s<  t dd | jD }i }i }t rt }nt }|du r&dt }i }i }	i }
| jD ]}|j	rLt
 }t|j	}|j||< ||	|< ||
|j< q/i }| jD ]}t|||||jj< qRi }t| |D ]}t||||	}d}d}|dur||jv r|j| }t|j}t|j}|  tj|||d}W d   n1 sw   Y  t||| || D ]	}|| | qd|jv r|jd= t |j!|j"|j#j$}t%j&j'|||jd}|r||}|| |||< |||j< t(dd |) D r|t  ||
v r|
| }||t|< t*|t+| qf|S )	a  Load a set of functions as concrete functions without captured inputs.

  Functions names are manipulated during load such that they do not overlap
  with previously created ones.

  Gradients are re-registered under new names. Ops that reference the gradients
  are updated to reflect the new registered names.

  Args:
    library: FunctionDefLibrary proto message.
    saved_object_graph: SavedObjectGraph proto message. If not passed in,
      concrete function structured signatures and outputs will not be set.
    load_shared_name_suffix: If specified, used to uniquify shared names.
      Otherwise, a unique name is generated.
    wrapper_function: An object that will be wrapped on newly created functions.

  Returns:
    Map of original function names in the library to instances of
    `ConcreteFunction` without captured inputs.

  Raises:
    ValueError: if functions dependencies have a cycle.
  c                 s   s    | ]}|j jV  qd S r   	signaturer3   rT   fdefr   r   r   r     s    z,load_function_def_library.<locals>.<genexpr>Nz_load_{})r!   rb   Z_input_shapes)attrsc                 s   s    | ]}|j d kV  qdS )ZTRTEngineOpN)type)rT   opr   r   r   r     r   ),setr   r   Z#executing_eagerly_outside_functionsZGraphZget_default_graphr   uidZregistered_gradientsZregistered_op_typer   Zgenerate_namer   as_bytesgradient_func_list_function_depsr   r3   _sort_function_defs_fix_fdef_in_placerl   r   rI   Zcanonicalized_input_signatureZoutput_signaturer6   function_def_libr
   _restore_gradient_functionsrk   attrrP   Zfrom_structured_signaturer!   rb   Zfunction_capturesZcapture_typesfunction_libZConcreteFunctionZfrom_func_graphr   get_operationsZRegisterGradient_gen_gradient_func)libraryZsaved_object_graphZload_shared_name_suffixZwrapper_functionlibrary_function_names	functionsrenamed_functionsr    library_gradient_namesnew_gradient_op_typesZgradients_to_registerZgdefZnew_op_typeZold_op_typefunction_depsr   loaded_gradients	orig_namer!   rb   protor	   depr   funcgradient_op_typer   r   r   load_function_def_libraryg  s   













r   c                    s    fdd}|S )zWraps a deserialized function.c                    s,   dd   fddt |jjD }| S )Nc                 S   sX   | d ur| S t |\}}| rt |S g }|jd ur&dd | D }t||S )Nc                 S   s   g | ]
}|d u r
dn|qS )Nr>   r   )rT   dr   r   r   rV     s    zS_gen_gradient_func.<locals>.gradient_func.<locals>.none_to_zero.<locals>.<listcomp>)r   Zshape_and_dtypeZis_fully_definedZ
zeros_likeZrankas_listr   Zzeros)xr   r4   r(   dimsr   r   r   none_to_zero  s   

z?_gen_gradient_func.<locals>.gradient_func.<locals>.none_to_zeroc                    s   g | ]	\}} ||qS r   r   )rT   r   r   r   r   r   rV     s    z=_gen_gradient_func.<locals>.gradient_func.<locals>.<listcomp>)r$   r    r+   )Z	unused_opZresult_gradsr   r   r   r     s
   
z)_gen_gradient_func.<locals>.gradient_funcr   )r   r   r   r   r   r     s   r   c              	   C   s   |   D ]A}|jdv r|t|jjd jj }| |_	z|
d}W n	 ty-   Y qw ||v rE|| }t|j|_dd |jD |_qdS )z@Populate function op's _gradient_function with default gradient.ZStatefulPartitionedCallZPartitionedCallf_gradient_op_typec                 S   s   g | ]}|j qS r   r2   r   r   r   r   rV   ,  s    z/_restore_gradient_functions.<locals>.<listcomp>N)r   r   r   r   node_defr   r   r3   Z_get_gradient_functionZ_gradient_functionZget_attrr8   r   r+   rj   ri   )r	   r   r   r   r   r   Zgrad_fnr   r   r   r     s"   

r   c                    s  t t}t dd  | D ]\}}|D ]}|| |  |  d7  < qq fdd| jD }g }|rZ| }|| || D ]}	 |	  d8  <  |	 sW||	 qD|s7t|t| jkrxtt	 
 t	| }
tdd|
 dd	d
 | jD fdd|D S )z5Return a topologic sort of FunctionDefs in a library.c                   S   rt   )Nr   r   r   r   r   r   <lambda>2  s    z%_sort_function_defs.<locals>.<lambda>r>   c                    s$   g | ]} |j j d kr|j jqS )r   r   r   )in_countr   r   rV   8  s    z'_sort_function_defs.<locals>.<listcomp>z0There is a cyclic dependency between functions. zCould not resolve .c                 S   s   i | ]}|j j|qS r   r   r   r   r   r   rY   K  s    z'_sort_function_defs.<locals>.<dictcomp>c                    s   g | ]} | qS r   r   )rT   r   )reverser   r   rV   L  r   )collectionsdefaultdictlistr_   r&   r   popr   sortedr   keysr8   )r   r   edgesfnamedepsr   readyoutputnodedestZfailed_to_resolver   )r   r   r   r   /  s6   




r   c                 C   s$   d| j v r| jdvr| j d jS dS )z$Returns the custom gradient op type.r   r   N)r   r   s)r   r   r   r   _get_gradient_op_typeO  s
   
r   c           	      C   sP  | j |v r|| j  j| _ | j D ]*\}}|ddkr&||jj j|j_q|ddkr;|jjD ]	}||j j|_q1q| j dkr[d| jvsL| jd js[d| jd _|dt	
 7 }t| j }|rtdd	 |jD d
}|rd
}d| jv r| jd jr| jd j}n|jjrt|jj}|st| j}|t| | jd _d
S d
S d
S )z7Replace functions calls and shared names in `node_def`.valuer   r   ZHashTableV2Zuse_node_name_sharingTz_{}c                 s   s    | ]
}|j d kr|V  qdS )shared_nameNr2   r   r   r   r   r   q  s    zfix_node_def.<locals>.<genexpr>Nr   )r   r3   r   r_   
WhichOneofr   r   br   r   r   r   rN   nextr   default_valuer   r   )	r   r   shared_name_suffixrd   
attr_valuefnZop_defr   r   r   r   r   fix_node_defW  s<   



r   c                 C   s   | j j}d}| jD ]"}t||| t|}|dur+||v r)t|| |jd _q	d}q	|r6t	
d| j j t| j j| j _|S )a  Fixes a FunctionDef proto to be loaded in current context.

  In particular, when loading a function library into an eager context, one
  must rename the functions to avoid conflicts with existent functions.

  Args:
    fdef: FunctionDef proto to fix. It is mutated in-place.
    functions: map from function name to a ConcreteFunction instance.
    shared_name_suffix: A unique string for this load which helps to avoid
      `shared_name` collisions across loads. Two functions from the same load
      using the same `shared_name` still need to share, but functions from
      different loads with the same `shared_name` should not.
    new_gradient_op_types: map from old gradient op type to newly generated op
      type.

  Returns:
    orig_name: original value of fdef.signature.name
  FNr   TznImporting a function (%s) with ops with unsaved custom gradients. Will likely fail if a gradient is requested.)r   r3   r   r   r   r   r   r   r   r   warning_clean_function_name)r   r   r   r   r   Z!contains_unsaved_custom_gradientsr   Zop_typer   r   r   r     s&   
r   c           	      C   s   t  }| jD ]M}t|}|j|v r||j q|r&||v r&|||  q|j D ]'\}}|ddkr>||jj	 q+|ddkrR|j
jD ]}||j	 qIq+q|S )z$Find functions referenced in `fdef`.r   r   r   )r   r   r   r   addr   r_   r   r   r3   r   )	r   r   r   r   r   Zgrad_op_typerd   r   r   r   r   r   r     s    

r   z^%s(.*)_\d+$c                 C   s   t t| }|r|dS | S )z:Vanity function to keep the function names comprehensible.r>   )research_FUNCTION_WRAPPER_NAME_REGEXgroup)r3   matchr   r   r   r     s   
r   )NNN)=r   r   r   r   Zabslr   Ztensorflow.core.functionr   Z%tensorflow.core.function.polymorphismr   rP   Ztensorflow.core.protobufr   Ztensorflow.python.eagerr   r   r   Z,tensorflow.python.eager.polymorphic_functionr   Ztensorflow.python.frameworkr	   r5   r
   r   r   r   r   r   Ztensorflow.python.opsr   r   r   r   Ztensorflow.python.saved_modelr   Ztensorflow.python.utilr   r   r   r   r   r1   r9   r<   rO   rf   rn   Functionro   r   r   r   r   r   r   r   r   r   Z_INFERENCE_PREFIXr   r   r   r   r   r   <module>   sb   "*&*[
 ! ()
