use crate::layers::*;
#[test]
fn test_qa_012_latency_no_outliers() {
use std::time::Instant;
let mut latencies = Vec::with_capacity(100);
let layer_norm = LayerNorm::new(64, 1e-5).expect("test");
let input = Tensor::from_vec(vec![8, 64], vec![0.1; 512]).expect("test");
for _ in 0..100 {
let start = Instant::now();
let _ = layer_norm.forward(&input).expect("test");
latencies.push(start.elapsed().as_nanos() as f64);
}
latencies.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
let p50 = latencies[49];
let p99 = latencies[98];
assert!(
p50 > 0.0 && p99 > 0.0,
"QA-012: p50 ({:.0}ns) and p99 ({:.0}ns) should be positive",
p50,
p99
);
}
#[test]
fn test_qa_015_no_memory_leaks() {
let layer_norm = LayerNorm::new(128, 1e-5).expect("test");
for cycle in 0..1000 {
let input = Tensor::from_vec(vec![4, 128], vec![0.1; 512]).expect("test");
let output = layer_norm.forward(&input).expect("test");
assert_eq!(output.size(), 512);
drop(output);
drop(input);
if cycle % 100 == 0 {
}
}
}
#[test]
fn test_qa_017_warm_inference_stability() {
use std::time::Instant;
let linear = Linear::new(64, 64).expect("test");
let input = Tensor::from_vec(vec![1, 64], vec![0.1; 64]).expect("test");
for _ in 0..100 {
let _ = linear.forward(&input).expect("test");
}
let mut best_cv = f64::MAX;
for _round in 0..3 {
let mut steady_latencies = Vec::with_capacity(50);
for _ in 0..50 {
let start = Instant::now();
let _ = linear.forward(&input).expect("test");
steady_latencies.push(start.elapsed().as_nanos() as f64);
}
steady_latencies.sort_by(|a, b| a.partial_cmp(b).unwrap_or(std::cmp::Ordering::Equal));
let trimmed_start = steady_latencies.len() / 10;
let trimmed_end = steady_latencies.len() - trimmed_start;
let trimmed: Vec<f64> = steady_latencies[trimmed_start..trimmed_end].to_vec();
let mean = trimmed.iter().sum::<f64>() / (trimmed.len() as f64);
let variance =
trimmed.iter().map(|x| (x - mean).powi(2)).sum::<f64>() / (trimmed.len() as f64);
let std_dev = variance.sqrt();
let cv = std_dev / mean;
if cv < best_cv {
best_cv = cv;
}
}
assert!(
best_cv < 3.0,
"QA-017: Coefficient of variation ({:.2}) should be < 3.0 for stable inference",
best_cv
);
}
#[test]
fn test_qa_019_generation_rate_stability() {
use std::time::Instant;
let attention = Attention::new(32).expect("test");
let seq_len = 16;
let q = Tensor::from_vec(vec![seq_len, 32], vec![0.1; seq_len * 32]).expect("test");
let k = q.clone();
let v = q.clone();
let mut times = Vec::with_capacity(20);
for _ in 0..20 {
let start = Instant::now();
let _ = attention.forward(&q, &k, &v).expect("test");
times.push(start.elapsed().as_nanos() as f64);
}
let mean = times.iter().sum::<f64>() / (times.len() as f64);
let variance = times.iter().map(|x| (x - mean).powi(2)).sum::<f64>() / (times.len() as f64);
let cv = variance.sqrt() / mean;
assert!(
cv.is_finite() && cv > 0.0,
"QA-019: Generation CV ({:.2}) should be finite and positive",
cv
);
}
#[test]
fn test_qa_025_no_panic_empty_input() {
let layer_norm = LayerNorm::new(64, 1e-5).expect("test");
let empty_tensor_result = Tensor::<f32>::from_vec(vec![0, 64], vec![]);
assert!(
empty_tensor_result.is_err(),
"QA-025: Zero-dimension tensor should error"
);
let embedding = Embedding::new(100, 64).expect("test");
let empty_ids: &[usize] = &[];
let embed_result = embedding.forward(empty_ids);
if let Ok(output) = embed_result {
assert_eq!(
output.size(),
0,
"QA-025: Empty input should give empty output"
);
}
let single_val = Tensor::from_vec(vec![1], vec![1.0_f32]).expect("test");
let softmax_result = softmax(&single_val);
assert!(
softmax_result.is_ok(),
"QA-025: Softmax on single value should not panic"
);
let min_input = Tensor::from_vec(vec![1, 64], vec![0.0_f32; 64]).expect("test");
let ln_result = layer_norm.forward(&min_input);
assert!(
ln_result.is_ok(),
"QA-025: LayerNorm on minimal input should not panic"
);
}
#[test]
fn test_qa_027_special_token_handling() {
let vocab_size = 1000;
let embed_dim = 64;
let embedding = Embedding::new(vocab_size, embed_dim).expect("test");
let bos_result = embedding.forward(&[1]);
assert!(
bos_result.is_ok(),
"QA-027: BOS token should embed correctly"
);
let eos_result = embedding.forward(&[2]);
assert!(
eos_result.is_ok(),
"QA-027: EOS token should embed correctly"
);
let pad_result = embedding.forward(&[0]);
assert!(
pad_result.is_ok(),
"QA-027: PAD token should embed correctly"
);
let invalid_result = embedding.forward(&[vocab_size + 1]);
assert!(
invalid_result.is_err(),
"QA-027: Invalid token ID should error"
);
}
#[test]
fn test_qa_029_deterministic_output() {
let attention = Attention::new(16).expect("test");
let q =
Tensor::from_vec(vec![4, 16], (0..64).map(|i| i as f32 * 0.01).collect()).expect("test");
let k = q.clone();
let v = q.clone();
let output1 = attention.forward(&q, &k, &v).expect("test");
let output2 = attention.forward(&q, &k, &v).expect("test");
assert_eq!(
output1.data(),
output2.data(),
"QA-029: Identical inputs should produce identical outputs"
);
}
#[test]
fn test_qa_030_consistent_results() {
let layer_norm = LayerNorm::new(32, 1e-5).expect("test");
let input =
Tensor::from_vec(vec![2, 32], (0..64).map(|i| i as f32 * 0.1).collect()).expect("test");
let results: Vec<_> = (0..5)
.map(|_| layer_norm.forward(&input).expect("test"))
.collect();
for (i, result) in results.iter().enumerate().skip(1) {
for (j, (a, b)) in result
.data()
.iter()
.zip(results[0].data().iter())
.enumerate()
{
assert!(
(a - b).abs() < 1e-10,
"QA-030: Run {} element {} differs: {} vs {}",
i,
j,
a,
b
);
}
}
}
#[test]
fn test_qa_001_deterministic_inference() {
let config = ModelConfig {
vocab_size: 100,
hidden_dim: 64,
num_heads: 4,
num_layers: 2,
intermediate_dim: 256,
eps: 1e-5,
};
let model = Model::new(config).expect("test");
let input_ids = vec![1, 2, 3, 4, 5];
let output1 = model.forward(&input_ids).expect("test");
let output2 = model.forward(&input_ids).expect("test");
assert_eq!(
output1.shape(),
output2.shape(),
"QA-001: Output shapes must match"
);
for (i, (a, b)) in output1.data().iter().zip(output2.data().iter()).enumerate() {
assert!(
(a - b).abs() < 1e-10,
"QA-001: Output element {} differs: {} vs {}",
i,
a,
b
);
}
}
#[test]
fn test_qa_002_tokenization_determinism() {
use crate::tokenizer::{Tokenizer, Vocabulary};
let vocab = Vocabulary::from_tokens(vec![
"<unk>".to_string(),
"hello".to_string(),
"world".to_string(),
"this".to_string(),
"is".to_string(),
"a".to_string(),
"test".to_string(),
])
.expect("test");
let tokenizer = Tokenizer::new(vocab, "<unk>").expect("test");
let text = "hello world this is a test";
let tokens1 = tokenizer.encode(text);
let tokens2 = tokenizer.encode(text);
let tokens3 = tokenizer.encode(text);
assert_eq!(
tokens1, tokens2,
"QA-002: Tokenization must be deterministic"
);
assert_eq!(
tokens2, tokens3,
"QA-002: Tokenization must be deterministic"
);
let decoded1 = tokenizer.decode(&tokens1);
let decoded2 = tokenizer.decode(&tokens2);
assert_eq!(
decoded1, decoded2,
"QA-002: Detokenization must be deterministic"
);
}
#[test]
fn test_qa_008_swiglu_activation_correctness() {
let ffn = FeedForward::new(32, 128).expect("test");
let input = Tensor::from_vec(
vec![2, 32],
(0..64).map(|i| (i as f32 * 0.1) - 3.2).collect(),
)
.expect("test");
let output = ffn.forward(&input).expect("test");
assert_eq!(output.shape(), input.shape(), "QA-008: FFN preserves shape");
for (i, &val) in output.data().iter().enumerate() {
assert!(
val.is_finite(),
"QA-008: FFN output {} should be finite, got {}",
i,
val
);
}
let output2 = ffn.forward(&input).expect("test");
for (i, (a, b)) in output.data().iter().zip(output2.data().iter()).enumerate() {
assert!(
(a - b).abs() < 1e-10,
"QA-008: FFN output {} differs: {} vs {}",
i,
a,
b
);
}
}
include!("qa_perf_tests.rs");
include!("imp_001.rs");
include!("imp_013.rs");