
    AVh4             
       |   d Z ddlZddlmZ ddlZddlZddl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l)m.Z. ddl)m/Z/ ddl0m1Z1 ddl0m2Z2 ddl0m3Z3 ddl4m5Z5 dd l6m7Z7 dd!l6m8Z8 dd"l9m:Z: dd#l;m<Z<  e:d$ e=       d%      Z> e:d& e=       d'      Z?	 e>j                   d( ZBd) ZC G d* d+eD      ZEe?j                         r$ ej                  d,d-d      rej                  d.z
  ZInd/ZId0ZJd1ZKd2ZLd3ZMd4 ZN e<d5g 6       G d7 d8 ej                  d8g d9                   ZP eP       ZQd:ZRdUd<ZSd= ZTddd;d;d>eJfd?ZU e7j                  dd@      	 	 	 	 dVdA       ZWdB ZX G dC dDeD      ZYdE ZZdF Z[ G dG dHe3j                        Z]dI Z^dWdJZ_dK Z`dL ZadM ZbdN Zc e<dOg 6       G dP dQeD             ZddReIeEj                  dSd;dRddddf
dTZfy# eA$ r Y *w xY w)Xz3Exposes the Python wrapper conversion to trt_graph.    N)partial)variable_pb2)
config_pb2)meta_graph_pb2)rewriter_config_pb2)session)utils)context)wrap_function)convert_to_constants)dtypeserrors)importer)ops)tensor)tf_optimizer)	array_ops)gen_resource_variable_ops)
tf_logging)builder)load)loader)save)signature_constants)tag_constants)asset)autotrackable)resource)saver)deprecation)nest)
LazyLoader)	tf_exportgen_trt_opsz/tensorflow.compiler.tf2tensorrt.ops.gen_trt_ops_pywrap_py_utilsz0tensorflow.compiler.tf2tensorrt._pywrap_py_utilsc                 `    t        | t        j                        r| j                  dd      S | S )z&Encode s if it is a sequence of chars.utf-8surrogateescaper   )
isinstance_six	text_typeencodess    _/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/python/compiler/tensorrt/trt_convert.py	_to_bytesr1   T   s)    4>>"88G$5866	
(    c                 \    t        | t        j                        r| j                  d      S | S )z&Decode s if it is a sequence of bytes.r(   )r*   r+   binary_typedecoder.   s    r0   
_to_stringr6   [   s&    4##$88G	
(r2   c                   (    e Zd ZdZdZdZed        Zy)TrtPrecisionModeFP32FP16INT8c                      t         j                  t         j                  t         j                  g} | | D cg c]  }|j	                          c}z   S c c}w N)r8   r9   r:   r;   lower)
precisionsps     r0   supported_precision_modesz*TrtPrecisionMode.supported_precision_modesg   sG     	/446F6K6KJ J7q7777s   AN)__name__
__module____qualname__r9   r:   r;   staticmethodrA    r2   r0   r8   r8   b   s#    	$	$	$8 8r2   r8         i   i   @RangeOptimalzRange+OptimalImplicitBatchModeCompatiblec                  .    t         t        t        t        gS r=   )PROFILE_STRATEGY_RANGEPROFILE_STRATEGY_OPTIMALPROFILE_STRATEGY_RANGE_OPTIMAL/PROFILE_STRATEGY_IMPLICIT_BATCH_MODE_COMPATIBLErF   r2   r0   supported_profile_strategiesrQ      s    6$5
 r2   z&experimental.tensorrt.ConversionParams)v1c                   D     e Zd ZdZeej                  ddddf fd	Z xZS )TrtConversionParamsa  Parameters that are used for TF-TRT conversion.

  Fields:
    max_workspace_size_bytes: the maximum GPU temporary memory that the TRT
      engine can use at execution time. This corresponds to the
      'workspaceSize' parameter of nvinfer1::IBuilder::setMaxWorkspaceSize().
    precision_mode: one of the strings in
      TrtPrecisionMode.supported_precision_modes().
    minimum_segment_size: the minimum number of nodes required for a subgraph
      to be replaced by TRTEngineOp.
    maximum_cached_engines: max number of cached TRT engines for dynamic TRT
      ops. Created TRT engines for a dynamic dimension are cached. If the
      number of cached engines is already at max but none of them supports the
      input shapes, the TRTEngineOp will fall back to run the original TF
      subgraph that corresponds to the TRTEngineOp.
    use_calibration: this argument is ignored if precision_mode is not INT8.
      If set to True, a calibration graph will be created to calibrate the
      missing ranges. The calibration graph must be converted to an inference
      graph by running calibration with calibrate(). If set to False,
      quantization nodes will be expected for every tensor in the graph
      (excluding those which will be fused). If a range is missing, an error
      will occur. Please note that accuracy may be negatively affected if
      there is a mismatch between which tensors TRT quantizes and which
      tensors were trained with fake quantization.
    allow_build_at_runtime: whether to allow building TensorRT engines during
      runtime if no prebuilt TensorRT engine can be found that can handle the
      given inputs during runtime, then a new TensorRT engine is built at
      runtime if allow_build_at_runtime=True, and otherwise native TF is used.
        Tc           	      6    t         t        |   | ||||||      S r=   )superrT   __new__)clsmax_workspace_size_bytesprecision_modeminimum_segment_sizemaximum_cached_enginesuse_calibrationallow_build_at_runtime	__class__s          r0   rY   zTrtConversionParams.__new__   s3     $!#;^24J-/EGGr2   )	rB   rC   rD   __doc__$DEFAULT_TRT_MAX_WORKSPACE_SIZE_BYTESr8   r9   rY   __classcell__ra   s   @r0   rT   rT      s/    > (L-22#$%&"%)
