
    BVh                        d 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Zej                  j                  e      d   j                  ej                  j                  dd            sddlmZ ddlmZ ddlmZ nddlmZ ddlmZ d	 Zej                  j                  e      d   j                  ej                  j                  d
d            ZdZ G d d      Z ed      dd       Z G d d      Z ed      ej:                   G d dej<                                      Zej@                  fdZ! ed       G d d             Z" G d de"      Z#y)zPython TF-Lite interpreter.    Ntflite_runtimeinterpreter)&_pywrap_tensorflow_interpreter_wrapper)metrics)	tf_export)metrics_portablec                      ~ ~d S )Nc                     | S N )xs    R/home/dcms/DCMS/lib/python3.12/site-packages/tensorflow/lite/python/interpreter.py<lambda>z_tf_export.<locals>.<lambda>'   s    Q     r   )r   kwargss     r   
_tf_exportr   %   s    	6r   ai_edge_literta       Warning: tf.lite.Interpreter is deprecated and is scheduled for deletion in
    TF 2.20. Please use the LiteRT interpreter from the ai_edge_litert package.
    See the [migration guide](https://ai.google.dev/edge/litert/migration)
    for details.
    c                   $    e Zd ZdZddZd Zd Zy)Delegatea(  Python wrapper class to manage TfLiteDelegate objects.

  The shared library is expected to have two functions,
  tflite_plugin_create_delegate and tflite_plugin_destroy_delegate,
  which should implement the API specified in
  tensorflow/lite/delegates/external/external_delegate_interface.h.
  Nc                 p   t        j                         dk7  rt        d      t        j                  j                  |      | _        t        j                  t        j                        t        j                  t        j                        t        j                  t        j                  dt        j                        g| j                  j                  _        t        j                  | j                  j                  _        |xs i }t        j                  t        |      z         }t        j                  t        |      z         }t!        |j#                               D ]B  \  }\  }}t%        |      j'                  d      ||<   t%        |      j'                  d      ||<   D  G d d      } |       }	 t        j                  dt        j                        |	j(                        }
| j                  j                  ||t        |      |
      | _        | j*                  t-        |	j.                        y)a  Loads delegate from the shared library.

    Args:
      library: Shared library name.
      options: Dictionary of options that are required to load the delegate. All
        keys and values in the dictionary should be serializable. Consult the
        documentation of the specific delegate for required and legal options.
        (default None)

    Raises:
      RuntimeError: This is raised if the Python implementation is not CPython.
    CPythonz_Delegates are currently only supported into CPythondue to missing immediate reference counting.Nutf-8c                       e Zd Zd Zd Zy).Delegate.__init__.<locals>.ErrorMessageCapturec                     d| _         y )N )messageselfs    r   __init__z7Delegate.__init__.<locals>.ErrorMessageCapture.__init__h   s	    r   c                     | xj                   t        |t              r
|z  c_         y |j                  d      z  c_         y )Nr   )r   
isinstancestrdecode)r   r   s     r   reportz5Delegate.__init__.<locals>.ErrorMessageCapture.reportk   s)    Z3/FQXXg5FFr   N)__name__
__module____qualname__r    r%   r   r   r   ErrorMessageCapturer   f   s    Gr   r)   )platformpython_implementationRuntimeErrorctypespydllLoadLibrary_libraryPOINTERc_char_pc_int	CFUNCTYPEtflite_plugin_create_delegateargtypesc_void_prestypelen	enumerateitemsr#   encoder%   _delegate_ptr
ValueErrorr   )r   libraryoptionsoptions_keysoptions_valuesidxkeyvaluer)   captureerror_capturer_cbs              r   r    zDelegate.__init__A   s     %%'94 H I I LL,,W5DMv'v'v/<DMM//8 ;A//DMM//7 mGOOc'l25LooG47N&w}}7 7\c5c(//'2l3J--g6nS7G G "#G?((v?ODDnc'l4EGD!w'' "r   c                     | j                   Wt        j                  g| j                   j                  _        | j                   j                  | j
                         d | _         y y r   )r0   r-   r7   tflite_plugin_destroy_delegater6   r=   r   s    r   __del__zDelegate.__del__v   sK     }} ?E>Odmm22;
