gradcheck 0.1.0

Finite-difference gradient checking for Rust ML frameworks. Verifies an autodiff engine against an independent numerical oracle, with a negative control that must fail.
// gradcheck — finite-difference gradient checking for Rust ML frameworks.
// Copyright (c) 2026 Henos D <henosd19@gmail.com> (GitHub: @4ktLuffy)
// Repository: https://github.com/4ktLuffy/gradcheck
// SPDX-License-Identifier: MIT OR Apache-2.0

//! Isolating why the shape sweep did not reproduce burn#5304.
#![cfg(feature = "burn")]
use gradcheck::{adapters::burn::Burn, gradcheck, Config};

#[test]
fn probe_5304_exact_original_conditions() {
    // The exact data and expression from the probe that originally caught the bug.
    let d = vec![0.7f64, -1.3, 2.1, -0.4, 1.9, -3.2];
    for step in [1e-2, 1e-3] {
        let c = Config::f32_defaults().with_step(step);
        let r = gradcheck::<Burn<2>, _>(
            &format!("matmul_t step={step}"),
            &d,
            &[2, 3],
            |t| t.clone().matmul(t.transpose()),
            &c,
        );
        println!("PROBE {r}");
        let r2 = gradcheck::<Burn<2>, _>(
            &format!("transposed_lhs step={step}"),
            &d,
            &[2, 3],
            |t| t.clone().transpose().matmul(t),
            &c,
        );
        println!("PROBE {r2}");
    }
}

#[test]
fn probe_forward_directly() {
    use gradcheck::Backend;
    // Forward only: does THIS build of burn-cpu even have the #5304 defect?
    // truth for a[m,k].T @ b[m,n] computed in plain Rust.
    let a = vec![0.7f64, -1.3, 2.1, -0.4, 1.9, -3.2]; // [2,3]
    let (m, k, n) = (2usize, 3usize, 2usize);
    let b = vec![1.0f64; m * n];
    let mut truth = vec![0f64; k * n];
    for x in 0..k {
        for y in 0..n {
            let mut acc = 0.0;
            for i in 0..m {
                acc += a[i * k + x] * b[i * n + y];
            }
            truth[x * n + y] = acc;
        }
    }
    let av = <Burn<2> as Backend>::from_slice(&a, &[m, k]);
    let bv = <Burn<2> as Backend>::from_slice(&b, &[m, n]);
    let got = <Burn<2> as Backend>::to_vec(&av.transpose().matmul(bv));
    println!("FWD got   = {got:?}");
    println!("FWD truth = {truth:?}");
    let err = got
        .iter()
        .zip(truth.iter())
        .map(|(x, t)| (x - t).abs())
        .fold(0.0f64, f64::max);
    println!(
        "FWD max_abs_err = {err:.6}  -> {}",
        if err > 1e-3 {
            "DEFECT PRESENT"
        } else {
            "forward is correct in this build"
        }
    );
}