G 
Gr2   rT   r[   r\   r]   r^   r_   r`   TRTEngineOpFc                     t         j                         }| j                  |vr%t        dj	                  | j                  |            | j
                  dk  r| j
                  dk7  rt        d      yy)a8  Validate the provided TrtConversionParams.

  Args:
    conversion_params: a TrtConversionParams instance.
    is_v2: whether we're getting a RewriterConfig for TF 2.0.

  Raises:
    TypeError: if any of the parameters are of unexpected type.
    ValueError: if any of the parameters are of unexpected value.
  z;precision mode '{}' is not supported.It should be one of {}r   zQminimum segment size should be positive or -1 (to disable main graph conversion).N)r8   rA   r\   
ValueErrorformatr]   )conversion_paramsis_v2rA   s      r0   _check_conversion_paramsrn      s     /HHJ%%-FF

"#)6*;*J*J*C$EF F ,,1,,2
 ; < < 3 2r2   c                  f   t         j                         s t        j                  d       t	        d      t        j                         dk(  rt        j                  d       t         j                         } t         j                         }t        j                  dt        |              t        j                  dt        |             d }t        j                  dd	d	      s	 |d
|        t        j                  dd	d	      s	 |d|       |d	   | d	   k7  st        j                  |  sHt        j                  dt        j                  |      t        j                  |              t	        d      || k7  r>t        j                  dt        j                  |      t        j                  |              yy)zyCheck compatibility of TensorRT version.

  Raises:
    RuntimeError: if the TensorRT library version is incompatible.
  zVTensorflow needs to be built with TensorRT support enabled to allow TF-TRT to operate.z4Tensorflow has not been built with TensorRT support.WindowszWindows support is provided experimentally. No guarantee is made regarding functionality or engineering support. Use at your own risk.zLinked TensorRT version: %szLoaded TensorRT version: %sc                     | dv s
J d| z         t        j                  dj                  | t        j                  |                   t        d| z        )N)linkedloadedzMIncorrect value received for version_type: %s. Accepted: ['linked', 'loaded']zzThe {version_type} version of TensorRT: `{trt_version}` has now been removed. Please upgrade to TensorRT 7 or more recent.version_typetrt_versionz!Incompatible %s TensorRT versions)loggingerrorrk   	trt_utilsversion_tuple_to_stringRuntimeErrorrt   s     r0   raise_trt_version_deprecatedzF_check_trt_version_compatibility.<locals>.raise_trt_version_deprecated   sw       $	#$$ 
 MM	EEKV%!99+F FL FHI :\I
JJr2      r   rr   rs   a6  Loaded TensorRT %s but linked TensorFlow against TensorRT %s. A few requirements must be met:
	-It is required to use the same major version of TensorRT during compilation and runtime.
	-TensorRT does not support forward compatibility. The loaded version has to be equal or more recent than the linked version.z#Incompatible TensorRT major versionzLoaded TensorRT %s and linked TensorFlow against TensorRT %s. This is supported because TensorRT minor/patch upgrades are backward compatible.N)r&   is_tensorrt_enabledrw   rx   r{   platformsystemwarnget_linked_tensorrt_versionget_loaded_tensorrt_versioninfostrry   (is_linked_tensorrt_version_greater_equal(is_loaded_tensorrt_version_greater_equalrz   )linked_versionloaded_versionr|   s      r0    _check_trt_version_compatibilityr      so    
	-	-	/MM	 M
NN__)#LL	PQ $??A.#??A.	,,,c..AB	,,,c..ABK 
	;	;Aq!	D >:		;	;Aq!	D >:Q>!,,

<
<n
MMM	J 	)).9)).9; <
=='LL	 88H)).9	; (r2   Tc                    t        | |       |r||st        d      |s|t        d      ||r|t        d      ||st        |t              st        d      t	        j
                         }d|_        t        j                  ddd      xs t        j                  ddd      |_
        |s|j                  j                  g d	       t        j
                  j                  |_        |j                  j!                         }|sd
|j                  j!                         _        d|_        | j$                  |j&                  d   _        | j*                  |j&                  d   _        t-        | j.                        |j&                  d   _        | j2                  |j&                  d   _        | j4                  |j&                  d   _        ||j&                  d   _        | j8                  |j&                  d   _        |||j&                  d   _        ||j&                  d   _        |s+t-        |j;                               |j&                  d   _        |rt        j<                  |       |S )a  Returns a RewriterConfig proto for TRT transformation.

  Args:
    conversion_params: a TrtConversionParams instance.
    is_dynamic_op: whether to use dynamic engines.
    max_batch_size: maximum batch size for static engines.
    is_v2: whether we're getting a RewriterConfig for TF 2.0.
    disable_non_trt_optimizers: Turn off all default Grappler optimizers.
    use_implicit_batch: Whether to use implicit batch or explicit batch.
    profile_strategy: dynamic shape optimization profile strategy.

  Returns:
    A RewriterConfig proto which sets a TensorRTOptimizer to run Grappler.

  Raises:
    TypeError: if any of the parameters are of unexpected type.
    ValueError: if any of the parameters are of unexpected value.
  rm   z,is_dynamic_op is either None or True for TF2z#is_dynamic_op can't be None for TF1zJmax_batch_size has to be None for TF2 or when is_dynamic_op == True in TF1zCmax_batch_size has to be an integer for is_dynamic_op==False in TF1FrG   r   )pruningdebug_stripperlayout
dependency	constfoldcommon_subgraph_eliminationr   TensorRTOptimizerr]   r[   r\   r^   r_   is_dynamic_opr`   max_batch_sizeuse_implicit_batchprofile_strategy)rn   rj   r*   intr   RewriterConfig	remappingry   r   r   3experimental_disable_folding_quantization_emulation
optimizersextendONEmeta_optimizer_iterationscustom_optimizersaddnamer]   parameter_mapir[   r1   r\   r/   r^   r_   br`   r>   -disable_non_trt_optimizers_in_rewriter_config)	rl   r   r   rm   disable_non_trt_optimizersr   r   rewriter_config_with_trt	optimizers	            r0   _get_tensorrt_rewriter_configr     s   2 ,E:
}(
C
DD	=(
:
;;}.2L
 = > >}Zc>
MO O0??A (-$
 88AqA B88AqA 7 
$''.. 0  ((,, 4&88<<>)	#<G..2249&)."3"H"H 00 45709&&1()*+- %6$L$L   !.>> /<)/*,$5$L$L   !2@I,-/4F)./1 
4= 5"I./1
  ;; " 
"!r2   zBYou shouldn't need a rewriter_config with the current TF-TRT APIs.c                      t        | ||||      S r=   )r   )rl   r   r   rm   r   s        r0   get_tensorrt_rewriter_configr   u  s      
''8-'5u'A
C Cr2   c                 *    | j                  d      d   S )N/ri   )splitr   s    r0   _get_canonical_engine_namer     s    	C	r2   c                   z    e Zd ZdZddddddeej                  ddddfdZd Zd	 Z	d
 Z
d Zd Zd Z	 	 ddZd Zy)TrtGraphConvertera;  A converter for TF-TRT transformation for TF 1.x GraphDef/SavedModels.

  To run the conversion without quantization calibration (e.g. for FP32/FP16
  precision modes):

  ```python
  converter = TrtGraphConverter(
      input_saved_model_dir="my_dir",
      precision_mode=TrtPrecisionMode.FP16)
  converted_graph_def = converter.convert()
  converter.save(output_saved_model_dir)
  ```

  To run the conversion with quantization calibration:

  ```python
  converter = TrtGraphConverter(
      input_saved_model_dir="my_dir",
      precision_mode=TrtPrecisionMode.INT8)
  converter.convert()

  # Run calibration 10 times.
  converted_graph_def = converter.calibrate(
      fetch_names=['output:0'],
      num_runs=10,
      feed_dict_fn=lambda: {'input:0': my_next_data()})

  converter.save(output_saved_model_dir)
  ```
  NrV   rU   FTc                    t        j                         rt        d      |r|rt        d      |s|st        d      t	                || _        || _        || _        d| _        d| _	        |xs t        j                  g| _        |xs t        j                  | _        d| _        d| _        |t$        j&                  k(  xs! |t$        j&                  j)                         k(  xr || _        | j*                  r|
st-        j.                  d       d}
|
| _        |
rd| _        |8t-        j.                  d       n"t5        |t6              st        d	      || _        t9        |||	||d
      | _        t=        | j:                         d| _        y)a	  Initializes the converter.

    Args:
      input_saved_model_dir: the directory to load the SavedModel which contains
        the input graph to transforms. Used only when input_graph_def is None.
      input_saved_model_tags: list of tags to load the SavedModel.
      input_saved_model_signature_key: the key of the signature to optimize the
        graph for.
      input_graph_def: a GraphDef object containing a model to be transformed.
        If set to None, the graph will be read from the SavedModel loaded from
        input_saved_model_dir.
      nodes_denylist: list of node names to prevent the converter from touching.
      max_batch_size: max size for the input batch.
      max_workspace_size_bytes: the maximum GPU temporary memory which the TRT
        engine can use at execution time. This corresponds to the
        'workspaceSize' parameter of nvinfer1::IBuilder::setMaxWorkspaceSize().
      precision_mode: one of TrtPrecisionMode.supported_precision_modes().
      minimum_segment_size: the minimum number of nodes required for a subgraph
        to be replaced by TRTEngineOp.
      is_dynamic_op: whether to generate dynamic TRT ops which will build the
        TRT network and engine at run time.
      maximum_cached_engines: max number of cached TRT engines in dynamic TRT
        ops. If the number of cached engines is already at max but none of them
        can serve the input, the TRTEngineOp will fall back to run the TF
        function based on which the TRTEngineOp is created.
      use_calibration: this argument is ignored if precision_mode is not INT8.
        If set to True, a calibration graph will be created to calibrate the
        missing ranges. The calibration graph must be converted to an inference
        graph by running calibration with calibrate(). If set to False,
        quantization nodes will be expected for every tensor in the graph
        (excluding those which will be fused). If a range is missing, an error
        will occur. Please note that accuracy may be negatively affected if
        there is a mismatch between which tensors TRT quantizes and which
        tensors were trained with fake quantization.

    Raises:
      ValueError: if the combination of the parameters is invalid.
      RuntimeError: if this class is used in TF 2.0.
    z8Please use tf.experimental.tensorrt.Converter in TF 2.0.zACan only specify one of input_graph_def and input_saved_model_dirz=Must specify one of input_graph_def and input_saved_model_dirFNzrINT8 precision mode with calibration is supported with dynamic TRT ops only. Disregarding is_dynamic_op parameter.Tz6When is_dynamic_op==True max_batch_size should be Nonez=When is_dynamic_op==False max_batch_size should be an integerrf   ) r
   executing_eagerlyr{   rj   r   _input_graph_def_nodes_denylist_input_saved_model_dir
_converted_grappler_meta_graph_defr   SERVING_input_saved_model_tagsr   !DEFAULT_SERVING_SIGNATURE_DEF_KEY _input_saved_model_signature_key_calibration_graph_calibration_data_collectedr8   r;   r>   _need_calibrationrw   r   _is_dynamic_op_max_batch_sizer*   r   rT   _conversion_paramsrn   %_test_only_disable_non_trt_optimizers)selfinput_saved_model_dirinput_saved_model_tagsinput_saved_model_signature_keyinput_graph_defnodes_denylistr   r[   r\   r]   r   r^   r_   s                r0   __init__zTrtGraphConverter.__init__  s   h   "
DF F 0
MO O#8 / 0 0$&+D)D"7DDO$(D! 	9=#8#8"9 	  	( 	>== 	)
 #D',D$
,11
1 
;
,11779
9	P@O 	 mllHI m'D!d		#MN, & ' 	'+d1!9%15'#%D T44516D.r2   c                 B   t        j                         }t        | j                  | j                  | j
                  | j                  d      }|j                  j                  j                  |       t        j                  || j                  d      | _        d| _        y)z9Run Grappler's OptimizeGraph() tool to convert the graph.T)rl   r   r   r   r      tf_graphgraph_idN)r   ConfigProtor   r   r   r   r   graph_optionsrewrite_optionsCopyFromr   OptimizeGraphr   _converted_graph_defr   )r   grappler_session_configcustom_rewriter_configs      r0   _run_conversionz!TrtGraphConverter._run_conversion  s     )446:11))++#'#M#M! ))99BB  !- : :%%!D DOr2   c                 P   | j                   r| j                  j                  d   }|j                  j                  }| j                   D ][  }t        |t        j                        r%|j                  t        |j                               B|j                  t        |             ] y y )Ntrain_op)r   r   collection_def	node_listvaluer*   r   Tensorappendr1   r   )r   r   denylistr   s       r0   _add_nodes_denylistz%TrtGraphConverter._add_nodes_denylist1  s    44CCJOn))//h## (!a'
//)AFF+
,
//)A,
'	( r2   c                 P   t        j                         }|j                         5  t        j                  | j
                  d       ddd       t        j                  |j                  d      |      | _	        | j                          | j                          y# 1 sw Y   VxY w)zConvert the input GraphDef. r   NT
add_shapes	graph_defgraph)r   Graph
as_defaultr   import_graph_defr   r    export_meta_graphas_graph_defr   r   r   )r   r   s     r0   _convert_graph_defz$TrtGraphConverter._convert_graph_def;  s    IIKE				 @ 5 5B?@$)$;$;$$$5U%DD!@ @s   "BB%c                    t         j                  j                  t         j                  j                  t         j                  j                  t         j                  j
                  gz   }|D cg c]	  }||vs| c}S c c}w r=   )r   	GraphKeys_VARIABLE_COLLECTIONSTRAIN_OPWHILE_CONTEXTCOND_CONTEXT)r   collection_keyscollections_to_removekeys       r0   _collections_to_keepz&TrtGraphConverter._collections_to_keepF  sd     	++MM""CMM$?$?MM&&/
 	
 
 +OCc9N.NCOOOs   -	A>7A>c                    t        j                         }t        j                  |      5 }t	        j
                  || j                  | j                        }|j                  | j                     }d } ||j                        j                   ||j                              }| j                  |j                        D ]j  }|j                  j!                  |      D ]J  }t#        |t         j$                        s|j'                  |j(                  j+                  d      d          L l t-        j.                  ||j                  j1                  d      t3        |            }	t5        j6                         | _        | j8                  j:                  j=                  |	       | j                  |j                        D ]7  }| j8                  j                  |   j=                  |j                  |          9 | j?                          | j8                  j@                  j=                  |j@                         | j8                  j                  | j                     j=                  |       ddd       | jC                          y# 1 sw Y   xY w)zConvert the input SavedModel.)r   c                 j    | D ch c]#  }| |   j                   j                  d      d   % c}S c c}w )z%Get the node names from a TensorInfo.:r   )r   r   )tensor_infor   s     r0   _gather_namesz=TrtGraphConverter._convert_saved_model.<locals>._gather_names[  s1    ?JKC %%++C03KKKs   (0r   r   Tr   N)"r   r   r   Sessionr   r   r   r   signature_defr   inputsunionoutputsr   r   r   get_collectionr*   	Operationr   r   r   r   convert_variables_to_constantsr   listr   MetaGraphDefr   r   r   r   meta_info_defr   )
r   r   sessinput_meta_graph_definput_signature_defr   output_node_namescollection_keyopfrozen_graph_defs
             r0   _convert_saved_modelz&TrtGraphConverter._convert_saved_modelR  s8   IIKE	u	% )O#[[t/K/K)-)D)DF0>>

/
/1L
 ((;(B(BCII
+33
46 !55

-
-/ 9.**++N; 	9BCMM*!!"''--"4Q"78	99 .LL


''4'8
 
!# '5&A&A&Cd#
##--667GH !55

-
-/ A.%%44^DMM //?	AA
   ##11::

,
,.
##11

/
/119:M1NS)OX 	Y)O )Os   CJ;E/JJc                     | j                   rJ | j                  r| j                          | j                  S | j                          | j                  S )zVRun the TF-TRT conversion.

    Returns:
      The converted GraphDef for TF 1.x.
    )r   r   r   r  r   r   s    r0   convertzTrtGraphConverter.convert  sN     
 $$$ !$$$r2   c           
      V   | j                   sJ | j                  sJ | j                  rJ |r|s|s|st        d      |r] |       j	                         D ]E  \  }}t        |t              st        d      t        |t        j                        r<t        d       t        j                         | _        | j                  j                         5  t        j                  | j                  |r |       nd|d      }ddd       t!        j"                         }| j$                  rt'        j(                  |       t+        j,                  dt+        j.                  |      	      }	t1        j2                  | j                  |	
      5 }
t5        |      D ]  }|
j7                  |r |       nd         i }| j                  j                         5  t9        j:                  t<        j>                        }| j                  j@                  D ]  }|jB                  tD        k(  s|jF                  |vrR| j                  jG                  |jF                        5  tH        jK                  |      }ddd       ||jF                  <   |
j7                  ||jF                     |tM        |jN                        i      }||jP                  d   _)         	 ddd       d| _        ddd       | j                  S # 1 sw Y   xY w# 1 sw Y   xY w# 1 sw Y   =xY w# 1 sw Y   | j                  S xY w)a#  Run the calibration and return the calibrated GraphDef.

    Args:
      fetch_names: a list of output tensor name to fetch during calibration.
      num_runs: number of runs of the graph during calibration.
      feed_dict_fn: a function that returns a dictionary mapping input names (as
        strings) in the GraphDef to be calibrated to values (e.g. Python list,
        numpy arrays, etc). One and only one of `feed_dict_fn` and
        `input_map_fn` should be specified.
      input_map_fn: a function that returns a dictionary mapping input names (as
        strings) in the GraphDef to be calibrated to Tensor objects. The values
        of the named input tensors in the GraphDef to be calibrated will be
        re-mapped to the respective `Tensor` values during calibration. One and
        only one of `feed_dict_fn` and `input_map_fn` should be specified.

    Raises:
      ValueError: if the input combination is invalid.
      RuntimeError: if this method is called in eager mode.

    Returns:
      The GraphDef after the calibration.
    zAShould specify one and only one of feed_dict_fn and input_map_fn.z(Keys of input_map_fn must be of type strz0Values of input_map_fn must be of type tf.TensorNr   )	input_mapreturn_elementsr   T)r   )allow_soft_placementr   )r   config)	feed_dictcalibration_data)*r   r   r   rj   itemsr*   r   r   r   r   r   r   r   r   r   r   r   r   r   ry   r   r   r   GraphOptionsr   r   rangerunr   placeholderr   stringnoder  _TRT_ENGINE_OP_NAMEdevicer%   get_calibration_data_opr   r   attrr/   )r   fetch_namesnum_runsfeed_dict_fninput_map_fnkvfetchescalibrate_rewriter_cfgcalibrate_configcalibration_sess_device_to_get_resource_op_mapresource_name_inputr"  serialized_resources_outputcalibration_results                    r0   	calibratezTrtGraphConverter.calibrate  s   6 ???!!!!////|/;
MO O .&&( O$!Q!S!EF
F!V]]+MN
N	O "iikD		 	 	+	+	- ))

#
#&2LN%	g 1??A11==
 " "--! --245
 
%%
! &.$4X I!|~4 	 	II ')#""--/ A'33FMMB--22 	ADWW++ {{"??**11$++> N778KL ,N . ,DKK8 "2!5!5-dkk:')CDII)N "6 "
 /ADII()+%	AA. *.d&M&.P $$$y XN NA A&.P $$$sQ   -K/A	LAL 3LK<	)A"LL/K9<LLL	LL(c                    | j                   sJ | j                  r| j                  sJ | j                  rt	        d      d }t        j                  |      }t        j                         j                         5  t        j                  | j                  d        |t        j                         | j                  | j                  | j                  j                                t#        j$                         5 }|j'                  || j(                  | j                  j*                         ddd       ddd       |j-                          y# 1 sw Y   "xY w# 1 sw Y   &xY w)a  Save the converted graph as a SavedModel.

    Args:
      output_saved_model_dir: construct a SavedModel using the converted
        GraphDef and save it to the specified directory. This option only works
        when the input graph is loaded from a SavedModel, i.e. when
        input_saved_model_dir is specified and input_graph_def is None in
        __init__().

    Raises:
      ValueError: if the input to the converter is a GraphDef instead of a
      SavedModel.
    z:Not able to save to a SavedModel since input is a GraphDefc           	      d   d}|D ]  }|j                   |   }|j                  d      }|t        j                  d|       =t	        j
                  |      }|rk|dk(  rft	        j                  |      }|j                  j                  D ]7  }	 |       }
|
j                  |	       	  ||
|      }| j                  ||       9 t        ||      }|dk(  rM|j                  D ]<  }	t	        j                  |	|      }	 | j                  |      }| j                  ||       > |dk(  r.|j                  D ]  }	| j                  |t#        |	              P|j                  D ](  }	| j                  |t	        j                  |	|             *  y#  Y xY w# t        t        t         f$ r Y w xY w)	z*Restores collections that we need to keep.r   kindNz6Cannot identify data type for collection %s. Skipping.
bytes_list)import_scoper   
int64_list)r   
WhichOneofrw   rx   r   get_from_proto_functionget_collection_proto_typer:  r   ParseFromStringadd_to_collectiongetattrprepend_name_scopeas_graph_element	TypeErrorrj   KeyErrorr   )
dest_graphsrc_meta_graph_defr   scoper   r   r9  
from_proto
proto_typer   proto	new_valuefieldr   col_ops                  r0   _restore_collectionsz4TrtGraphConverter.save.<locals>._restore_collections  s   e  (Q#+::3?((0<
--FM
005
$,.44S9*%0066 9eLE!!%($U?i ((i89 .$/%[  8++E59d#44T: **378 |#  <**3E
;<  Q**3+.+A+A%+OQQM(Q   X6 s   %
F;FFF/.F/r   r   )signature_def_mapN)r   r   r   r   rj   r   SavedModelBuilderr   r   r   r   r   r   get_default_graphr   r   r   r   r   add_meta_graph_and_variablesr   r   r   )r   output_saved_model_dirrP  saved_model_builderr
  s        r0   r   zTrtGraphConverter.save  s<    ???----
FH H+Q\ "334JK				! K 9 9C



!4#@#@

#
#++::<=
 ?? K88((";;II 	9 	KKK K KK Ks%   :A?E93E,EE	EE")NN)rB   rC   rD   rb   rc   r8   r9   r   r   r   r   r   r  r  r6  r   rF   r2   r0   r   r     sp    @ &*&*/3#"(L.33$%"&'#m7^((	
P/b%  "!	h%TQr2   r   c                     t        j                  |      5  t        j                  |       cd d d        S # 1 sw Y   y xY w)N)resource_name)r   r$  r%   create_trt_resource_handle)r   r$  s     r0   _get_resource_handlerZ  M  s8    
zz& F111EF F Fs   6?c                    | j                   j                         }d}t        t        t	        |j
                  j                                    D ]  }|j
                  j                  |   }d|j                  j                  v s5|dz  }t        j                         j                  |j                  j                        rot        j                         j                  |j                  j                         t        j                         j                  |j                  j                        ro|j
                  j                  |=  t        j                  d| d       |j                  D ]  }|j                  dk(  s|j                   d= ! |j
                  j                  D ]0  }|j"                  D ]  }|j                  dk(  s|j                   d= ! 2 t%        | |      }|S )a8  Remove native segments from the input TF-TRT Converted Function.

  Args:
    input_func: provide the concrete function with native segment nodes. The
      transformed output func will not contain any native segment nodes. All the
      TRTEngineOp references will be deleted and reset to default empty func.
  r   native_segmentrV   z'Found and deleted native segments from z TRTEngineOp nodes.rg   segment_func)r   r   reversedr  lenlibraryfunction	signaturer   r
   has_functionremove_functionrw   r   r"  r  r&  node_def"_construct_function_from_graph_def)
input_funcr   nodes_deletedfunc_idfr"  funcnew_funcs           r0   _remove_native_segmentsrm  R  s    $$113/-%O$;$;$D$D EFG 4g((1A1;;+++qmOO**1;;+;+;<))!++*:*:; OO**1;;+;+;<

!
!
*
*7
34 
,,/	*, "" $dww-
))N
#$ %%.. &d &	M	!IIn%&&
 0
OL(	/r2   c                   8     e Zd ZdZ	 d fd	Zd Zd Zd Z xZS )_TRTEngineResourcez/Class to track the serialized engines resource.c                     t         t        |   |       || _        | j	                  t        j                  |      d      | _        || _        y )N)r$  !_serialized_trt_resource_filename)	rX   ro  r   _resource_name_track_trackabler   Asset	_filename_maximum_cached_engines)r   rX  filenamer^   r$  ra   s        r0   r   z_TRTEngineResource.__init__}  sJ    
 

d,F,;'D**HBDDN#9D r2   c                 B    t        | j                  | j                        S r=   )rZ  rr  _resource_devicer  s    r0   _create_resourcez#_TRTEngineResource._create_resource  s     3 3T5J5JKKr2   c                 p    t         j                  | j                  | j                  | j                         y )N)max_cached_engines_count)r%   initialize_trt_resourceresource_handleru  rv  r  s    r0   _initializez_TRTEngineResource._initialize  s.    ''!%!=!= ( ?r2   c                     t        | j                  | j                        }t        j                  | j                        5  t        j                  |d       d d d        y # 1 sw Y   y xY w)NT)ignore_lookup_error)rZ  rr  ry  r   r$  r   destroy_resource_op)r   handles     r0   _destroy_resourcez$_TRTEngineResource._destroy_resource  sT    !$"5"5t7L7LMF	D))	* ,33
d,, , ,s    A!!A*)GPU)	rB   rC   rD   rb   r   rz  r  r  rd   re   s   @r0   ro  ro  z  s     7 	
:L?,r2   ro  c                     d}t        |       D ]O  \  }}t        |      }||   }|dkD  r|dz   }dj                  ||z   |      }t        |      |kD  sE|d|dz
   dz   }Q  ||       y)	zPrints a row.r   r    z{0:{min_length}})
min_lengthNrH   z ...)	enumerater   rk   r_  )fields	positionsprint_fnliner   rN  end_line_poss          r0   
_print_rowr    s    	$F# 0haJEQ<L1uCZd$$TE\l$KD
4y<%L1$&/d0 4.r2   c                    || }|j                   j                  D ]  }t        j                         j                  |j                  j
                        s;t        j                         j                  |j                  j
                         t        j                         j                  |j                  j
                        ro |j                  j                  D ci c]'  }|d   j
                  j                  d      d   |d   ) }}t        j                  ||j                  D cg c]  }|j
                   c}|j                  D cg c]  }|j
                   c}|      }t        j                  | j                  j                   |j                  j                         |j                  _        | j"                  |_        | j&                  |j                  _        |S c c}w c c}w c c}w )z Rebuild function from graph_def.rV   r   r   )r`  ra  r
   rc  rb  r   rd  r   capturesr   r   function_from_graph_defr  r  r"   pack_sequence_asstructured_outputsfunction_type_function_typestructured_input_signature)rk  r   frozen_funcrj  cr  r   rl  s           r0   rf  rf    s   K
 %% :a
//

(
()9)9
:oo''(8(89 //

(
()9)9
::   ))
 diiooc1qt#(  22K,>,>?&&++?!,!4!45vv{{5xA( '+&;&;
jj##X^^%F%F'H(..# ..( 04/N/N(..+	/
 @5s   ,G$+G)