mm2243E3EFdm !r   c                     | j                   S )zReturns the native TfLiteDelegate pointer.

    It is not safe to copy this pointer because it needs to be freed.

    Returns:
      TfLiteDelegate *
    )r=   r   s    r   _get_native_delegate_pointerz%Delegate._get_native_delegate_pointer~   s     r   r   )r&   r'   r(   __doc__r    rJ   rL   r   r   r   r   r   8   s    3(jr   r   zlite.experimental.load_delegatec           	          	 t        | |      }|S # t        $ r)}t        dj                  | t        |                  d}~ww xY w)ac  Returns loaded Delegate object.

  Example usage:

  ```
  import tensorflow as tf

  try:
    delegate = tf.lite.experimental.load_delegate('delegate.so')
  except ValueError:
    // Fallback to CPU

  if delegate:
    interpreter = tf.lite.Interpreter(
        model_path='model.tflite',
        experimental_delegates=[delegate])
  else:
    interpreter = tf.lite.Interpreter(model_path='model.tflite')
  ```

  This is typically used to leverage EdgeTPU for running TensorFlow Lite models.
  For more information see: https://coral.ai/docs/edgetpu/tflite-python/

  Args:
    library: Name of shared library containing the
      [TfLiteDelegate](https://www.tensorflow.org/lite/performance/delegates).
    options: Dictionary of options that are required to load the delegate. All
      keys and values in the dictionary should be convertible to str. Consult
      the documentation of the specific delegate for required and legal options.
      (default None)

  Returns:
    Delegate object.

  Raises:
    ValueError: Delegate failed to load.
    RuntimeError: If delegate loading is used on unsupported platform.
  z"Failed to load delegate from {}
{}N)r   r>   formatr#   )r?   r@   delegatees       r   load_delegaterR      sQ    P)H 
/ 
 
