use super::result::{BenchmarkResult, WorkloadSize};
#[derive(Debug, Clone)]
pub struct WorkloadConfig {
pub size: usize,
pub convergence_threshold: f64,
pub max_iterations: usize,
pub custom_params: std::collections::HashMap<String, String>,
}
impl Default for WorkloadConfig {
fn default() -> Self {
Self {
size: 10_000,
convergence_threshold: 1e-6,
max_iterations: 100,
custom_params: std::collections::HashMap::new(),
}
}
}
impl WorkloadConfig {
#[must_use]
pub fn new(size: usize) -> Self {
Self {
size,
..Default::default()
}
}
#[must_use]
pub fn with_convergence_threshold(mut self, threshold: f64) -> Self {
self.convergence_threshold = threshold;
self
}
#[must_use]
pub fn with_max_iterations(mut self, max: usize) -> Self {
self.max_iterations = max;
self
}
#[must_use]
pub fn with_param(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
self.custom_params.insert(key.into(), value.into());
self
}
}
pub trait Benchmarkable: Send + Sync {
fn name(&self) -> &str;
fn code(&self) -> &str;
fn execute(&self, config: &WorkloadConfig) -> BenchmarkResult;
fn workload_size(&self) -> WorkloadSize {
WorkloadSize::default()
}
fn requires_gpu(&self) -> bool {
true
}
fn description(&self) -> Option<&str> {
None
}
}
#[cfg(test)]
mod tests {
use super::*;
use std::time::Duration;
struct TestWorkload;
impl Benchmarkable for TestWorkload {
fn name(&self) -> &str {
"Test"
}
fn code(&self) -> &str {
"TST"
}
fn execute(&self, config: &WorkloadConfig) -> BenchmarkResult {
BenchmarkResult {
workload_id: self.name().to_string(),
size: config.size,
throughput_ops: 1000.0,
total_time: Duration::from_millis(10),
iterations: Some(10),
converged: Some(true),
measurement_times: vec![Duration::from_millis(10)],
custom_metrics: Default::default(),
}
}
}
#[test]
fn test_workload_config_default() {
let config = WorkloadConfig::default();
assert!(config.size > 0);
}
#[test]
fn test_workload_config_builder() {
let config = WorkloadConfig::new(1000)
.with_convergence_threshold(1e-5)
.with_max_iterations(50)
.with_param("damping", "0.85");
assert_eq!(config.size, 1000);
assert!((config.convergence_threshold - 1e-5).abs() < f64::EPSILON);
assert_eq!(config.max_iterations, 50);
assert_eq!(
config.custom_params.get("damping"),
Some(&"0.85".to_string())
);
}
#[test]
fn test_benchmarkable_trait() {
let workload = TestWorkload;
assert_eq!(workload.name(), "Test");
assert_eq!(workload.code(), "TST");
assert!(workload.requires_gpu());
let result = workload.execute(&WorkloadConfig::default());
assert_eq!(result.workload_id, "Test");
assert!(result.throughput_ops > 0.0);
}
}