G.c                    | j                   j                         }|j                  j                  D ]  }d|j                  v s|j                  d=   t        j                  || j                         }dD ]  }g }|j                  d   j                  j                  D ]W  }t        j                         }|j                  |       |j                  d       |j                  |j                                Y ||j                  |   j                  j                  dd  t!        j"                         }| j$                  | j&                  z   D ]1  }	|j(                  j                  j                  |	j*                         3 |j                  d   j-                  |       t/        j0                         }
|
j2                  j4                  }d|_        |j8                  j                  d	       t;        j<                  |
|      }|S )
zBApply an inlining optimization to the function's graph definition.api_implementsr   )	variablesmodel_variablestrainable_variableslocal_variablesr  initializer_nameNr   ri   ra  )r   r   r`  ra  r&  r    r   r   r:  r   r   VariableDefr@  
ClearFieldr   SerializeToStringr   CollectionDefr  r  r   r   r   r   r   r   r   min_graph_nodesr   r   r   )rk  r   ra  
meta_graphr   raw_listrawvariablefetch_collectionarrayr  r   new_graph_defs                r0   _apply_inliningr    s   jj%%') ##,, *h8==(
--(
)* &&$**M* 	Cd H((5@@FF 4))+hs#,-ooh0023	4
 ;CJd#..44Q7	C $113{{T\\) 8e$$++EJJ78J'001AB !!#&((88/$&/!##J/,,VZ@-	r2   c                    i }t        | j                  j                  | j                        D ]  \  }}|j                  ||j
                  <     |j                  D ci c]  }|j
                  | }}|j                  D ]  }|j                  dk(  s|j                  dk(  s"|}||j                  d      j                  dk(  r2||j                  d      }||j                  d      j                  dk(  r2|j                  d   dz   }||v r<||   }	|j                  d   j                  j                  |	j                                t        dj                  |             yc c}w )	ae  Annotates variable operations with custom `_shape` attribute.

  This is required for the converters and shape inference. The graph
  definition is modified in-place.

  Args:
    func: Function represented by the graph definition.
    graph_def: Graph definition to be annotated in-place.

  Raises:
    RuntimeError: if some shapes cannot be annotated.
  ReadVariableOpResourceGatherr   Identityz:0_shapez&Not found in the function captures: {}N)zipr   internal_capturesr  shaper   r"  r  inputr&  r   as_protor{   rk   )
rk  r   ph_shape_mapphvarr"  name_to_nodenode_ph_namer  s
             r0   _annotate_variable_opsr    sK    ,TZZ114>>B &gb#IIL& /8nn=d$))T/=,=nn Fdww""dgg1A&AeQ(++z9U[[^, Q(++z9A%g	L	 W%		(!!**5>>+;<4;;GDF 	FF >s   E!c                 ,   	 t         j                  t        | j                              }|j	                         | j
                  d   _        y # t        j                  t        j                  f$ r# t        j                  d| j                         Y y w xY w)Nr  z Warning calibration error for %s)r%   r%  r   r   numpyr&  r/   r   UnknownErrorNotFoundErrorrw   warning)r"  calibration_tables     r0   _save_calibration_tabler    su    C#;;"499-/&7&=&=&?DII !#


v33	4 COO6		BCs   A
A ABBc                    	 t        | t              r9g }| j                         D ci c]  \  }}|t        j                  |       }}}nIi }t        | t
        t        f      rt        t        j                  |       }nt        j                  |       g}||fS c c}}w #  d}t        j                  |dj                  |       z          t        |      xY w)Nz"Failed to convert input to tensor.z
