ExecuTorch-rs
executorch
is a Rust library for executing PyTorch models in Rust.
It is a Rust wrapper around the ExecuTorch C++ API.
It depends on version 0.3.0
of the CPP API, but will advance as the API does.
The underlying C++ library is still in alpha, and its API is subject to change together with the Rust API.
Usage
Create a model in Python
and export it:
return +
=
=
=
Execute the model in Rust:
use ;
use Module;
use ;
use array;
let mut module = new;
let input_array1 = new;
let input_tensor1 = input_array1.to_tensor_impl;
let input_evalue1 = from_tensor;
let input_array2 = new;
let input_tensor2 = input_array2.to_tensor_impl;
let input_evalue2 = from_tensor;
let outputs = module.forward.unwrap;
assert_eq!;
let output = outputs.into_iter.next.unwrap;
assert_eq!;
let output = output.as_tensor;
println!;
assert_eq!;
See example/hello_world_add
and example/hello_world_add_no_std
for the complete examples.
Build
To build the library, you need to build the C++ library first.
The C++ library allow for great flexibility with many flags, customizing which modules, kernels, and extensions are built.
Multiple static libraries are built, and the Rust library links to them.
In the following example we build the C++ library with the necessary flags to run example hello_world_add
:
# Clone the C++ library
# Install requirements
# Build C++ library
&&
# Static libraries are in cmake-out/
# core:
# cmake-out/libexecutorch.a
# cmake-out/libexecutorch_no_prim_ops.a
# kernels implementations:
# cmake-out/kernels/portable/libportable_ops_lib.a
# cmake-out/kernels/portable/libportable_kernels.a
# extension data loader, enabled with EXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON:
# cmake-out/extension/data_loader/libextension_data_loader.a
# extension module, enabled with EXECUTORCH_BUILD_EXTENSION_MODULE=ON:
# cmake-out/extension/module/libextension_module_static.a
# Run example
# We set EXECUTORCH_RS_EXECUTORCH_LIB_DIR to the path of the C++ build output
EXECUTORCH_RS_EXECUTORCH_LIB_DIR= /executorch/cmake-out
The executorch
crate will always look for the following static libraries:
libexecutorch.a
libexecutorch_no_prim_ops.a
Additional libs are required if feature flags are enabled (see next section):
libextension_data_loader.a
libextension_module_static.a
The static libraries of the kernels implementations are required only if your model uses them, and they should be linked manually by the binary that uses the executorch
crate.
For example, the hello_world_add
example uses a model with a single addition operation, so it compile the C++ library with DEXECUTORCH_SELECT_OPS_LIST=aten::add.out
and contain the following lines in its build.rs
:
println!;
println!;
let libs_dir = var.unwrap;
println!;
Note that the portable_ops_lib
is linked with +whole-archive
to ensure that all symbols are included in the binary.
Cargo Features
-
data-loader
include the
FileDataLoader
struct. Thelibextension_data_loader.a
static library is required, compile C++executorch
withEXECUTORCH_BUILD_EXTENSION_DATA_LOADER=ON
. -
module
include the
Module
struct. Thelibextension_module_static.a
static library is required, compile C++executorch
withEXECUTORCH_BUILD_EXTENSION_MODULE=ON
. Also includes thestd
feature. -
f16
Support for half precision floating point numbers using the
half
crate. Models that require input or output tensors withf16
data type can be operated on with this features. -
complex
Support for complex numbers using the
num-complex
crate. Models that require input or output tensors with complex32
or64
bit floating point numbers can be operated on with this feature. If in addition thef16
feature is enabled, complex numbers with half precision can be used. -
std
Enable the standard library. This feature is enabled by default, but can be disabled to build
executorch
in ano_std
environment. See thehello_world_add_no_std
example. Also includes thealloc
feature. -
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 thestd
feature, and the allocations will be done using thealloc
crate, that requires a global allocator to be set.
By default the std
feature is enabled.