# `TFLiteElixir.Interpreter`
[🔗](https://github.com/cocoa-xu/tflite_elixir/blob/main/lib/tflite_elixir/interpreter.ex#L1)

An interpreter for a graph of nodes that input and output from tensors.

# `nif_error`

```elixir
@type nif_error() :: {:error, String.t()}
```

# `nif_resource_ok`

```elixir
@type nif_resource_ok() :: {:ok, reference()}
```

# `allocate_tensors`

```elixir
@spec allocate_tensors(reference()) :: :ok | nif_error()
```

Allocate memory for tensors in the graph

# `allocate_tensors!`

Raising version of `allocate_tensors/1`.

# `cancel`

```elixir
@spec cancel(reference()) :: :ok | nif_error()
```

Ask an in-flight `invoke/1` to stop.

Does not block and is safe to call from another process, which is the point: an
invocation occupies a dirty scheduler and cannot otherwise be interrupted. Later
invocations are unaffected. Requires `enable_cancellation/1`.

# `controlling_process`

```elixir
@spec controlling_process(reference()) :: {:ok, pid()} | :undefined | nif_error()
```

Which process this interpreter belongs to, or `:undefined` if it is shared.

# `controlling_process`

```elixir
@spec controlling_process(reference(), pid() | :undefined) :: :ok | nif_error()
```

Hand this interpreter to `pid`.

Follows `:gen_tcp.controlling_process/2`: while an interpreter belongs to
nobody any process may take it, and once it belongs to someone only that
process may hand it on. Pass `:undefined` to give it back to nobody. A
controlling process that dies releases it, since an interpreter has no
equivalent of a socket being closed.

Two processes whose calls overlap on an unclaimed interpreter get
`{:error, "interpreter is already in use by another process"}`, and once it is
claimed every other process gets `{:error, "interpreter belongs to another
process"}` whether their calls overlap or not.

# `controlling_process!`

Raising version of `controlling_process/1`.

# `controlling_process!`

Raising version of `controlling_process/2`.

# `enable_cancellation`

```elixir
@spec enable_cancellation(reference()) :: :ok | nif_error()
```

Allow a running `invoke/1` to be cancelled.

Has to be called before invoking. Without it `cancel/1` is an error.

# `execution_plan`

```elixir
@spec execution_plan(reference()) :: [non_neg_integer()] | nif_error()
```

Return the execution plan of the model.

Experimental interface, subject to change.

# `get_allow_fp16_precision_for_fp32`

```elixir
@spec get_allow_fp16_precision_for_fp32(reference()) :: {:ok, boolean()} | nif_error()
```

Whether float32 operations may be carried out in float16.

# `get_allow_fp16_precision_for_fp32!`

Raising version of `get_allow_fp16_precision_for_fp32/1`.

# `get_input_name`

```elixir
@spec get_input_name(reference(), non_neg_integer()) ::
  {:ok, String.t()} | nif_error()
```

Get the name of the input tensor

Note that the index here means the index in the result list of `inputs/1`. For example,
if `inputs/1` returns `[42, 314]`, then `0` should be passed here to get the name of
tensor `42`

# `get_input_name!`

Raising version of `get_input_name/2`.

# `get_output_name`

```elixir
@spec get_output_name(reference(), non_neg_integer()) ::
  {:ok, String.t()} | nif_error()
```

Get the name of the output tensor

Note that the index here means the index in the result list of `outputs/1`. For example,
if `outputs/1` returns `[42, 314]`, then `0` should be passed here to get the name of
tensor `42`

# `get_output_name!`

Raising version of `get_output_name/2`.

# `get_signature_defs`

```elixir
@spec get_signature_defs(reference()) :: {:ok, map() | nil} | {:error, String.t()}
```

Get SignatureDef map from the Metadata of a TfLite flatbuffer buffer.

`self`: `TFLiteElixir.Interpreter`

  TFLite model buffer to get the signature_def.

##### Returns:

`{:ok, map()}` of serving names to SignatureDefs, or `{:ok, nil}` for a model
that carries none.

# `get_signature_defs!`

Raising version of `get_signature_defs/1`.

# `get_signature_runner`

```elixir
@spec get_signature_runner(reference(), String.t() | nil) ::
  nif_resource_ok() | nif_error()
```

Get a runner for one of the model's signatures.

Pass `nil` for the primary subgraph: the first signature that points at it, or a
placeholder one when the model declares no signatures at all, so this works with
older exports too.

The runner keeps this interpreter alive. See `TFLiteElixir.SignatureRunner`.

# `get_signature_runner!`

Raising version of `get_signature_runner/2`.

# `get_subgraph_index_from_signature`

```elixir
@spec get_subgraph_index_from_signature(reference(), String.t()) ::
  {:ok, integer()} | nif_error()
```

The subgraph a signature belongs to, or `-1` for a key the model does not declare.

# `get_subgraph_index_from_signature!`

Raising version of `get_subgraph_index_from_signature/2`.

# `input_tensor`

```elixir
@spec input_tensor(reference(), non_neg_integer(), binary()) :: :ok | nif_error()
```

Fill data to the specified input tensor

Note: although we have `typed_input_tensor` available in C++, here what we really passed
to the NIF is `binary` data, therefore, I'm not pretend that we have type information.

# `input_tensor!`

Raising version of `input_tensor/3`.

# `inputs`

```elixir
@spec inputs(reference()) :: {:ok, [non_neg_integer()]} | nif_error()
```

Get the list of input tensors.

return a list of input tensor id

# `inputs!`

Raising version of `inputs/1`.

# `invoke`

```elixir
@spec invoke(reference()) :: :ok | nif_error()
```

Run forwarding

# `invoke!`

Raising version of `invoke/1`.

# `new`

```elixir
@spec new() :: nif_resource_ok() | nif_error()
```

New interpreter

# `new`

```elixir
@spec new(String.t()) :: nif_resource_ok() | nif_error()
```

New interpreter with model filepath

# `new!`

Raising version of `new/0`.

# `new!`

Raising version of `new/1`.

# `new_from_buffer`

```elixir
@spec new_from_buffer(binary()) :: nif_resource_ok() | nif_error()
```

New interpreter with model buffer

# `nodes_size`

```elixir
@spec nodes_size(reference()) :: non_neg_integer() | nif_error()
```

Return the number of ops in the model.

# `output_tensor`

```elixir
@spec output_tensor(reference(), non_neg_integer()) :: {:ok, binary()} | nif_error()
```

Get the data of the output tensor

Note that the index here means the index in the result list of `outputs/1`. For example,
if `outputs/1` returns `[42, 314]`, then `0` should be passed here to get the name of
tensor `42`

# `output_tensor!`

Raising version of `output_tensor/2`.

# `outputs`

```elixir
@spec outputs(reference()) :: {:ok, [non_neg_integer()]} | nif_error()
```

Get the list of output tensors.

return a list of output tensor id

# `outputs!`

Raising version of `outputs/1`.

# `predict`

```elixir
@spec predict(
  reference(),
  binary()
  | Nx.Tensor.t()
  | [binary() | Nx.Tensor.t()]
  | %{required(String.t()) =&gt; binary() | Nx.Tensor.t()}
) :: [Nx.Tensor.t()] | nif_error()
```

Fill input data to corresponding input tensor of the interpreter,
call `Interpreter.invoke` and return output tensor(s)

Each input is a binary of the tensor's bytes or an `Nx.Tensor` of its type
and shape. A model with one input takes it bare; otherwise pass them as a list
in the order of `inputs/1`, or as a map from tensor name to data.

# `release_non_persistent_memory`

```elixir
@spec release_non_persistent_memory(reference()) :: :ok | nif_error()
```

Release memory that is only needed while invoking.

Invoking again reallocates it, so this trades time for memory on devices short of
the latter.

# `reset_variable_tensors`

```elixir
@spec reset_variable_tensors(reference()) :: :ok | nif_error()
```

Reset all variable tensors to zero.

# `resize_input_tensor`

```elixir
@spec resize_input_tensor(reference(), integer(), [integer()] | tuple()) ::
  :ok | nif_error()
```

Change the dimensionality of a given input tensor.

Only inputs can be resized, and `allocate_tensors/1` has to be called again
afterwards.

`dims` is a list, or the tuple `TFLiteElixir.TFLiteTensor.shape/1` returns.

# `resize_input_tensor_strict`

```elixir
@spec resize_input_tensor_strict(reference(), integer(), [integer()] | tuple()) ::
  :ok | nif_error()
```

Change the dimensionality of a given input tensor, keeping the rank fixed.

Unlike `resize_input_tensor/3` this only accepts dimensions the model left unknown,
so a tensor whose shape is fully fixed cannot be resized.

`dims` is a list, or the tuple `TFLiteElixir.TFLiteTensor.shape/1` returns.

# `set_allow_fp16_precision_for_fp32`

```elixir
@spec set_allow_fp16_precision_for_fp32(reference(), boolean()) :: :ok | nif_error()
```

Allow or forbid carrying out float32 operations in float16.

Only has an effect on backends that can do it, and has to be set before the graph is
prepared.

# `set_inputs`

```elixir
@spec set_inputs(reference(), [integer()]) :: :ok | nif_error()
```

Provide a list of tensor indexes that are inputs to the model.
Each index is bound check and this modifies the consistent_ flag of the
interpreter.

# `set_num_threads`

```elixir
@spec set_num_threads(reference(), integer()) :: :ok | nif_error()
```

Set the number of threads available to the interpreter.

NOTE: num_threads should be >= 1.

As TfLite interpreter could internally apply a TfLite delegate by default
(i.e. XNNPACK), the number of threads that are available to the default
delegate *should be* set via InterpreterBuilder APIs as follows:

```elixir
interpreter = Interpreter.new!()
builder = InterpreterBuilder.new!(tflite model, op resolver)
InterpreterBuilder.set_num_threads(builder, ...)
assert :ok == InterpreterBuilder.build!(builder, interpreter)
```

`num_threads` follows TfLite: `-1` asks the runtime to choose, `0` means the
same as `1`, and anything below `-1` is answered with `{:error, reason}`.

# `set_num_threads!`

Raising version of `set_num_threads/2`.

# `set_outputs`

```elixir
@spec set_outputs(reference(), [integer()]) :: :ok | nif_error()
```

Provide a list of tensor indexes that are outputs to the model.
Each index is bound check and this modifies the consistent_ flag of the
interpreter.

# `set_variables`

```elixir
@spec set_variables(reference(), [integer()]) :: :ok | nif_error()
```

Provide a list of tensor indexes that are variable tensors.
Each index is bound check and this modifies the consistent_ flag of the
interpreter.

# `signature_inputs`

```elixir
@spec signature_inputs(reference(), String.t()) :: {:ok, map()} | nif_error()
```

The inputs of the named signature, as a map of name to tensor index.

An empty map is returned for a key the model does not declare.

# `signature_inputs!`

Raising version of `signature_inputs/2`.

# `signature_keys`

```elixir
@spec signature_keys(reference()) :: [String.t()] | nif_error()
```

Returns list of all keys of different method signatures defined in the
model.

WARNING: Experimental interface, subject to change

# `signature_outputs`

```elixir
@spec signature_outputs(reference(), String.t()) :: {:ok, map()} | nif_error()
```

The outputs of the named signature, as a map of name to tensor index.

An empty map is returned for a key the model does not declare.

# `signature_outputs!`

Raising version of `signature_outputs/2`.

# `subgraphs_size`

```elixir
@spec subgraphs_size(reference()) :: {:ok, non_neg_integer()} | nif_error()
```

How many subgraphs the model has.

# `subgraphs_size!`

Raising version of `subgraphs_size/1`.

# `tensor`

```elixir
@spec tensor(reference(), non_neg_integer()) ::
  %TFLiteElixir.TFLiteTensor{
    index: term(),
    name: term(),
    quantization_params: term(),
    reference: term(),
    shape: term(),
    shape_signature: term(),
    sparsity_params: term(),
    type: term()
  }
  | nif_error()
```

Get any tensor in the graph by its id

Note that the `tensor_index` here means the id of a tensor. For example,
if `inputs/1` returns `[42, 314]`, then `42` should be passed here to get tensor `42`.

# `tensors_size`

```elixir
@spec tensors_size(reference()) :: non_neg_integer() | nif_error()
```

Return the number of tensors in the model.

# `variables`

```elixir
@spec variables(reference()) :: {:ok, [non_neg_integer()]} | nif_error()
```

Get the list of variable tensors.

---

*Consult [api-reference.md](api-reference.md) for complete listing*
