use native_neural_network_std as nn;
use std::sync::{Arc, Mutex};
use std::thread;
use std::time::{Duration, Instant};
fn scale_from_env() -> usize {
std::env::var("STRESS_SCALE")
.ok()
.and_then(|s| s.parse().ok())
.unwrap_or(1)
}
#[test]
fn cpu_backend_abstraction_real() {
let previous = native_neural_network_std::std::engine_std::get_compute_backend();
native_neural_network_std::std::engine_std::set_compute_backend(
native_neural_network_std::std::engine_std::ComputeBackend::Cpu,
);
assert_eq!(
native_neural_network_std::std::engine_std::get_compute_backend(),
native_neural_network_std::std::engine_std::ComputeBackend::Cpu
);
native_neural_network_std::std::engine_std::set_compute_backend(previous);
}
#[test]
fn stress_massive_allocations() {
for cycle in 0..10 {
let mut holders = Vec::with_capacity(8);
for _ in 0..8 {
let n = 100_000_000usize;
let mut v = vec![0f32; n];
for i in (0..n).step_by(10_000_000) {
v[i] = (i as f32).sin();
}
holders.push(v);
}
thread::sleep(Duration::from_millis(500));
drop(holders);
println!("cycle {} completed", cycle);
}
}
#[test]
fn stress_threads_shared_access() {
let cpus = thread::available_parallelism()
.map(|n| n.get())
.unwrap_or(4);
let shared = Arc::new(Mutex::new(vec![0u8; 10_000_000]));
let mut handles = Vec::new();
for _ in 0..(cpus * 4) {
let s = Arc::clone(&shared);
handles.push(thread::spawn(move || {
for _ in 0..100 {
let mut guard = s.lock().unwrap();
guard[0] = guard[0].wrapping_add(1);
drop(guard);
thread::sleep(Duration::from_millis(5));
}
}));
}
for h in handles {
h.join().unwrap();
}
}
#[test]
fn stress_numerical_limits() {
let extremes = [
f32::INFINITY,
f32::NEG_INFINITY,
f32::NAN,
0.0f32,
1e-38f32,
1e38f32,
];
for &x in &extremes {
let add = x + 1.0f32;
let mul = x * 2.0f32;
let sq = x.sqrt();
if x.is_finite() {
assert!(
add.is_finite() && mul.is_finite() && sq.is_finite(),
"finite inputs must produce finite results"
);
} else {
assert!(
!add.is_finite() || !mul.is_finite() || !sq.is_finite(),
"non-finite should propagate non-finites"
);
}
println!("checked {} -> {}, {}, {}", x, add, mul, sq);
}
}
#[test]
fn stress_cpu_oscillation() {
let cpus = thread::available_parallelism()
.map(|n| n.get())
.unwrap_or(4);
let duration = Duration::from_secs(10);
let start = Instant::now();
let mut handles = Vec::new();
for _ in 0..cpus {
handles.push(thread::spawn(move || {
while Instant::now() - start < duration {
let mut acc = 0u64;
for i in 0..5_000_000u64 {
acc = acc.wrapping_add(i);
}
thread::sleep(Duration::from_millis(10));
}
}));
}
for h in handles {
h.join().unwrap();
}
}
#[test]
fn stress_combined_max() {
let cpus = thread::available_parallelism()
.map(|n| n.get())
.unwrap_or(4);
let shared = Arc::new(Mutex::new(Vec::<u8>::new()));
let mut handles = Vec::new();
for _ in 0..cpus {
let s = Arc::clone(&shared);
handles.push(thread::spawn(move || {
for _ in 0..50 {
let v = vec![0u8; 10_000_000];
{
let mut g = s.lock().unwrap();
g.extend_from_slice(&v[0..100]);
}
let mut acc = 0u64;
for i in 0..1_000_000u64 {
acc = acc.wrapping_add(i);
}
drop(v);
thread::sleep(Duration::from_millis(20));
}
}));
}
for h in handles {
h.join().unwrap();
}
}
#[test]
fn stress_alloc_massive_network() {
let scale = scale_from_env();
let base = 512usize.saturating_mul(scale);
let layers = vec![base, base * 2, base * 2, base];
let wcount =
nn::std::network_std::NeuralNetworkStd::expected_weights_count(&layers).unwrap_or(0);
let bcount =
nn::std::network_std::NeuralNetworkStd::expected_biases_count(&layers).unwrap_or(0);
let weights = vec![1f32; wcount];
let biases = vec![0f32; bcount];
let _net = nn::std::network_std::NeuralNetworkStd::from_parts(layers.clone(), weights, biases)
.expect("construct");
}
#[test]
fn stress_alloc_free_cycles() {
let scale = scale_from_env();
let base = 256usize.saturating_mul(scale);
let layers = vec![base, base * 2, base];
let wcount =
nn::std::network_std::NeuralNetworkStd::expected_weights_count(&layers).unwrap_or(0);
let bcount =
nn::std::network_std::NeuralNetworkStd::expected_biases_count(&layers).unwrap_or(0);
for _ in 0..100 {
let weights = vec![0.5f32; wcount];
let biases = vec![0.0f32; bcount];
let net =
nn::std::network_std::NeuralNetworkStd::from_parts(layers.clone(), weights, biases)
.expect("construct");
nn::std::network_std::validate_network_parts(&net.layers, &net.weights, &net.biases);
nn::std::network_std::network_stats(&net.layers, &net.weights, &net.biases);
drop(net);
}
}
#[test]
fn stress_kv_cache_saturation() {
let max_tokens = 50_000usize;
let head_dim = 64usize;
let num_heads = 8usize;
let mut kv = nn::std::kv_cache_std::KvCacheStd::new(max_tokens, head_dim, num_heads);
let stride = head_dim * num_heads;
let token = vec![1f32; stride];
for i in 0..(max_tokens + 5) {
let res = kv.append_token(&token, &token);
if i < max_tokens {
assert!(res.is_ok());
} else {
assert!(res.is_err());
}
}
}
#[test]
fn stress_multithread_forward() {
let scale = scale_from_env();
let base = 128usize.saturating_mul(scale);
let layers = vec![base, base * 2, base];
let wcount =
nn::std::network_std::NeuralNetworkStd::expected_weights_count(&layers).unwrap_or(0);
let bcount =
nn::std::network_std::NeuralNetworkStd::expected_biases_count(&layers).unwrap_or(0);
let weights = vec![0.1f32; wcount];
let biases = vec![0f32; bcount];
let net = Arc::new(
nn::std::network_std::NeuralNetworkStd::from_parts(layers.clone(), weights, biases)
.expect("construct"),
);
let threads = thread::available_parallelism()
.map(|n| n.get())
.unwrap_or(4)
.saturating_mul(2);
let mut handles = Vec::new();
for _ in 0..threads {
let net = Arc::clone(&net);
let layers = layers.clone();
handles.push(thread::spawn(move || {
for _ in 0..100 {
nn::std::network_std::validate_network_parts(&layers, &net.weights, &net.biases);
}
}));
}
for h in handles {
h.join().unwrap();
}
}
#[test]
fn stress_numeric_extremes() {
let scale = scale_from_env();
let base = 64usize.saturating_mul(scale);
let layers = vec![base, base * 2, base];
let wcount =
nn::std::network_std::NeuralNetworkStd::expected_weights_count(&layers).unwrap_or(0);
let bcount =
nn::std::network_std::NeuralNetworkStd::expected_biases_count(&layers).unwrap_or(0);
let mut weights = vec![1f32; wcount];
let mut biases = vec![0f32; bcount];
if !weights.is_empty() {
weights[0] = f32::INFINITY;
}
if biases.len() > 1 {
biases[1] = f32::NAN;
}
let net = nn::std::network_std::NeuralNetworkStd::from_parts(layers.clone(), weights, biases)
.expect("construct");
nn::std::network_std::validate_network_parts(&net.layers, &net.weights, &net.biases);
nn::std::network_std::network_stats(&net.layers, &net.weights, &net.biases);
}