inp = `{0}`
)r*   dictr  r   convert_to_tensorr  tuplemaprw   rx   rk   r{   )inpargsr+  r,  kwargs	error_msgs         r0   _convert_to_tensorr  !  s    "#td8;		D13((++DfDf	C$	'3((#.%%c*+ 
v E"4IMM)/66s;;<
y
!!s   %B  BAB B 6Czexperimental.tensorrt.Converterc                       e Zd ZdZd Z ej                  ddd      dddddeej                  dddddfd	       Z
d
 Zd Zd Zd ZddZd Z	 	 ddZddZy)TrtGraphConverterV2ax  An offline converter for TF-TRT transformation for TF 2.0 SavedModels.

  Windows support is provided experimentally. No guarantee is made regarding
  functionality or engineering support. Use at your own risk.

  There are several ways to run the conversion:

  1. FP32/FP16 precision

     ```python
     params = tf.experimental.tensorrt.ConversionParams(
         precision_mode='FP16')
     converter = tf.experimental.tensorrt.Converter(
         input_saved_model_dir="my_dir", conversion_params=params)
     converter.convert()
     converter.save(output_saved_model_dir)
     ```

     In this case, no TRT engines will be built or saved in the converted
     SavedModel. But if input data is available during conversion, we can still
     build and save the TRT engines to reduce the cost during inference (see
     option 2 below).

  2. FP32/FP16 precision with pre-built engines

     ```python
     params = tf.experimental.tensorrt.ConversionParams(
         precision_mode='FP16',
         # Set this to a large enough number so it can cache all the engines.
         maximum_cached_engines=16)
     converter = tf.experimental.tensorrt.Converter(
         input_saved_model_dir="my_dir", conversion_params=params)
     converter.convert()

     # Define a generator function that yields input data, and use it to execute
     # the graph to build TRT engines.
     def my_input_fn():
       for _ in range(num_runs):
         inp1, inp2 = ...
         yield inp1, inp2

     converter.build(input_fn=my_input_fn)  # Generate corresponding TRT engines
     converter.save(output_saved_model_dir)  # Generated engines will be saved.
     ```

     In this way, one engine will be built/saved for each unique input shapes of
     the TRTEngineOp. This is good for applications that cannot afford building
     engines during inference but have access to input data that is similar to
     the one used in production (for example, that has the same input shapes).
     Also, the generated TRT engines is platform dependent, so we need to run
     `build()` in an environment that is similar to production (e.g. with
     same type of GPU).

  3. INT8 precision and calibration with pre-built engines

     ```python
     params = tf.experimental.tensorrt.ConversionParams(
         precision_mode='INT8',
         # Currently only one INT8 engine is supported in this mode.
         maximum_cached_engines=1,
         use_calibration=True)
     converter = tf.experimental.tensorrt.Converter(
         input_saved_model_dir="my_dir", conversion_params=params)

     # Define a generator function that yields input data, and run INT8
     # calibration with the data. All input data should have the same shape.
     # At the end of convert(), the calibration stats (e.g. range information)
     # will be saved and can be used to generate more TRT engines with different
     # shapes. Also, one TRT engine will be generated (with the same shape as
     # the calibration data) for save later.
     def my_calibration_input_fn():
       for _ in range(num_runs):
         inp1, inp2 = ...
         yield inp1, inp2

     converter.convert(calibration_input_fn=my_calibration_input_fn)

     # (Optional) Generate more TRT engines offline (same as the previous
     # option), to avoid the cost of generating them during inference.
     def my_input_fn():
       for _ in range(num_runs):
         inp1, inp2 = ...
         yield inp1, inp2
     converter.build(input_fn=my_input_fn)

     # Save the TRT engine and the engines.
     converter.save(output_saved_model_dir)
     ```
  4. To use dynamic shape, we need to call the build method with an input
     function to generate profiles. This step is similar to the INT8 calibration
     step described above. The converter also needs to be created with
     use_dynamic_shape=True and one of the following profile_strategies for
     creating profiles based on the inputs produced by the input function:
     * `Range`: create one profile that works for inputs with dimension values
       in the range of [min_dims, max_dims] where min_dims and max_dims are
       derived from the provided inputs.
     * `Optimal`: create one profile for each input. The profile only works for
       inputs with the same dimensions as the input it is created for. The GPU
       engine will be run with optimal performance with such inputs.
     * `Range+Optimal`: create the profiles for both `Range` and `Optimal`.
  c                     t               D cg c]  }|j                          }}|j                         |vr#t        dj                  |t                           |dk(  rt	        j
                  d       y y c c}w )Nz>profile_strategy '{}' is not supported. It should be one of {}rK   zImplicitBatchModeCompatible strategy is deprecated, and using it may result in errors during engine building. Please consider using a different profile strategy.)rQ   r>   rj   rk   rw   r   )r   strategyr/   supported_strategiess       r0   _verify_profile_strategyz,TrtGraphConverterV2._verify_profile_strategy  sv    /K/MN!AGGINN~~33KF89;<> > 00ll:; 1 Os   A7Nz+Use individual converter parameters insteadrl   rU   rV   Tc                 T   t        j                         sJ |t        ||||	|
