#[derive(Debug, Clone)]
pub struct BatchConfig {
pub max_batch_size: usize,
pub max_seq_len: usize,
pub chunk_size: usize,
pub prefill_reserve_pages: usize,
}
impl Default for BatchConfig {
fn default() -> Self {
Self {
max_batch_size: 32,
max_seq_len: 4096,
chunk_size: 512,
prefill_reserve_pages: 8,
}
}
}
impl BatchConfig {
pub fn validate(&self) -> Result<(), String> {
if self.max_batch_size == 0 {
return Err("max_batch_size must be > 0".into());
}
if self.max_seq_len == 0 {
return Err("max_seq_len must be > 0".into());
}
if self.chunk_size == 0 {
return Err("chunk_size must be > 0".into());
}
if self.chunk_size > 512 {
return Err(format!(
"chunk_size {} exceeds 512-token safety limit (ADR-048 R3: Metal device timeout)",
self.chunk_size
));
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn default_config_is_valid() {
assert!(BatchConfig::default().validate().is_ok());
}
#[test]
fn zero_batch_size_is_invalid() {
let cfg = BatchConfig {
max_batch_size: 0,
..Default::default()
};
assert!(cfg.validate().is_err());
}
#[test]
fn zero_chunk_size_is_invalid() {
let cfg = BatchConfig {
chunk_size: 0,
..Default::default()
};
assert!(cfg.validate().is_err());
}
#[test]
fn chunk_size_exceeds_512_is_invalid() {
let cfg = BatchConfig {
chunk_size: 513,
..Default::default()
};
let err = cfg.validate().unwrap_err();
assert!(err.contains("512"), "error message should cite the limit");
}
#[test]
fn chunk_size_512_is_valid() {
let cfg = BatchConfig {
chunk_size: 512,
..Default::default()
};
assert!(cfg.validate().is_ok());
}
#[test]
fn zero_max_seq_len_is_invalid() {
let cfg = BatchConfig {
max_seq_len: 0,
..Default::default()
};
assert!(cfg.validate().is_err());
}
}