Agent Notes (rust-mlp)
This file is for agentic coding tools operating in this repository.
Repo snapshot:
- Rust edition: 2024 (
Cargo.toml) - Crate:
rust-mlp(library-first;src/main.rsis a tiny helper binary) - Core focus: small MLP (dense layers + tanh), allocation-free per-sample hot path
Commands (Build / Lint / Test)
CI runs (see .github/workflows/ci.yml):
cargo fmt --check
cargo clippy --all-targets --all-features -- -D warnings
cargo test --all-targets --all-features
Common local commands:
# Fast compile check
cargo check
# Build
cargo build
cargo build --release
# Format
cargo fmt
# Lint (match CI)
cargo clippy --all-targets --all-features -- -D warnings
# Tests
cargo test
# Docs
cargo doc --open
Run a single unit test (recommended patterns):
# Substring match (fastest to type)
cargo test backward_matches_numeric_gradients
# Exact match (best for disambiguation)
cargo test mlp::tests::backward_matches_numeric_gradients -- --exact
# Show stdout/stderr
cargo test mlp::tests::backward_matches_numeric_gradients -- --exact --nocapture
# Run tests matching a module/file
cargo test layer::tests::
Note: cargo test --all-targets will also build/run benches and examples as test targets.
Use plain cargo test for the tight inner loop.
Examples: cargo run --example tanh_sum
Benchmarks (Criterion):
cargo bench
cargo bench --bench mlp -- mlp_forward
Code Style and Conventions
Formatting
- Use
rustfmt(no custom config in this repo). Runcargo fmtbefore finalizing changes. - Keep lines readable; let rustfmt handle wrapping.
Imports
- Prefer grouping imports by origin (typical order):
std::..., external crates, thencrate::.... - Prefer
{}import lists for multiple items:use crate::{Error, Result};. use super::*;is fine inside#[cfg(test)] mod tests.
Types and Numerics
- Scalars are
f32throughout the crate. - Dimensions/indices use
usize(in_dim,out_dim,input_dim,target_dim,len). - Deterministic seeds use
u64andStdRng::seed_from_u64. - Prefer
mul_addin inner loops where it is already used (dot products). - Keep weight/data layout decisions consistent:
- Layer weights: row-major
(out_dim, in_dim)contiguousVec<f32>. - Dataset/inputs: row-major contiguous buffers.
- Layer weights: row-major
Naming
- Types:
PascalCase(Mlp,Layer,Scratch,Gradients,FitConfig). - Methods/vars:
snake_case. - Gradients use
d_prefix (d_weights,d_biases,d_input,d_output). - Use
idxfor indices in loops; uselen()for counts.
API Layers (Panics vs Result)
The crate intentionally has two layers of API:
-
Low-level, allocation-free hot path:
Mlp::forward,Mlp::backward,Mlp::sgd_stepLayer::forward,Layer::backward,Layer::sgd_step- loss helpers (e.g.
loss::mse_backward) These treat shape mismatches as programmer error and MUST panic on misuse. Useassert!/assert_eq!with clear messages (expected vs actual).
-
High-level convenience APIs:
Mlp::fit,Mlp::predict,Mlp::predict_inputs,Mlp::evaluate_mseThese validate inputs and returnResultwithError::InvalidData/Error::InvalidConfig.
Avoid adding duplicate "try_*" APIs; keep one obvious way to do things.
Error Handling
- Use the crate error types:
crate::Result<T>andcrate::Error(src/error.rs). - Use:
Error::InvalidConfigfor hyperparameters/model configuration (e.g.epochs == 0,lr <= 0).Error::InvalidDatafor dataset/inputs issues (empty sets, dimension mismatch, bad shapes).
- Prefer actionable error strings that include the offending values.
Performance Guidelines
- Hot paths should be allocation-free when buffers are reused.
- Use
ScratchandGradientsfromMlp::scratch()/Mlp::gradients(). - Avoid creating temporary
Vecs inside per-sample loops.
- Use
- Use
Vec::with_capacitywhen building contiguous buffers.
Tests
- Keep tests deterministic (use fixed seeds).
- Numerical gradient checks exist; keep tolerances reasonable and avoid flakiness.
- Panic tests (
#[should_panic]) should be minimal and fast.
Documentation
- Each module uses a short
//!module doc at the top. - Public types/functions should have rustdoc comments, especially describing:
- shape contracts
- overwrite vs accumulation semantics
- panic vs
Resultbehavior
Cursor / Copilot Instructions
No Cursor rules were found (.cursor/rules/ or .cursorrules).
No Copilot instructions were found (.github/copilot-instructions.md).