|      }t                t	        |d       || _        || _        |xs t        j                  g| _	        |xs t        j                  | _        t        j                  d       | _        |j                   t"        j$                  k(  xs+ |j                   t"        j$                  j'                         k(  xr |j(                  | _        d| _        d| _        d| _        d| _        d| _        |d| _        n|| _        | j                  s(| j6                  st9        j:                  d       d| _        d| _        | j6                  r-|t>        | _        d| _!        y| jA                  |       || _        d| _!        y)	a
  Initialize the converter.

    Args:
      input_saved_model_dir: the directory to load the SavedModel which contains
        the input graph to transforms. Required.
      input_saved_model_tags: list of tags to load the SavedModel.
      input_saved_model_signature_key: the key of the signature to optimize the
        graph for.
      use_dynamic_shape: whether to enable dynamic shape support. None is
        equivalent to False in the current implementation.
      dynamic_shape_profile_strategy: one of the strings in
        supported_profile_strategies(). None is equivalent to Range in the
        current implementation.
      max_workspace_size_bytes: the maximum GPU temporary memory that the TRT
        engine can use at execution time. This corresponds to the
        'workspaceSize' parameter of nvinfer1::IBuilder::setMaxWorkspaceSize().
      precision_mode: one of the strings in
        TrtPrecisionMode.supported_precision_modes().
      minimum_segment_size: the minimum number of nodes required for a subgraph
        to be replaced by TRTEngineOp.
      maximum_cached_engines: max number of cached TRT engines for dynamic TRT
        ops. Created TRT engines for a dynamic dimension are cached. If the
        number of cached engines is already at max but none of them supports the
        input shapes, the TRTEngineOp will fall back to run the original TF
        subgraph that corresponds to the TRTEngineOp.
      use_calibration: this argument is ignored if precision_mode is not INT8.
        If set to True, a calibration graph will be created to calibrate the
        missing ranges. The calibration graph must be converted to an inference
        graph by running calibration with calibrate(). If set to False,
        quantization nodes will be expected for every tensor in the graph
        (excluding those which will be fused). If a range is missing, an error
        will occur. Please note that accuracy may be negatively affected if
        there is a mismatch between which tensors TRT quantizes and which
        tensors were trained with fake quantization.
      allow_build_at_runtime: whether to allow building TensorRT engines during
        runtime if no prebuilt TensorRT engine can be found that can handle the
        given inputs during runtime, then a new TensorRT engine is built at
        runtime if allow_build_at_runtime=True, and otherwise native TF is used.
      conversion_params: a TrtConversionParams instance (deprecated).

    Raises:
      ValueError: if the combination of the parameters is invalid.
    Nrf   Tr   disable_graph_freezingFzZDisabling graph freezing is only possible in dynamic shape mode. The graph will be frozen.Unknown)"r
   r   rT   r   rn   r   r   r   r   r   r   r   r   ry   !is_experimental_feature_activatedfreezer\   r8   r;   r>   r_   r   _calibration_input_fnr   _device_build_called_once_calibrated_use_dynamic_shaperw   r   _profile_strategyrM   r  r   )r   r   r   r   use_dynamic_shapedynamic_shape_profile_strategyr[   r\   r]   r^   r_   r`   rl   s                r0   r   zTrtGraphConverterV2.__init__  s   v $$&&& -#;'3!7)!79 %&.d;/D"7D9=#8#8"9 	  	( 	>== 	)  AA " "DK 
	)	)-=-B-B	B 	L		)	)-=-B-B-H-H-J	J@ 0?? 	
 "&DDODL#DD  %d 1d;;t66ll'( dk&D	'	/!7 27D.	 	%%&DE!? 27D.r2   c                     | j                   S r=   )r  r  s    r0   _need_trt_profilesz&TrtGraphConverterV2._need_trt_profiles  s    """r2   c                 8   t        j                         }t        | j                  j	                  d      dd| j
                  | j                   | j                        }|j                  j                  j                  |       t        j                  ||d      S )zRun Grappler's OptimizeGraph() tool to convert the graph.

    Args:
      meta_graph_def: the MetaGraphDef instance to run the optimizations on.

    Returns:
      The optimized GraphDef.
    T)r`   N)rl   r   r   r   r   r   r   r   )r   r   r   r   _replacer   r  r  r   r   r   r   r   )r   meta_graph_defr   r   s       r0   r   z#TrtGraphConverterV2._run_conversion  s     )446:11::#' ; )#'#M#M#666//1 ))99BB %%+G Gr2   c                     |j                   D ]  }|j                  t        k(  s ||         |j                  j                  D ]/  }|j
                  D ]  }|j                  t        k(  s ||         1 y)z;Helper method to manipulate all TRTEngineOps in a GraphDef.N)r"  r  r#  r`  ra  re  )r   r   fnr"  rk  s        r0   _for_each_trt_nodez&TrtGraphConverterV2._for_each_trt_node7  sm     	'	'
