sciforge 0.0.3

A comprehensive scientific computing library in pure Rust with zero dependencies
Documentation
use std::hint::black_box;
use std::time::Instant;

#[derive(Clone, Copy, Debug, PartialEq)]
pub struct BenchmarkMetrics<'a> {
    pub experiment_name: &'a str,
    pub precision: &'a str,
    pub elapsed_ms: u64,
    pub iterations: u64,
    pub input_samples: u64,
    pub avg_time_ns: f32,
    pub last_time_ns: f32,
    pub output_bytes: usize,
    pub total_flops: u64,
    pub step_count: u32,
    pub input_dim: u32,
    pub output_dim: u32,
    pub benchmark_flags: u64,
    pub input_bytes: u64,
    pub result_bytes: u64,
    pub min_time_ns: f32,
    pub max_time_ns: f32,
    pub time_stddev: f32,
    pub iterations_per_sec: f32,
    pub samples_per_sec: f32,
    pub eval_error: f32,
    pub eval_accuracy: f32,
    pub eval_r_squared: f32,
    pub eval_mae: f32,
    pub eval_samples: u64,
    pub eval_dataset_hash: u64,
    pub logical_cores: u32,
    pub avg_frequency_mhz: u32,
    pub max_frequency_mhz: u32,
    pub max_workers: u32,
    pub target_cpu_utilization: f32,
}

pub const CSV_HEADER: &str = "experiment_name,precision,elapsed_ms,iterations,avg_time_ns,min_time_ns,max_time_ns,time_stddev,iterations_per_sec,result";

impl BenchmarkMetrics<'_> {
    pub fn to_csv_row(&self) -> String {
        format!(
            "{},{},{},{},{},{},{},{},{}",
            self.experiment_name,
            self.precision,
            self.elapsed_ms,
            self.iterations,
            self.avg_time_ns,
            self.min_time_ns,
            self.max_time_ns,
            self.time_stddev,
            self.iterations_per_sec,
        )
    }
}

#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum BenchmarkEncodeError {
    BufferTooSmall,
    InvalidFormat,
}

pub const BENCHMARK_MAGIC: [u8; 4] = [b'B', b'M', b'K', 0x01];
pub const BENCHMARK_VERSION: u16 = 4;
pub const BENCHMARK_HEADER_SIZE: usize = 4
    + 2
    + 2
    + 8
    + 8
    + 8
    + 4
    + 4
    + 8
    + 8
    + 4
    + 4
    + 4
    + 8
    + 8
    + 8
    + 4
    + 4
    + 4
    + 4
    + 4
    + 4
    + 4
    + 4
    + 4
    + 8
    + 8
    + 4
    + 4
    + 4
    + 4
    + 4
    + 2
    + 2;

pub fn bench<'a, T, F: Fn() -> T>(
    experiment_name: &'a str,
    precision: &'a str,
    iterations: u64,
    f: F,
) -> BenchmarkMetrics<'a> {
    let start = Instant::now();
    for _ in 0..iterations {
        black_box(f());
    }
    let elapsed = start.elapsed();
    let elapsed_ms = elapsed.as_millis() as u64;
    let avg_ns = elapsed.as_nanos() as f32 / iterations as f32;
    let ips = if elapsed_ms > 0 {
        iterations as f32 * 1000.0 / elapsed_ms as f32
    } else {
        0.0
    };
    BenchmarkMetrics {
        experiment_name,
        precision,
        elapsed_ms,
        iterations,
        input_samples: 0,
        avg_time_ns: avg_ns,
        last_time_ns: avg_ns,
        output_bytes: 0,
        total_flops: 0,
        step_count: 0,
        input_dim: 0,
        output_dim: 0,
        benchmark_flags: 0,
        input_bytes: 0,
        result_bytes: 0,
        min_time_ns: avg_ns,
        max_time_ns: avg_ns,
        time_stddev: 0.0,
        iterations_per_sec: ips,
        samples_per_sec: 0.0,
        eval_error: 0.0,
        eval_accuracy: 0.0,
        eval_r_squared: 0.0,
        eval_mae: 0.0,
        eval_samples: 0,
        eval_dataset_hash: 0,
        logical_cores: 0,
        avg_frequency_mhz: 0,
        max_frequency_mhz: 0,
        max_workers: 0,
        target_cpu_utilization: 0.0,
    }
}