:AAQ  s    	A$=Ac                   *    e Zd ZdZddZd Zd Zd Zy)SignatureRunneraJ  SignatureRunner class for running TFLite models using SignatureDef.

  This class should be instantiated through TFLite Interpreter only using
  get_signature_runner method on Interpreter.
  Example,
  signature = interpreter.get_signature_runner("my_signature")
  result = signature(input_1=my_input_1, input_2=my_input_2)
  print(result["my_output"])
  print(result["my_second_output"])
  All names used are this specific SignatureDef names.

  Notes:
    No other function on this object or on the interpreter provided should be
    called while this object call has not finished.
  Nc                    |st        d      |st        d      || _        |j                  | _        || _        |j	                         }||vrt        d      ||   | _        | j
                  d   j                         | _        | j
                  d   | _        | j                  j                  | j                        | _
        y)zConstructor.

    Args:
      interpreter: Interpreter object that is already initialized with the
        requested model.
      signature_key: SignatureDef key to be used.
    zNone interpreter provided.zNone signature_key provided.zInvalid signature_key provided.outputsinputsN)r>   _interpreter_interpreter_wrapper_signature_key_get_full_signature_list_signature_defr;   _outputs_inputsGetSubgraphIndexFromSignature_subgraph_index)r   r   signature_keysignature_defss       r   r    zSignatureRunner.__init__   s     344566#D + 8 8D'D 99;NN*899(7D''	288:DM&&x0DL 	!!??	! 	r   c                 x   t        |      t        | j                        k7  r-t        dt        | j                        dt        |            |j                         D ]  \  }}|| j                  vrt        d|z        | j                  j                  | j                  |   t        j                  |j                  t        j                        d| j                          | j                  j                  | j                         |j                         D ]9  \  }}| j                  j                  | j                  |   || j                         ; | j                  j                  | j                         i }| j                  D ].  \  }}| j                  j                  || j                        ||<   0 |S )aq  Runs the SignatureDef given the provided inputs in arguments.

    Args:
      **kwargs: key,value for inputs to the model. Key is the SignatureDef input
        name. Value is numpy array with the value.

    Returns:
      dictionary of the results from the model invoke.
      Key in the dictionary is SignatureDef output name.
      Value is the result Tensor.
    zGInvalid number of inputs provided for running a SignatureDef, expected z vs provided z(Invalid Input name (%s) for SignatureDefdtypeF)r9   r^   r>   r;   rY   ResizeInputTensornparrayshapeint32r`   AllocateTensors	SetTensorInvoker]   	GetTensor)r   r   
input_namerE   resultoutput_nameoutput_indexs          r   __call__zSignatureRunner.__call__   s    6{c$,,''*-dll*;S[JK K
 $\\^ '
E	4<<	'C#$ % 	%
11
,,z
"BHHU[[$I
%%'	' 	--d.B.BC#\\^ @
E
))$,,z*BE*.*>*>@@ 	$$T%9%9:F%)]] .!\ 55??
,,.f[. Mr   c                     i }| j                   j                         D ].  \  }}| j                  j                  || j                        ||<   0 |S )a   Gets input tensor details.

    Returns:
      A dictionary from input name to tensor details where each item is a
      dictionary with details about an input tensor. Each dictionary contains
      the following fields that describe the tensor:

      + `name`: The tensor name.
      + `index`: The tensor index in the interpreter.
      + `shape`: The shape of the tensor.
      + `shape_signature`: Same as `shape` for models with known/fixed shapes.
        If any dimension sizes are unknown, they are indicated with `-1`.
      + `dtype`: The numpy data type (such as `np.int32` or `np.uint8`).
      + `quantization`: Deprecated, use `quantization_parameters`. This field
        only works for per-tensor quantization, whereas
        `quantization_parameters` works in all cases.
      + `quantization_parameters`: A dictionary of parameters used to quantize
        the tensor:
        ~ `scales`: List of scales (one if per-tensor quantization).
        ~ `zero_points`: List of zero_points (one if per-tensor quantization).
        ~ `quantized_dimension`: Specifies the dimension of per-axis
        quantization, in the case of multiple scales/zero_points.
      + `sparsity_parameters`: A dictionary of parameters used to encode a
        sparse tensor. This is empty if the tensor is dense.
    )r^   r;   rX   _get_tensor_detailsr`   )r   rp   ro   tensor_indexs       r   get_input_detailsz!SignatureRunner.get_input_details  sW    4 F$(LL$6$6$8 . 
L,,@@
,,.fZ. Mr   c                     i }| j                   D ].  \  }}| j                  j                  || j                        ||<   0 |S )a  Gets output tensor details.

    Returns:
      A dictionary from input name to tensor details where each item is a
      dictionary with details about an output tensor. The dictionary contains
      the same fields as described for `get_input_details()`.
    )r]   rX   ru   r`   )r   rp   rq   rv   s       r   get_output_detailsz"SignatureRunner.get_output_details,  sN     F%)]] .!\ --AA
,,.f[. Mr   )NN)r&   r'   r(   rM   r    rs   rw   ry   r   r   r   rT   rT      s     "4&P@r   rT   z lite.experimental.OpResolverTypec                        e Zd ZdZdZdZdZdZy)OpResolverTypea	  Different types of op resolvers for Tensorflow Lite.

  * `AUTO`: Indicates the op resolver that is chosen by default in TfLite
     Python, which is the "BUILTIN" as described below.
  * `BUILTIN`: Indicates the op resolver for built-in ops with optimized kernel
    implementation.
  * `BUILTIN_REF`: Indicates the op resolver for built-in ops with reference
    kernel implementation. It's generally used for testing and debugging.
  * `BUILTIN_WITHOUT_DEFAULT_DELEGATES`: Indicates the op resolver for
    built-in ops with optimized kernel implementation, but it will disable
    the application of default TfLite delegates (like the XNNPACK delegate) to
    the model graph. Generally this should not be used unless there are issues
    with the default configuration.
  r            N)r&   r'   r(   rM   AUTOBUILTINBUILTIN_REF!BUILTIN_WITHOUT_DEFAULT_DELEGATESr   r   r   r{   r{   ;  s$     
$ ' + '(#r   r{   c                     t         j                  dt         j                  dt         j                  dt         j                  dij                  | d      S )z-Get a integer identifier for the op resolver.r|   r}   r~   N)r{   r   r   r   r   get)op_resolver_types    r   _get_op_resolver_idr   Z  sI     1a  !66
 C$ r   zlite.Interpreterc                       e Zd ZdZddddej
                  dddfdZd Zd Zd Z	d Z
d	 Zd
 Zd Zd ZddZd Zd ZddZd Zd Zd ZddZddZd Zd Zd Zd Zy)Interpretera7  Interpreter interface for running TensorFlow Lite models.

  Models obtained from `TfLiteConverter` can be run in Python with
  `Interpreter`.

  As an example, let's generate a simple Keras model and convert it to TFLite
  (`TfLiteConverter` also supports other input formats with `from_saved_model`
  and `from_concrete_function`)

  >>> x = np.array([[1.], [2.]])
  >>> y = np.array([[2.], [4.]])
  >>> model = tf.keras.models.Sequential([
  ...           tf.keras.layers.Dropout(0.2),
  ...           tf.keras.layers.Dense(units=1, input_shape=[1])
  ...         ])
  >>> model.compile(optimizer='sgd', loss='mean_squared_error')
  >>> model.fit(x, y, epochs=1)
  >>> converter = tf.lite.TFLiteConverter.from_keras_model(model)
  >>> tflite_model = converter.convert()

  `tflite_model` can be saved to a file and loaded later, or directly into the
  `Interpreter`. Since TensorFlow Lite pre-plans tensor allocations to optimize
  inference, the user needs to call `allocate_tensors()` before any inference.

  >>> interpreter = tf.lite.Interpreter(model_content=tflite_model)
  >>> interpreter.allocate_tensors()  # Needed before execution!

  Sample execution:

  >>> output = interpreter.get_output_details()[0]  # Model has single output.
  >>> input = interpreter.get_input_details()[0]  # Model has single input.
  >>> input_data = tf.constant(1., shape=[1, 1])
  >>> interpreter.set_tensor(input['index'], input_data)
  >>> interpreter.invoke()
  >>> interpreter.get_tensor(output['index']).shape
  (1, 1)

  Use `get_signature_runner()` for a more user-friendly inference API.
  NFc	                    t         st        j                  t               t	        | d      sg | _        |}	|r;|t        j                  k(  s|t        j                  k(  rt        j                  d       t        |	      }
|
t        dj                  |            |+t        |t              st        d      |dk  rt        d      |r|s| j
                  D cg c]  }t        |t              s| }}| j
                  D cg c]  }t        |t              r| }}t        j                   ||
||||t        |xs d      |      | _        | j"                  st        dj                  |            |r|s| j
                  D cg c]  }t        |t              s| }}| j
                  D cg c]  }t        |t              r| }}|| _        t        j&                  ||
||||t        |xs d      |      | _        n|s|st        d	      t        d
      g | _        |rA|| _        | j(                  D ]+  }| j"                  j+                  |j-                                - | j/                         | _        t3        j4                         | _        | j6                  j9                          yc c}w c c}w c c}w c c}w )a
  Constructor.

    Args:
      model_path: Path to TF-Lite Flatbuffer file.
      model_content: Content of model.
      experimental_delegates: Experimental. Subject to change. List of
        [TfLiteDelegate](https://www.tensorflow.org/lite/performance/delegates)
        objects returned by lite.load_delegate().
      num_threads: Sets the number of threads used by the interpreter and
        available to CPU kernels. If not set, the interpreter will use an
        implementation-dependent default number of threads. Currently, only a
        subset of kernels, such as conv, support multi-threading. num_threads
        should be >= 1.
      experimental_op_resolver_type: The op resolver used by the interpreter. It
        must be an instance of OpResolverType. By default, we use the built-in
        op resolver which corresponds to tflite::ops::builtin::BuiltinOpResolver
        in C++.
      experimental_preserve_all_tensors: If true, then intermediate tensors used
        during computation are preserved for inspection, and if the passed op
        resolver type is AUTO or BUILTIN, the type will be changed to BUILTIN so
        that Tensorflow Lite default delegates are applied. If false, getting
        intermediate tensors could result in undefined values or None,
        especially when the graph is successfully modified by the Tensorflow
        Lite default delegate.
      experimental_disable_delegate_clustering: If true, don't perform delegate
        clustering during delegate graph partitioning phase. Disabling delegate
        clustering will make the execution order of ops respect the
        explicitly-inserted control dependencies in the graph (inserted via
        `with tf.control_dependencies()`) since the TF Lite converter will drop
        control dependencies by default. Most users shouldn't turn this flag to
        True if they don't insert explicit control dependencies or the graph
        execution order is expected. For automatically inserted control
        dependencies (with `tf.Variable`, `tf.Print` etc), the user doesn't need
        to turn this flag to True since they are respected by default. Note that
        this flag is currently experimental, and it might be removed/updated if
        the TF Lite converter doesn't drop such control dependencies in the
        model. Default is False.
      experimental_default_delegate_latest_features: If true, default delegates
        may enable all flag protected features. Default is False;

    Raises:
      ValueError: If the interpreter was unable to create.
    _custom_op_registerersaC  Warning: Enabling `experimental_preserve_all_tensors` with the BUILTIN or AUTO op resolver is intended for debugging purposes only. Be aware that this can significantly increase memory usage by storing all intermediate tensors. If you encounter memory problems or are not actively debugging, consider disabling this option.Nz+Unrecognized passed in op resolver type: {}z!type of num_threads should be intr|   znum_threads should >= 1zFailed to open {}z2`model_path` or `model_content` must be specified.z3Can't both provide `model_path` and `model_content`)_IS_LITERT_PACKAGEwarningswarn_INTERPRETER_DELETION_WARNINGhasattrr   r{   r   r   r   r>   rO   r"   intr#   rY   CreateWrapperFromFilerX   _model_contentCreateWrapperFromBuffer
_delegatesModifyGraphWithDelegaterL   get_signature_list_signature_defsr   TFLiteMetrics_metrics%increase_counter_interpreter_creation)r   
model_pathmodel_contentexperimental_delegatesnum_threadsexperimental_op_resolver_type!experimental_preserve_all_tensors(experimental_disable_delegate_clustering-experimental_default_delegate_latest_featuresactual_resolver_typeop_resolver_idr   custom_op_registerers_by_namecustom_op_registerers_by_funcrP   s                  r   r    zInterpreter.__init__  s   l mm12412$&d!8(%)<)<<%)?)??mmL ))=>NDKK
') * * S)<==	q233-00'Jq#4F!'# ' 00'
1c8J!'# ' /DD


'
'
+
2
kQ

7	d ,33J?@@	z00'Jq#4F!'# ' 00'
1c8J!'# ' *d.FF


'
'
+
2
kQ

7	d :KLLMNN DO.dooo 5(11113	55  224D))+DMMM779s'' ''s0   J-.J-J2J2J7J7.J<J<c                      d | _         d | _        y r   )rX   r   r   s    r   rJ   zInterpreter.__del__  s     DDOr   c                 V    | j                          | j                  j                         S r   )_ensure_saferX   rk   r   s    r   allocate_tensorszInterpreter.allocate_tensors(  s#    ,,..r   c                 F    t        j                  | j                        dk(  S )zReturns true if there exist no numpy array buffers.

    This means it is safe to run tflite calls that may destroy internally
    allocated memory. This works, because in the wrapper.cc we have made
    the numpy base be the self._interpreter.
    r}   )sysgetrefcountrX   r   s    r   _safe_to_runzInterpreter._safe_to_run,  s     ??4,,-22r   c                 :    | j                         st        d      y)aB  Makes sure no numpy arrays pointing to internal buffers are active.

    This should be called from any function that will call a function on
    _interpreter that may reallocate memory e.g. invoke(), ...

    Raises:
      RuntimeError: If there exist numpy objects pointing to internal memory
        then we throw.
    zThere is at least 1 reference to internal data
      in the interpreter in the form of a numpy array or slice. Be sure to
      only hold the function returned from tensor() if you are using raw
      data access.N)r   r,   r   s    r   r   zInterpreter._ensure_safe8  s'         r   c                    | j                   j                  |      D cg c]  }|dk7  r| j                  |d      d    }}| j                   j                  |      D cg c]  }|dk7  r| j                  |d      d    }}t	        |      | j                   j                  |      | j                   j                  |      | j                   j                  |      ||d}|S c c}w c c}w )a-  Gets a dictionary with arrays of ids for tensors involved with an op.

    Args:
      op_index: Operation/node index of node to query.

    Returns:
      a dictionary containing the index, op name, and arrays with lists of the
      indices and types for the inputs and outputs of the op/nodes.
    r   subgraph_indexre   )indexop_namerW   rV   operand_typesresult_types)rX   
NodeInputsru   NodeOutputsr   NodeName)r   op_index
tensor_idxr   r   detailss         r   _get_op_detailszInterpreter._get_op_detailsI  s     ++66x@ 	  A >wGM  ++77A 	  A >wGL  X$$--h7##..x8$$00:&$G N%
s   "C""C'c           
         t        |      }t        |      }| j                  j                  ||      }| j                  j                  ||      }| j                  j	                  ||      }| j                  j                  ||      }| j                  j                  ||      }| j                  j                  ||      }| j                  j                  ||      }	|st        d      |||||||d   |d   |d   d|	d}
|
S )a  Gets tensor details.

    Args:
      tensor_index: Tensor index of tensor to query.
      subgraph_index: Index of the subgraph.

    Returns:
      A dictionary containing the following fields of the tensor:
        'name': The tensor name.
        'index': The tensor index in the subgraph.
        'shape': The shape of the tensor.
        'quantization': Deprecated, use 'quantization_parameters'. This field
            only works for per-tensor quantization, whereas
            'quantization_parameters' work in all cases.
        'quantization_parameters': The parameters used to quantize the tensor:
          'scales': List of scales (one if per-tensor quantization)
          'zero_points': List of zero_points (one if per-tensor quantization)
          'quantized_dimension': Specifies the dimension of per-axis
              quantization, in the case of multiple scales/zero_points.

    Raises:
      ValueError: If tensor_index is invalid.
    zCould not get tensor detailsr   r|   r}   )scaleszero_pointsquantized_dimension)namer   ri   shape_signaturere   quantizationquantization_parameterssparsity_parameters)
r   rX   
TensorName
TensorSizeTensorSizeSignature
TensorTypeTensorQuantizationTensorQuantizationParametersTensorSparsityParametersr>   )r   rv   r   tensor_nametensor_sizetensor_size_signaturetensor_typetensor_quantizationtensor_quantization_paramstensor_sparsity_paramsr   s              r   ru   zInterpreter._get_tensor_detailsg  s%   0 |$L(N##..|^LK##..|^LK --AAn&##..|^LK++>>n&!%!2!2!O!On"&!..GGn& 566 0+035a8#=a#@$

  6G Nr   c                     t        | j                  j                               D cg c]  }| j                  |       c}S c c}w )zGets op details for every node.

    Returns:
      A list of dictionaries containing arrays with lists of tensor ids for
      tensors involved in the op.
    )rangerX   NumNodesr   )r   rC   s     r   _get_ops_detailszInterpreter._get_ops_details  s@     .343D3D3M3M3O-P&)S!  s   Ac                 6    | j                   j                         S )z-Returns the number of subgraphs in the model.)rX   NumSubgraphsr   s    r   num_subgraphszInterpreter.num_subgraphs  s    ))++r   c                 *   g }| j                   j                         }|dk  s||k\  rt        d| d| d      t        | j                   j	                  |            D ]$  }	 |j                  | j                  ||             & |S # t        $ r Y 4w xY w)a  Gets tensor details for every tensor with valid tensor details from a subgraph.

    Tensors where required information about the tensor is not found are not
    added to the list. This includes temporary tensors without a name.

    Args:
      subgraph_index: Index of the subgraph to fetch the tensor.

    Returns:
      A list of dictionaries containing tensor information.
    r   z subgraph_index is out of range: z for the model, which has z subgraphs.)rX   r   r>   r   
NumTensorsappendru   )r   r   tensor_detailsr   rC   s        r   get_tensor_detailszInterpreter.get_tensor_details  s     N%%224M^}<,^,< =%k3 
 T&&11.AB d66sNKL   s   !!B	BBc                 ~    | j                   j                         D cg c]  }| j                  |d       c}S c c}w )a  Gets model input tensor details.

    Returns:
      A list in which each item is a dictionary with details about
      an input tensor. Each dictionary contains the following fields
      that describe the tensor:

      + `name`: The tensor name.
      + `index`: The tensor index in the interpreter.
      + `shape`: The shape of the tensor.
      + `shape_signature`: Same as `shape` for models with known/fixed shapes.
        If any dimension sizes are unknown, they are indicated with `-1`.
      + `dtype`: The numpy data type (such as `np.int32` or `np.uint8`).
      + `quantization`: Deprecated, use `quantization_parameters`. This field
        only works for per-tensor quantization, whereas
        `quantization_parameters` works in all cases.
      + `quantization_parameters`: A dictionary of parameters used to quantize
        the tensor:
        ~ `scales`: List of scales (one if per-tensor quantization).
        ~ `zero_points`: List of zero_points (one if per-tensor quantization).
        ~ `quantized_dimension`: Specifies the dimension of per-axis
        quantization, in the case of multiple scales/zero_points.
      + `sparsity_parameters`: A dictionary of parameters used to encode a
        sparse tensor. This is empty if the tensor is dense.
    r   r   )rX   InputIndicesru   r   is     r   rw   zInterpreter.get_input_details  sC    8 ""//1 	  1 5     :c                 <    | j                   j                  ||       y)a  Sets the value of the input tensor.

    Note this copies data in `value`.

    If you want to avoid copying, you can use the `tensor()` function to get a
    numpy buffer pointing to the input buffer in the tflite interpreter.

    Args:
      tensor_index: Tensor index of tensor to set. This value can be gotten from
        the 'index' field in get_input_details.
      value: Value of tensor to set.

    Raises:
      ValueError: If the interpreter could not set the tensor.
    N)rX   rl   )r   rv   rE   s      r   
set_tensorzInterpreter.set_tensor  s      	e4r   c                     | j                          t        j                  |t        j                        }| j                  j                  |||       y)a  Resizes an input tensor.

    Args:
      input_index: Tensor index of input to set. This value can be gotten from
        the 'index' field in get_input_details.
      tensor_size: The tensor_shape to resize the input to.
      strict: Only unknown dimensions can be resized when `strict` is True.
        Unknown dimensions are indicated as `-1` in the `shape_signature`
        attribute of a given tensor. (default False)

    Raises:
      ValueError: If the interpreter could not resize the input tensor.

    Usage:
    ```
    interpreter = Interpreter(model_content=tflite_model)
    interpreter.resize_tensor_input(0, [num_test_images, 224, 224, 3])
    interpreter.allocate_tensors()
    interpreter.set_tensor(0, test_images)
    interpreter.invoke()
    ```
    rd   N)r   rg   rh   rj   rX   rf   )r   input_indexr   stricts       r   resize_tensor_inputzInterpreter.resize_tensor_input  s>    . 	 ((;bhh7K''[&Ir   c                 ~    | j                   j                         D cg c]  }| j                  |d       c}S c c}w )zGets model output tensor details.

    Returns:
      A list in which each item is a dictionary with details about
      an output tensor. The dictionary contains the same fields as
      described for `get_input_details()`.
    r   r   )rX   OutputIndicesru   r   s     r   ry   zInterpreter.get_output_details  sC     ""002 	  1 5  r   c                     | j                   j                         }|j                         D ]C  \  }}t        |d   j	                               |d<   t        |d   j	                               |d<   E |S )a  Gets the list of SignatureDefs in the model.

    Example,
    ```
    signatures = interpreter.get_signature_list()
    print(signatures)

    # {
    #   'add': {'inputs': ['x', 'y'], 'outputs': ['output_0']}
    # }

    Then using the names in the signature list you can get a callable from
    get_signature_runner().
    ```

    Returns:
      A list of SignatureDef details in a dictionary structure.
      It is keyed on the SignatureDef method name, and the value holds
      a dictionary of inputs and outputs.
    rW   rV   )rX   GetSignatureDefsr;   listkeys)r   full_signature_defs_signature_defs       r   r   zInterpreter.get_signature_list(  sz    * ++<<>/557 G= $]8%<%A%A%C DmH!%mI&>&C&C&E!FmIG r   c                 6    | j                   j                         S )a  Gets list of SignatureDefs in the model.

    Example,
    ```
    signatures = interpreter._get_full_signature_list()
    print(signatures)

    # {
    #   'add': {'inputs': {'x': 1, 'y': 0}, 'outputs': {'output_0': 4}}
    # }

    Then using the names in the signature list you can get a callable from
    get_signature_runner().
    ```

    Returns:
      A list of SignatureDef details in a dictionary structure.
      It is keyed on the SignatureDef method name, and the value holds
      dictionary of inputs and outputs.
    )rX   r   r   s    r   r[   z$Interpreter._get_full_signature_listC  s    * --//r   c                     |ct        | j                        dk7  r-t        dj                  t        | j                                    t	        t        | j                              }t        | |      S )a  Gets callable for inference of specific SignatureDef.

    Example usage,
    ```
    interpreter = tf.lite.Interpreter(model_content=tflite_model)
    interpreter.allocate_tensors()
    fn = interpreter.get_signature_runner('div_with_remainder')
    output = fn(x=np.array([3]), y=np.array([2]))
    print(output)
    # {
    #   'quotient': array([1.], dtype=float32)
    #   'remainder': array([1.], dtype=float32)
    # }
    ```

    None can be passed for signature_key if the model has a single Signature
    only.

    All names used are these specific SignatureDef names.


    Args:
      signature_key: Signature key for the SignatureDef, it can be None if and
        only if the model has a single SignatureDef. The Default value is None.

    Returns:
      This returns a callable that can run inference for SignatureDef defined
      by argument 'signature_key'.
      The callable will take key arguments corresponding to the arguments of the
      SignatureDef, that should have numpy values.
      The callable will return dictionary that maps from output names to numpy
      values of the computed results.

    Raises:
      ValueError: If passed signature_key is invalid.
    r|   zwSignatureDef signature_key is None and model has {0} Signatures. None is only allowed when the model has 1 SignatureDef)r   ra   )r9   r   r>   rO   nextiterrT   )r   ra   s     r   get_signature_runnerz Interpreter.get_signature_runnerZ  sn    J 	T!!	"a	'EEKVD(()F+, 	,
 T$"6"678t=IIr   c                 :    | j                   j                  ||      S )a  Gets the value of the output tensor (get a copy).

    If you wish to avoid the copy, use `tensor()`. This function cannot be used
    to read intermediate results.

    Args:
      tensor_index: Tensor index of tensor to get. This value can be gotten from
        the 'index' field in get_output_details.
      subgraph_index: Index of the subgraph to fetch the tensor. Default value
        is 0, which means to fetch from the primary subgraph.

    Returns:
      a numpy array.
    )rX   rn   )r   rv   r   s      r   
get_tensorzInterpreter.get_tensor  s     &&|^DDr   c                       fdS )aj  Returns function that gives a numpy view of the current tensor buffer.

    This allows reading and writing to these tensors w/o copies. This more
    closely mirrors the C++ Interpreter class interface's tensor() member, hence
    the name. Be careful not to hold these output references through calls
    to `allocate_tensors()` and `invoke()`. This function cannot be used to read
    intermediate results.

    Usage:

    ```
    interpreter.allocate_tensors()
    input = interpreter.tensor(interpreter.get_input_details()[0]["index"])
    output = interpreter.tensor(interpreter.get_output_details()[0]["index"])
    for i in range(10):
      input().fill(3.)
      interpreter.invoke()
      print("inference %s" % output())
    ```

    Notice how this function avoids making a numpy array directly. This is
    because it is important to not hold actual numpy views to the data longer
    than necessary. If you do, then the interpreter can no longer be invoked,
    because it is possible the interpreter would resize and invalidate the
    referenced tensors. The NumPy API doesn't allow any mutability of the
    underlying buffers.

    WRONG:

    ```
    input = interpreter.tensor(interpreter.get_input_details()[0]["index"])()
    output = interpreter.tensor(interpreter.get_output_details()[0]["index"])()
    interpreter.allocate_tensors()  # This will throw RuntimeError
    for i in range(10):
      input.fill(3.)
      interpreter.invoke()  # this will throw RuntimeError since input, output
    ```

    Args:
      tensor_index: Tensor index of tensor to get. This value can be gotten from
        the 'index' field in get_output_details.

    Returns:
      A function that can return a new numpy array pointing to the internal
      TFLite tensor state at any point. It is safe to hold the function forever,
      but it is not safe to hold the numpy array forever.
    c                  P     j                   j                   j                         S r   )rX   tensorr   rv   s   r   r   z$Interpreter.tensor.<locals>.<lambda>  s     4$$++D,=,=|L r   r   r   s   ``r   r   zInterpreter.tensor  s    ` MLr   c                 X    | j                          | j                  j                          y)a  Invoke the interpreter.

    Be sure to set the input sizes, allocate tensors and fill values before
    calling this. Also, note that this function releases the GIL so heavy
    computation can be done in the background while the Python interpreter
    continues. No other function on this object should be called while the
    invoke() call has not finished.

    Raises:
      ValueError: When the underlying interpreter fails raise ValueError.
    N)r   rX   rm   r   s    r   invokezInterpreter.invoke  s"     	r   c                 6    | j                   j                         S r   )rX   ResetVariableTensorsr   s    r   reset_all_variableszInterpreter.reset_all_variables  s    1133r   c                 6    | j                   j                         S )a}  Returns a pointer to the underlying tflite::Interpreter instance.

    This allows extending tflite.Interpreter's functionality in a custom C++
    function. Consider how that may work in a custom pybind wrapper:

      m.def("SomeNewFeature", ([](py::object handle) {
        auto* interpreter =
          reinterpret_cast<tflite::Interpreter*>(handle.cast<intptr_t>());
        ...
      }))

    and corresponding Python call:

      SomeNewFeature(interpreter.native_handle())

    Note: This approach is fragile. Users must guarantee the C++ extension build
    is consistent with the tflite.Interpreter's underlying C++ build.
    )rX   r   r   s    r   _native_handlezInterpreter._native_handle  s    & ((**r   )r   )Fr   )r&   r'   r(   rM   r{   r   r    rJ   r   r   r   r   ru   r   r   r   rw   r   r   ry   r   r[   r   r   r   r  r  r  r   r   r   r   r   h  s    &T !$2$7$7(-/449K:Z/
