| Crates.io | scirs2-autograd |
| lib.rs | scirs2-autograd |
| version | 0.1.0-beta.2 |
| created_at | 2025-04-12 11:23:53.309365+00 |
| updated_at | 2025-09-20 08:32:08.544255+00 |
| description | Automatic differentiation module for SciRS2 (scirs2-autograd) |
| homepage | |
| repository | https://github.com/cool-japan/scirs |
| max_upload_size | |
| id | 1630831 |
| size | 2,389,023 |
Production-Ready Automatic Differentiation for Rust
A high-performance automatic differentiation library for SciRS2, providing functionality comparable to PyTorch/TensorFlow's autograd systems with native Rust performance and safety guarantees.
Add to your Cargo.toml:
[dependencies]
scirs2-autograd = "0.1.0-beta.2"
Enable performance optimizations and additional backends:
[dependencies]
scirs2-autograd = { version = "0.1.0-beta.2", features = ["blas", "simd"] }
Available Features:
blas - BLAS acceleration for linear algebra operationsopenblas - OpenBLAS backendintel-mkl - Intel MKL backend for maximum performancesimd - SIMD acceleration for element-wise operationsuse scirs2_autograd::{run, tensor_ops as T};
// Compute gradients of z = 2x² + 3y + 1
run(|ctx| {
let x = ctx.placeholder("x", &[]);
let y = ctx.placeholder("y", &[]);
let z = 2.0 * x * x + 3.0 * y + 1.0;
// First-order gradients
let dz_dy = &T::grad(&[z], &[y])[0];
println!("dz/dy = {:?}", dz_dy.eval(ctx)); // => 3.0
let dz_dx = &T::grad(&[z], &[x])[0];
let x_val = scirs2_autograd::ndarray::arr0(2.0);
let result = ctx.evaluator()
.push(dz_dx)
.feed(x, x_val.view())
.run()[0];
println!("dz/dx at x=2 = {:?}", result); // => 8.0
// Higher-order derivatives
let d2z_dx2 = &T::grad(&[dz_dx], &[x])[0];
println!("d²z/dx² = {:?}", d2z_dx2.eval(ctx)); // => 4.0
});
use scirs2_autograd::{tensor_ops::*, VariableEnvironment};
use scirs2_autograd::optimizers::adam::Adam;
// Build a 2-layer MLP for classification
let mut env = VariableEnvironment::new();
let mut rng = scirs2_autograd::ndarray_ext::ArrayRng::<f32>::default();
// Initialize network parameters
env.name("w1").set(rng.glorot_uniform(&[784, 128]));
env.name("b1").set(zeros(&[1, 128]));
env.name("w2").set(rng.glorot_uniform(&[128, 10]));
env.name("b2").set(zeros(&[1, 10]));
// Setup Adam optimizer
let adam = Adam::default(
"adam_optimizer",
env.default_namespace().current_var_ids(),
&mut env
);
// Training loop
for epoch in 0..100 {
env.run(|ctx| {
// Input placeholders
let x = ctx.placeholder("x", &[-1, 784]); // batch_size Ć 784
let y_true = ctx.placeholder("y", &[-1]); // batch_size
// Load model parameters
let w1 = ctx.variable("w1");
let b1 = ctx.variable("b1");
let w2 = ctx.variable("w2");
let b2 = ctx.variable("b2");
// Forward pass
let hidden = relu(matmul(x, w1) + b1);
let logits = matmul(hidden, w2) + b2;
// Compute loss
let loss = reduce_mean(
sparse_softmax_cross_entropy(logits, &y_true),
&[0],
false
);
// Backpropagation
let params = [w1, b1, w2, b2];
let gradients = &grad(&[loss], ¶ms);
// Parameter updates would be performed here with actual training data
// adam.update(¶ms, gradients, ctx, feeder);
});
}
Gradient checkpointing is a memory optimization technique that trades additional computation time for reduced memory usage during backpropagation. This is especially useful for training large models under memory constraints.
During standard backpropagation, all intermediate activations must be stored to compute gradients, which can lead to high memory usage in deep networks. Gradient checkpointing selectively discards intermediate activations during the forward pass and recomputes them during the backward pass as needed.
use scirs2_autograd::{run, tensor_ops as T};
run(|ctx| {
// 1. Basic checkpointing of individual tensors
let input = T::ones(&[128, 128], ctx);
let w = T::ones(&[128, 128], ctx);
let hidden = T::matmul(&input, &w);
let hidden_checkpoint = T::checkpoint(&hidden); // This tensor will be recomputed during backprop
// 2. Adaptive checkpointing based on memory threshold (in bytes)
let large_tensor = T::matmul(&input, &w);
let adaptive_checkpoint = T::adaptive_checkpoint(&large_tensor, 1_000_000); // 1MB threshold
// 3. Checkpoint groups for multi-output operations
let checkpoint_group = T::CheckpointGroup::new(ctx);
let (output1, output2) = checkpoint_group.checkpoint_fn_flex2(&[&input, &w], |inputs| {
let a = T::matmul(&inputs[0], &inputs[1]);
let b = T::transpose(&a, &[1, 0]);
(a, b) // Both tensors will be checkpointed together
});
});
You can measure the memory savings and performance impact of your checkpointing strategy:
// Start tracking memory usage
T::CheckpointProfiler::start_tracking();
// Your model with checkpointing
// ... (model code with checkpoint operations)
// Evaluate performance
println!("Memory saved: {} KB", T::CheckpointProfiler::memory_saved() / 1024);
println!("Checkpoint operations: {}", T::CheckpointProfiler::checkpoint_count());
// Reset for next test
T::CheckpointProfiler::reset_statistics();
Test Coverage: 404 passing tests, 0 failures
Memory Efficiency: Up to 80% reduction with gradient checkpointing
Numerical Stability: Robust implementations for large-scale computations
Performance: SIMD and multi-threading optimizations throughout
SciRS2 Autograd v0.1.0-beta.2 is the first beta release and is production-ready:
This project is dual-licensed under:
You can choose to use either license. See the LICENSE file for details.