1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
// some new clippy::lint annotations are supported in latest Rust but not recognized by older versions
//! Bindings for ExecuTorch - On-device AI across mobile, embedded and edge for PyTorch.
//!
//! Provides a high-level Rust API for executing PyTorch models on mobile, embedded and edge devices using the
//! [ExecuTorch library](https://pytorch.org/executorch-overview), specifically the
//! [C++ API](https://github.com/pytorch/executorch).
//! PyTorch models are created and exported in Python, and then loaded and executed on-device using the
//! ExecuTorch library.
//!
//! The following example create a simple model in Python, exports it, and then executes it in Rust:
//!
//! Create a model in Python and export it:
//! ```ignore
//! import torch
//! from torch.export import export
//! from executorch.exir import to_edge_transform_and_lower
//!
//! class Add(torch.nn.Module):
//! def __init__(self):
//! super(Add, self).__init__()
//!
//! def forward(self, x: torch.Tensor, y: torch.Tensor):
//! return x + y
//!
//!
//! model = Add()
//! exported_program = export(model, (torch.ones(1), torch.ones(1)))
//! executorch_program = to_edge_transform_and_lower(exported_program).to_executorch()
//! with open("model.pte", "wb") as file:
//! file.write(executorch_program.buffer)
//! ```
//!
//! Execute the model in Rust:
//! ```rust,ignore
//! use executorch::evalue::{EValue, IntoEValue};
//! use executorch::module::Module;
//! use executorch::tensor_ptr;
//! use ndarray::array;
//!
//! let mut module = Module::new("model.pte");
//!
//! let (tensor1, tensor2) = (tensor_ptr![1.0_f32], tensor_ptr![1.0_f32]);
//! let inputs = [tensor1.into_evalue(), tensor2.into_evalue()];
//!
//! let outputs = module.forward(&inputs).unwrap();
//! let [output]: [EValue; 1] = outputs.try_into().expect("not a single output");
//! let output = output.as_tensor().into_typed::<f32>();
//!
//! println!("Output tensor computed: {:?}", output);
//! assert_eq!(array![2.0], output.as_array());
//! ```
//!
//! ## Cargo Features
//! - `data-loader`:
//! Includes additional structs in the [`data_loader`] module for loading data. Without this feature the only
//! available data loader is [`BufferDataLoader`](data_loader::BufferDataLoader). The `libextension_data_loader.a` static library is
//! required, compile C++ `executorch` with `EXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON`.
//! - `module`:
//! Includes the [`module`] API, a high-level API for loading and executing PyTorch models. It is an alternative to
//! the lower-level [`Program`](crate::program::Program) API, which is more suitable for embedded systems.
//! The `libextension_module_static.a` static library is required, compile C++ `executorch` with
//! `EXECUTORCH_BUILD_EXTENSION_MODULE=ON`.
//! Also includes the `std`, `data-loader` and `flat-tensor` features.
//! - `tensor-ptr`:
//! Includes the [`tensor::TensorPtr`] struct, a smart pointer for tensors that manage the lifetime of the tensor
//! object alongside the lifetimes of the data buffer and additional metadata. The `extension_tensor.a`
//! static library is required, compile C++ `executorch` with `EXECUTORCH_BUILD_EXTENSION_TENSOR=ON`.
//! Also includes the `std` feature.
//! - `flat-tensor`:
//! Includes the [`data_map::FlatTensorDataMap`] struct that can read `.ptd` files with external tensors for models.
//! The `libextension_flat_tensor.a` static library is required,
//! compile C++ `executorch` with `EXECUTORCH_BUILD_EXTENSION_FLAT_TENSOR=ON`.
//! - `etdump`:
//! Includes the [`event_tracer::ETDumpGen`] struct, an implementation of an `EventTracer`, used for debugging and profiling.
//! The `libetdump.a` static library is required, compile C++ `executorch` with `EXECUTORCH_BUILD_DEVTOOLS=ON` and
//! `EXECUTORCH_ENABLE_EVENT_TRACER=ON`.
//! In addition, the `flatcc` (or `flatcc_d`) library is required, available at `{CMAKE_DIR}/third-party/flatcc_ep/lib/`,
//! and should be linked by the user.
//! - `ndarray`:
//! Conversions between `executorch` tensors and `ndarray` arrays.
//! Adds a dependency to the `ndarray` crate.
//! This feature is enabled by default.
//! - `f16`:
//! Adds a dependency to the `half` crate, which provides a fully capable `f16` and `bf16` types.
//! Without this feature enabled, both of these types are available with a simple conversions to/from `u16` only.
//! Note that this only affect input/output tensors, the internal computations always have the capability to operate on such scalars.
//! - `num-complex`:
//! Adds a dependency to the `num-complex` crate, which provides a fully capable complex number type.
//! Without this feature enabled, complex numbers are available as a simple struct with two public fields without any operations.
//! Note that this only affect input/output tensors, the internal computations always have the capability to operate on such scalars.
//! - `std`:
//! Enable the standard library. This feature is enabled by default, but can be disabled to build [`executorch`](crate)
//! in a `no_std` environment.
//! See the `examples/no_std` example.
//! Also includes the `alloc` feature.
//! NOTE: no_std is still WIP, see <https://github.com/pytorch/executorch/issues/4561>
//! - `alloc`:
//! Enable allocations.
//! When this feature is disabled, all methods that require allocations will not be compiled.
//! This feature is enabled by the `std` feature, which is enabled by default.
//! Its possible to enable this feature without the `std` feature, and the allocations will be done using the
//! [`alloc`](https://doc.rust-lang.org/alloc/) crate, that requires a global allocator to be set.
//!
//! By default the `std` and `ndarray` features are enabled.
//!
//! ## Build
//! To use the library you must compile the C++ executorch library yourself, as there are many configurations that
//! determines which modules, backends, and operations are supported. See the `executorch-sys` crate for more info.
//! Currently the supported Cpp executorch version is `1.1.0`.
//!
//! ## Embedded Systems
//! The library is designed to be used both in `std` and `no_std` environments. The `no_std` environment is useful for
//! embedded systems, where the standard library is not available. The `alloc` feature can be used to provide an
//! alternative to the standard library's allocator, but it is possible to use the library without allocations at all.
//! Due to some difference between Cpp and Rust, it is not trivial to provide such API, and the interface may feel
//! more verbose. See the `memory::Storage` struct for stack allocations of Cpp objects, and the `examples/no_std`
//! example.
extern crate core as std;
use cratealloc;
/// The version of the crate.
pub const VERSION: &str = env!;
/// The version of the ExecuTorch C++ library that this crate is compatible and linked with.
pub const EXECUTORCH_CPP_VERSION: &str = EXECUTORCH_CPP_VERSION;
pub
pub use Error;
pub use Result;
pub use ndarray;
pub use half;
pub use num_complex;