4 !!** -- $77))
T(r2   c                      |       D ]"  }t        |      \  }} | j                  |i | $ | j                  | j                  t               t        | j                  | j                        | _        d| _        y)z@Run INT8 calibration with the provided input generator function.TN)r  _converted_funcr  r   r  rf  r  )r   calibration_input_fnr  r  r  s        r0   _execute_calibrationz(TrtGraphConverterV2._execute_calibrationA  sx    #% ,',ldFdD+F+, 	D557NO >d779DDr2   c                 4   | j                   rJ t        j                  g       j                  }d|j	                         vrt        d|       d|j	                         vr6|| _        t        j                  d| j                   d| j                          | j                  r|st        d      | j                  s|rt        d      t        j                  | j                  | j                        | _        | j                  j                  | j                     }| j                   rt#        j$                  |      }n#t'        |      }t)        ||       t+        ||      }|j,                  j/                         }t        j                  d       |j0                  D ]	  }d	|_         | j                  "t3        j4                  ||j,                        }nt7        j8                         j;                         5 }	t7        j                  | j                        5  t=        j>                  |d	       t3        j4                  |	j/                         |	      }d
d
d
       d
d
d
       tA        jB                         }
|jD                  |jF                  z   D ]1  }|
jH                  jJ                  jM                  |jN                         3 jP                  d   jS                  |
       | jU                  |      | _+        t+        || jV                  |      | _,        | j                  r)| j[                         s| j]                  |       n|| _/        d| _         t`        jb                  je                  dd
      }|H	 tg        jh                  | jX                  j,                  j/                  d      |       | jX                  S | jX                  S # 1 sw Y   vxY w# 1 sw Y   {xY w# tj        $ r-}t        jl                  d|        Y d
}~| jX                  S d
}~ww xY w)a  Convert the input SavedModel in 2.0 format.

    Args:
      calibration_input_fn: a generator function that yields input data as a
        list or tuple or dict, which will be used to execute the converted
        signature for calibration. All the returned input data should have the
        same shape. Example: `def input_fn(): yield input1, input2, input3`

        If dynamic_shape_mode==False, (or if the graph has static input shapes)
        then we run calibration and build the calibrated engine during
        conversion.

        If dynamic_shape_mode==True (and the graph has any unknown input
        shape), then the reference to calibration_input_fn is stored, and the
        calibration is actually performed when we build the engine (see
        build()).

    Raises:
      ValueError: if the input combination is invalid.

    Returns:
      The TF-TRT converted Function.
    gpuzSpecified device is not a GPU: zgpu:0zPlacing imported graph from `z` on device: zFShould specify calibration_input_fn because INT8 calibration is neededzNShould not specify calibration_input_fn because INT8 calibration is not neededz7Clearing prior device assignments in loaded saved modelr   Nr   r   r   TTF_TRT_EXPORT_GRAPH_VIZ_PATH)defaultr   )graphdefdot_output_filenamezDAn Exception occurred during the export of the graph visualization: )7r   r   zerosr$  r>   rj   r  rw   r   r   r   r   r   _saved_model
signaturesr   r  r   !convert_variables_to_constants_v2r  r  rf  r   r   r"  r    r   r   r   r   r   r   r   r  r  r  r   r   r   r   r   r   r   r   r  r  r  r  osenvirongetry   draw_graphdef_as_graphviz	Exceptionrx   )r   r  device_requestedrk  r  inlined_graph_defr  r"  grappler_meta_graph_defr   r  r  graphviz_pathes                 r0   r  zTrtGraphConverterV2.convertP  s   0  !r*11$**,,89I8JKLL&,,..%dlll 223=P Q 	'; / 0 0""'; 3 4 4 		$"="="&">">@D''(M(MND{{(JJ4Pk)$/T#456t=NOk"((557 LLJK %% dk || % 7 7$K,=,=!? 99;!!# 9ucjj.F 9!!"2<"'"9"9((*%#99 9 &335##k&9&99 :  &&--ejj9:**:6?? !% 4 45L MD=d''6D $$&!!"67%9"DOJJNN#A4NPM 
++))//<<<M -	/ 4M9 9 9 9@  
S"	
 	

 
s<   6 O=OO4;O! O	OO!	P*PPc                 $   | j                   rt        d      |st        d      | j                  st        d      | j                  r#| j
                  s| j                  t        d      d }| j                         rG| j                  | j                  t        |d             t        | j                  | j                        }n| j                  }d} |       D ]  }||}t        |      \  }} ||i |  | j                         r&| j                  | j                  t        |d             | j                  r/| j
                  s#| j                  | j                         d| _         yt        |      \  }} | j                  |i | d| _         y)	a  Run inference with converted graph in order to build TensorRT engines.

    If the conversion requires INT8 calibration, then a reference to the
    calibration function was stored during the call to convert(). Calibration
    will be performed while we build the TensorRT engines.

    Args:
      input_fn: a generator function that provides the input data as a single
        array, OR a list or tuple of the arrays OR a dict, which will be used
        to execute the converted signature to generate TRT engines.
        Example 1:
        `def input_fn():
             # Let's assume a network with 1 input tensor.
             # We generate 2 sets of dummy input data:
             input_shapes = [(1, 16),    # 1st shape
                             (2, 32)]    # 2nd shape
             for shapes in input_shapes:
                 # return an input tensor
                 yield np.zeros(shape).astype(np.float32)'

        Example 2:
        `def input_fn():
             # Let's assume a network with 2 input tensors.
             # We generate 3 sets of dummy input data:
             input_shapes = [[(1, 16), (2, 16)], # 1st input list
                             [(2, 32), (4, 32)], # 2nd list of two tensors
                             [(4, 32), (8, 32)]] # 3rd input list
             for shapes in input_shapes:
                 # return a list of input tensors
                 yield [np.zeros(x).astype(np.float32) for x in shapes]`

    Raises:
      NotImplementedError: build() is already called.
      RuntimeError: the input_fx is None.
    zNbuild() is already called. It is not supported to call build() more than once.zbinput_fn is None. Method build() needs input_fn to be specified in order to build TensorRT enginesz%Need to call convert() before build()NzENeed to provide the calibration_input_fn arg while calling convert().c                 ,    | |j                   d   _        y )N_profile_generation_moder&  r   )r   r"  s     r0   _set_profile_generation_modez?TrtGraphConverterV2.build.<locals>._set_profile_generation_mode  s    05dii*+-r2   TF)r  NotImplementedErrorr{   r   r   r  r  r  r  r   r   rf  r  r  r  )r   input_fnr  rk  first_inputr  r  r  s           r0   buildzTrtGraphConverterV2.build  s   H  !L M M N O O??@AAt'7'7""* . / /6  
