tflite_c/lib.rs
1//! # tflite-c-rs
2//!
3//! A small, safe Rust wrapper around the TensorFlow Lite C API that resolves
4//! the shared library at *runtime* with [`libloading`] instead of linking
5//! against it at build time. The crate ships no native code, no `build.rs`,
6//! no `-sys` crate — it dynamically opens a TFLite shared object that you
7//! (or your platform package manager) provide separately, then offers a
8//! tidy, RAII-driven API on top of the resolved C symbols.
9//!
10//! ## Why runtime dynamic loading?
11//!
12//! The TensorFlow Lite C library is famously awkward to link statically:
13//! its build system is Bazel-only, the released prebuilt binaries are
14//! platform-specific, and cross-compilation against it tends to drag the
15//! entire TensorFlow source tree along for the ride. For many real-world
16//! deployments — embedded Linux, edge accelerators, vendor-shipped
17//! NPU stacks — the path of least resistance is to ship the vendor's
18//! prebuilt `.so`/`.dylib`/`.dll` and pick it up at runtime.
19//!
20//! That is exactly what this crate does. It uses `libloading` to `dlopen`
21//! the TFLite C library, caches the symbols it needs, and exposes a small
22//! safe surface (`Model`, `InterpreterOptions`, `Interpreter`, `Tensor`,
23//! `ExternalDelegate`) on top of it.
24//!
25//! ## Quick start
26//!
27//! ```no_run
28//! use tflite_c::{TfLiteLibrary, Model, InterpreterOptions, Interpreter};
29//!
30//! # fn run() -> Result<(), tflite_c::Error> {
31//! let lib = TfLiteLibrary::load_default()?;
32//! let model = Model::from_file("model.tflite", lib.clone())?;
33//!
34//! let mut options = InterpreterOptions::new(lib.clone());
35//! options.num_threads(2);
36//!
37//! let mut interp = Interpreter::new(model, options)?;
38//!
39//! // Fill input 0 with whatever bytes your model expects.
40//! interp.input_mut(0)?.data_mut()?.fill(0);
41//!
42//! interp.invoke()?;
43//!
44//! let out = interp.output(0)?;
45//! let probs = out.to_vec_f32()?;
46//! println!("first prob: {}", probs[0]);
47//! # Ok(()) }
48//! ```
49//!
50//! ## Threading
51//!
52//! [`Interpreter`] is `Send + Sync`, but TensorFlow Lite's C interpreter is
53//! *not* thread-safe in itself. The standard pattern is to share via
54//! `Arc<Mutex<Interpreter>>` (or `Arc<parking_lot::Mutex<Interpreter>>`) and
55//! serialize every call into a given interpreter.
56//!
57//! ## Relationship to the upstream C API
58//!
59//! Type and function names that begin with `TfLite…` come from the upstream
60//! header [`c_api.h`](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/c/c_api.h)
61//! and the external-delegate header
62//! [`c_api_experimental.h`](https://github.com/tensorflow/tensorflow/blob/master/tensorflow/lite/c/c_api_experimental.h).
63//! This crate covers the minimum set required to load a model, run
64//! inference, and read results — enough for v0.0.1.
65
66#![deny(missing_docs)]
67#![deny(unused_imports)]
68#![cfg_attr(docsrs, feature(doc_cfg))]
69
70pub mod error;
71pub mod ffi;
72pub mod interpreter;
73pub mod library;
74pub mod model;
75pub mod tensor;
76
77pub use crate::error::{Error, Result};
78pub use crate::ffi::{TfLiteQuantizationParams, TfLiteStatus, TfLiteType};
79pub use crate::interpreter::{Interpreter, InterpreterOptions};
80pub use crate::library::{ExternalDelegate, ExternalDelegateBuilder, TfLiteLibrary};
81pub use crate::model::Model;
82pub use crate::tensor::{Tensor, TensorMut};