#store #validation #floretta

floretta

Automatic differentiation for WebAssembly

6 releases (breaking)

0.5.0 Apr 22, 2025
0.4.0 Feb 20, 2025
0.3.0 Jan 21, 2025
0.2.0 Nov 22, 2024
0.0.0 Nov 19, 2024

#2140 in Rust patterns

Download history 89/week @ 2025-02-05 427/week @ 2025-02-12 376/week @ 2025-02-19 428/week @ 2025-02-26 345/week @ 2025-03-05 313/week @ 2025-03-12 270/week @ 2025-03-19 171/week @ 2025-03-26 203/week @ 2025-04-02 209/week @ 2025-04-09 454/week @ 2025-04-16 70/week @ 2025-04-23 1/week @ 2025-04-30 22/week @ 2025-05-07 17/week @ 2025-05-14

197 downloads per month
Used in floretta-cli

MIT license

200KB
6K SLoC

Rust 5K SLoC // 0.0% comments WebAssembly 1K SLoC

Floretta

Floretta is an automatic differentiation tool for WebAssembly. This crate is the Rust library; for the command line interface, see the floretta-cli crate.

To install:

cargo add floretta

Here are some usage examples, assuming you have wat and Wasmtime installed.

Forward mode

Use Autodiff::new to create an empty config, then use Autodiff::forward to transform a Wasm module to compute derivatives in forward mode.

use floretta::Autodiff;
use wasmtime::{Engine, Instance, Module, Store};

let input = wat::parse_str(r#"
(module
  (func (export "square") (param f64) (result f64)
    (f64.mul (local.get 0) (local.get 0))))
"#).unwrap();

let output = Autodiff::new().forward(&input).unwrap();

let engine = Engine::default();
let mut store = Store::new(&engine, ());
let module = Module::new(&engine, &output).unwrap();
let instance = Instance::new(&mut store, &module, &[]).unwrap();
let square = instance.get_typed_func::<(f64, f64), (f64, f64)>(&mut store, "square").unwrap();

assert_eq!(square.call(&mut store, (3., 1.)).unwrap(), (9., 6.));

Reverse mode

Create an empty config via Autodiff::new, use Autodiff::export to specify one or more functions to export the backward pass, and then use Autodiff::reverse to transform a Wasm module to compute derivatives in reverse mode.

use floretta::Autodiff;
use wasmtime::{Engine, Instance, Module, Store};

let input = wat::parse_str(r#"
(module
  (func (export "square") (param f64) (result f64)
    (f64.mul (local.get 0) (local.get 0))))
"#).unwrap();

let mut ad = Autodiff::new();
ad.export("square", "backprop");
let output = ad.reverse(&input).unwrap();

let engine = Engine::default();
let mut store = Store::new(&engine, ());
let module = Module::new(&engine, &output).unwrap();
let instance = Instance::new(&mut store, &module, &[]).unwrap();
let square = instance.get_typed_func::<f64, f64>(&mut store, "square").unwrap();
let backprop = instance.get_typed_func::<f64, f64>(&mut store, "backprop").unwrap();

assert_eq!(square.call(&mut store, 3.).unwrap(), 9.);
assert_eq!(backprop.call(&mut store, 1.).unwrap(), 6.);

Dependencies

~6.5MB
~123K SLoC