d77%&BDIK
 00D0D040I0IKd !!dK z 		',ldF
DF	  
d77%&BEJL
 d&6&6
 : :; #D (4ldFdD+F+"Dr2   c                    
  j                   sJ t        j                  d      rXt        j                  d       t         j                         _         j                  j                  j                          _	         j                  r j                  st        d      t        j                         
i 
 fd} j                   j                  |        j                   rt#        j$                         n j&                  }|_         j*                  j,                  sd } j                   j                  |       t/        j0                   j                   j                  j2                  D cg c]  }|j4                   c} j                  j6                  D cg c]  }|j4                   c}      }t9        j:                   j                  j                  j<                  |j                  j<                        |j                  _         j                  j>                  |j                  _        | _         j@                   j                  i}	tC        jB                  |||	|       yc c}w c c}w )a  Save the converted SavedModel.

    Args:
      output_saved_model_dir: directory to saved the converted SavedModel.
      save_gpu_specific_engines: whether to save TRT engines that have been
        built. When True, all engines are saved and when False, the engines
        are not saved and will be rebuilt at inference time. By using
        save_gpu_specific_engines=False after doing INT8 calibration, inference
        can be done on different GPUs than the GPU that the model was calibrated
        and saved on.
      options: `tf.saved_model.SaveOptions` object for configuring save options.
    Raises:
      RuntimeError: if the needed calibration hasn't been done.
    remove_native_segmentsz_'remove_native_segments' experimental feature is enabled during saving of converted SavedModel.zA model that requires INT8 calibration has to be built before saving it. Call build() to build and calibrate the TensorRT engines.c                 Z   t        | j                        }|v ryt        j                  j	                  d|z         }	 t
        j                  ||d       t        ||j                  j                        |<   y# t        j                  $ r t        j                  d|       Y yw xY w)z2Serialize TRT engines in the cache and track them.Nztrt-serialized-engine.T)rX  rw  delete_resourcesave_gpu_specific_engineszCould not find %s in TF-TRT cache. This can happen if build() is not called, which means TensorRT engines will be built and cached at runtime.)r   r   r  pathjoinr%   serialize_trt_resourcer   r  rw   r   ro  r   r^   )r"  canonical_engine_namerw  engine_asset_dirresource_mapr  r   s      r0   _serialize_and_track_enginez=TrtGraphConverterV2.save.<locals>._serialize_and_track_engineD  s     9C	,	..69NNPh**/ &?	 	+ 	A -?