3"<8v	,8>5$J:60.-J^E"0Md4+r   r   c                   $     e Zd ZdZd fd	Z xZS )InterpreterWithCustomOpsar  Interpreter interface for TensorFlow Lite Models that accepts custom ops.

  The interface provided by this class is experimental and therefore not exposed
  as part of the public API.

  Wraps the tf.lite.Interpreter class and adds the ability to load custom ops
  by providing the names of functions that take a pointer to a BuiltinOpResolver
  and add a custom op.
  c                 B    |xs g | _         t        t        |   di | y)a  Constructor.

    Args:
      custom_op_registerers: List of str (symbol names) or functions that take a
        pointer to a MutableOpResolver and register a custom op. When passing
        functions, use a pybind function that takes a uintptr_t that can be
        recast as a pointer to a MutableOpResolver.
      **kwargs: Additional arguments passed to Interpreter.

    Raises:
      ValueError: If the interpreter was unable to create.
    Nr   )r   superr	  r    )r   custom_op_registerersr   	__class__s      r   r    z!InterpreterWithCustomOps.__init__   s%     #8"=2D	
"D2<V<r   r   )r&   r'   r(   rM   r    __classcell__)r  s   @r   r	  r	    s    = =r   r	  r   )$rM   r-   enumosr*   r   r   numpyrg   pathsplitext__file__endswithjoin*tensorflow.lite.python.interpreter_wrapperr   rY   tensorflow.lite.python.metricsr    tensorflow.python.util.tf_exportr   r   r   r   r   r   r   rR   rT   uniqueEnumr{   r   r   r   r	  r   r   r   <module>r     sW   "   	  
   
ww!!$--GGLL!=13 x4F \8 WW%%h/2;;GGLL!=1 ! N Nb -., /,^ D ./(TYY (  0(: *8)<)<   I
+ I
+  I
+X={ =r   