Native Acceleration
View Sourcefaber_tweann ships Rust NIFs for its numeric hot paths. They are part of the package and are built from source during compilation. There is no separate edition, no private repository, and nothing to enable.
Prior to v2.0.0 these NIFs lived in a separate
faber-nn-nifspackage described as an "enterprise" add-on. That package has been absorbed. If you depended onfaber_nn_nifsdirectly, depend onfaber_tweanninstead.
Requirements
A Rust toolchain must be available at compile time.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | shThe build never downloads prebuilt artifacts. Prebuilt shared objects couple a package to a specific glibc, which has caused deployment failures elsewhere in this ecosystem.
Selecting an implementation
Two implementations exist for the same numeric surface:
| Implementation | Module | Use |
|---|---|---|
| Native | faber_nn_nifs | Default. |
| Pure Erlang | tweann_nif_fallback | Platforms without Rust, and differential testing. |
Select with application environment:
%% sys.config
[{faber_tweann, [{nif_impl, nif}]}]. %% default, require native
[{faber_tweann, [{nif_impl, fallback}]}]. %% require pure Erlangnif is the default. If the native library is missing or fails to load,
faber_tweann raises on first use with an explanatory error. It does not
quietly fall back.
That is deliberate. Silent fallback means a system that keeps running, slower and potentially differently, with no log line saying so. This package previously auto-detected and fell back without notice, and as a result the native path was never exercised in its own test suite: two implementations drifted apart for months while every test passed.
To build without Rust:
FABER_TWEANN_SKIP_NIF=1 rebar3 compileThen set {nif_impl, fallback} at runtime. Skipping the build without setting
this will raise, by design.
Reporting the active path
tweann_nif:impl(). %% faber_nn_nifs | tweann_nif_fallback
tweann_nif:is_loaded(). %% true when nativeRecord tweann_nif:impl() in any benchmark or experiment log. A performance
number that does not name its execution path is not a number.
Keeping the two implementations honest
test/unit/nif_fallback_conformance_tests.erl runs both implementations over
the same inputs and asserts they agree.
When adding a function that has both a native and a fallback implementation,
add a case there. Testing each side against its own expectations is what
allowed weight_distance_l1/2 to compute Manhattan distance in Erlang and
mean absolute deviation in Rust, both under the same name, with both test
suites green.
Performance
This guide previously quoted speedup figures. They are not reproduced here, because no committed measurement supported them and the two packages quoted mutually inconsistent numbers.
Measured figures will be added once a benchmark harness runs and its output is
committed. Until then, test/benchmark/bench_nif_vs_erlang.erl exists and can
be run directly.