!
!
8
8-:l() !! % '<		=
 	s    A> >)B*)B*c                 ,    d| j                   d   _        y )NF_allow_build_at_runtimer  )r"  s    r0   _reset_allow_build_at_runtimez?TrtGraphConverterV2.save.<locals>._reset_allow_build_at_runtimen  s    16		+,.r2   )optionsN)"r   ry   r  rw   r   rm  r  r   r   r   r   r  r{   tempfilemkdtempr  r  r   AutoTrackabler  trt_engine_resourcesr   r`   r   r  r  r   r  r"   r  r  r  r   r   )r   rU  r  r  r  	trackabler  r   reset_converted_funcr  r  r  s   ` `       @@r0   r   zTrtGraphConverterV2.save  s   $ ??? 223KLll4 5T5I5IJd"&"6"6"<"<"I"I"Kdd&6&6 ; < <
  '')L:: 	D5579 
 ++ ++ %1I" ""997 d77;= +BB

#
#%)%9%9%@%@
A66;;
A%)%9%9%A%A
B66;;
BD 7;6K6K



$
$
7
7

$
$
7
779  3 


9
9   ;1d 779M9MNJIIi/WM B
Bs   8I4
%I9c                    | j                   s:t        d| j                  j                   d| j                  j                   d      |dk  rt	        d| d      |t
        }g d}|D cg c]  \  }}t        ||z         }}}t        j                  |      j                         }|D cg c]  \  }}|	 }	}}t        |	||	        |d
|z         d}
d}d}| j                  j                  j                  d      }t               }|j                  D ]+  }|j                   dk7  r|dz  }|||j"                  <   |
dz  }
- t%        |j'                               D ]1  \  }}|j(                  j+                  d      d   }t-        j.                  |d      }t-        j.                  |d      }t-        j0                  |d      }t-        j0                  |d      }t-        j2                  |d      }t-        j2                  |d      }t-        j4                  ||      \  }}||z  }|
dk7  r |dd d       t        |||||||||g	||       |s |        t%        t        |      j'                               D ]  \  }} |d| d| d        4  |dd
|z           |d|
        ||z   }||z  dz  } |d|dd | d| d!       yc c}}w c c}}w )"a  This method describes the results of the conversion by TF-TRT.

    It includes information such as the name of the engine, the number of nodes
    per engine, the input and output dtype, along with the input shape of each
    TRTEngineOp.

    Args:
      line_length: Default line length when printing on the console. Minimum 160
        characters long.
      detailed: Whether or not to show the nodes inside each TRTEngineOp.
      print_fn: Print function to use. Defaults to `print`. It will be called on
        each line of the summary. You can set it to a custom function in order
        to capture the string summary.

    Raises:
      RuntimeError: if the graph is not converted.
    zImpossible to call `z.summary()` before calling z.convert()`.   z/Invalid `line_length` value has been received: z. Minimum: 160.N)	)zTRTEngineOP Nameg?)Device
ףp=
?)z# Nodesg?)z# Inputsr%  )z	# Outputsr%  )zInput DTypesQ?)zOutput Dtypesr&  )zInput Shapesr&  )zOutput Shapesr&  )r  =r   Tr   rg   rV   r   ri   input_shapes_output_shapesInTOutT
z(----------------------------------------)r  r  r  z	- z: xz&[*] Total number of TensorRT engines: d   z[*] % of OPs Converted: z.2fz% [z]
)r   r{   ra   rB   rj   printr   npcumsumtolistr  r  r   r   r  r"  r  r   sortedr  r$  r   ry   get_node_io_shapesget_trtengineop_io_dtypesget_trtengineop_io_nodes_countget_trtengineop_node_op_count)r   line_lengthdetailedr  columnsr1  r@   r  hheaders	n_enginesn_ops_convertedn_ops_not_convertedr  trtengineops_dictr"  r   node_device	in_shapes
out_shapes	in_dtypes
out_dtypesin_nodes_countout_nodes_count
node_countconverted_ops_dictr   r   	total_opsconversion_ratios                                 r0   summaryzTrtGraphConverterV2.summary  s2   $ ?? !8!8 9 :^^,,-\;< < SH%o7 8 8 h
G 3::$!Q[1_%:I:		)$++-I$%TQq%G%w	H5S;IO##))66$6GH 	M	!q '+$))$Q	 .4467 +
dKK%%c*2.k..t^Di//6FGj55dEBi66tVDj ??eLn!@@vNo'0'N'N
D($j$ #o	a2fXR!K^_Y
  

 &8!9!?!?!AB 	+JC
T#bq)
*	+5+: r#k/"#$5i[AB#o5I&2S8'(8'= > !9+S2 3o ;%s   ,K/Kr=   )TN)r#  TN)rB   rC   rD   rb   r  r!   deprecated_argsrc   r8   r9   r   r  r   r  r  r  r  r   rL  rF   r2   r0   r  r  4  s    dL
; ;tL24 &*&*/3!%.2(L.33$%&'#&*!%o74o7b#G0f P]#B &*jNXf3r2   r  rV   rU   c                 z    t        ||	|
| |||||||d      }|j                         }|r|j                  |       |S )a  Python wrapper for the TRT transformation.

  Args:
    input_graph_def: a GraphDef object containing a model to be transformed. If
      set to None, the graph will be read from the SavedModel loaded from
      input_saved_model_dir.
    outputs: list of tensors or node names for the model outputs. Only used when
      input_graph_def is not None.
    max_batch_size: max size for the input batch.
    max_workspace_size_bytes: the maximum GPU temporary memory which the TRT
      engine can use at execution time. This corresponds to the 'workspaceSize'
      parameter of nvinfer1::IBuilder::setMaxWorkspaceSize().
    precision_mode: one of TrtPrecisionMode.supported_precision_modes().
    minimum_segment_size: the minimum number of nodes required for a subgraph to
      be replaced by TRTEngineOp.
    is_dynamic_op: whether to generate dynamic TRT ops which will build the TRT
      network and engine at run time.
    maximum_cached_engines: max number of cached TRT engines in dynamic TRT ops.
      If the number of cached engines is already at max but none of them can
      serve the input, the TRTEngineOp will fall back to run the TF function
      based on which the TRTEngineOp is created.
    input_saved_model_dir: the directory to load the SavedModel which contains
      the input graph to transforms. Used only when input_graph_def is None.
    input_saved_model_tags: list of tags to load the SavedModel.
    input_saved_model_signature_key: the key of the signature to optimize the
      graph for.
    output_saved_model_dir: if not None, construct a SavedModel using the
      returned GraphDef and save it to the specified directory. This option only
      works when the input graph is loaded from a SavedModel, i.e. when
      input_saved_model_dir is specified and input_graph_def is None.

  Returns:
    A GraphDef transformed from input_graph_def (or the SavedModel graph def
    loaded from input_saved_model_dir, if input_graph_def is not present), where
    all TRT compatible subgraphs are replaced with TRTEngineOps, and a TF
    function is added for each of the subgraphs.

    If is_dynamic_op is True, each TRTEngineOp will contain a serialized
    subgraph GraphDef, which will be converted to a TRT engine at execution time
    and the TRT engine will be cached for future usage. A new TRT engine will be
    created each time when none of the cached engines match the input shapes. If
    it fails to execute the TRT engine or the number of cached engines reaches
    maximum_cached_engines, the op will fall back to call the corresponding TF
    function.

    If is_dynamic_op is False, each TRTEngineOp will contain a serialized TRT
    engine created from the corresponding subgraph. No more engines will be
    created on the fly, and the op will fall back to call the corresponding TF
    function when it fails to execute the engine.

  Raises:
    ValueError: if the combination of the parameters is invalid.
  F)r   r   r   r   r   r   r[   r\   r]   r   r^   r_   )r   r  r   )r   r  r   r[   r\   r]   r   r^   r   r   r   rU  trt_converterconverted_graph_defs                 r0   create_inference_graphrQ    s\    D $13&E%#7#/!3- &--/-.	r2   )F)NNFFr=   )grb   collections	functoolsr   r  r   sysr  r  r0  sixr+   tensorflow.core.frameworkr   tensorflow.core.protobufr   r   r   tensorflow.python.clientr   #tensorflow.python.compiler.tensorrtr	   ry   tensorflow.python.eagerr
   r   tensorflow.python.frameworkr   r   r   r   r   r   tensorflow.python.grapplerr   tensorflow.python.opsr   r   tensorflow.python.platformr   rw   tensorflow.python.saved_modelr   r   r   r   r   r   tensorflow.python.trackabler   r   r   tensorflow.python.trainingr    tensorflow.python.utilr!   r"   "tensorflow.python.util.lazy_loaderr#    tensorflow.python.util.tf_exportr$   globalsr%   r&   trt_engine_opAttributeErrorr1   r6   objectr8   r~   r   maxsizerc   rM   rN   rO   rP   rQ   
namedtuplerT   DEFAULT_TRT_CONVERSION_PARAMSr#  rn   r   r   
deprecatedr   r   r   rZ  rm  TrackableResourcero  r  rf  r  r  r  r  r  r9   rQ  rF   r2   r0   <module>rn     s   :   	  
    2 / 3 8 , B + 1 < . . 0 + . 3 + ; < 1 . 0 . = 7 - 5 0 , . ' 9 6
 7957 	68 

8v 
8  ((*6I66q!Q?),s):&)0&  $ !0 2O / 3;-GK0 3 -G <-G` !4 5 # <.?;F 1515(-=B593I\"~ 
NP 0404',<A	CPC&} }~F
%P,33 ,> <,^FDC& ,4t
3& t
3 5t
3v A#(($(R{4  s   H2 2H;:H;