sciforge 0.0.3

A comprehensive scientific computing library in pure Rust with zero dependencies
Documentation
use super::engine::{
    BENCHMARK_HEADER_SIZE, BENCHMARK_MAGIC, BENCHMARK_VERSION, BenchmarkEncodeError,
    BenchmarkMetrics,
};

pub fn encoded_size(metrics: &BenchmarkMetrics<'_>) -> Option<usize> {
    BENCHMARK_HEADER_SIZE
        .checked_add(metrics.experiment_name.len())?
        .checked_add(metrics.precision.len())
}

pub fn encode(
    metrics: &BenchmarkMetrics<'_>,
    out: &mut [u8],
) -> Result<usize, BenchmarkEncodeError> {
    if metrics.experiment_name.len() > u16::MAX as usize
        || metrics.precision.len() > u16::MAX as usize
    {
        return Err(BenchmarkEncodeError::InvalidFormat);
    }
    let needed = encoded_size(metrics).ok_or(BenchmarkEncodeError::InvalidFormat)?;
    if out.len() < needed {
        return Err(BenchmarkEncodeError::BufferTooSmall);
    }

    out[0..4].copy_from_slice(&BENCHMARK_MAGIC);
    out[4..6].copy_from_slice(&BENCHMARK_VERSION.to_le_bytes());
    out[6..8].copy_from_slice(&0u16.to_le_bytes());
    out[8..16].copy_from_slice(&metrics.elapsed_ms.to_le_bytes());
    out[16..24].copy_from_slice(&metrics.iterations.to_le_bytes());
    out[24..32].copy_from_slice(&metrics.input_samples.to_le_bytes());
    out[32..36].copy_from_slice(&metrics.avg_time_ns.to_le_bytes());
    out[36..40].copy_from_slice(&metrics.last_time_ns.to_le_bytes());
    out[40..48].copy_from_slice(&(metrics.output_bytes as u64).to_le_bytes());
    out[48..56].copy_from_slice(&metrics.total_flops.to_le_bytes());
    out[56..60].copy_from_slice(&metrics.step_count.to_le_bytes());
    out[60..64].copy_from_slice(&metrics.input_dim.to_le_bytes());
    out[64..68].copy_from_slice(&metrics.output_dim.to_le_bytes());
    out[68..76].copy_from_slice(&metrics.benchmark_flags.to_le_bytes());
    out[76..84].copy_from_slice(&metrics.input_bytes.to_le_bytes());
    out[84..92].copy_from_slice(&metrics.result_bytes.to_le_bytes());
    out[92..96].copy_from_slice(&metrics.min_time_ns.to_le_bytes());
    out[96..100].copy_from_slice(&metrics.max_time_ns.to_le_bytes());
    out[100..104].copy_from_slice(&metrics.time_stddev.to_le_bytes());
    out[104..108].copy_from_slice(&metrics.iterations_per_sec.to_le_bytes());
    out[108..112].copy_from_slice(&metrics.samples_per_sec.to_le_bytes());
    out[112..116].copy_from_slice(&metrics.eval_error.to_le_bytes());
    out[116..120].copy_from_slice(&metrics.eval_accuracy.to_le_bytes());
    out[120..124].copy_from_slice(&metrics.eval_r_squared.to_le_bytes());
    out[124..128].copy_from_slice(&metrics.eval_mae.to_le_bytes());
    out[128..136].copy_from_slice(&metrics.eval_samples.to_le_bytes());
    out[136..144].copy_from_slice(&metrics.eval_dataset_hash.to_le_bytes());
    out[144..148].copy_from_slice(&metrics.logical_cores.to_le_bytes());
    out[148..152].copy_from_slice(&metrics.avg_frequency_mhz.to_le_bytes());
    out[152..156].copy_from_slice(&metrics.max_frequency_mhz.to_le_bytes());
    out[156..160].copy_from_slice(&metrics.max_workers.to_le_bytes());
    out[160..164].copy_from_slice(&metrics.target_cpu_utilization.to_le_bytes());
    out[164..166].copy_from_slice(&(metrics.experiment_name.len() as u16).to_le_bytes());
    out[166..168].copy_from_slice(&(metrics.precision.len() as u16).to_le_bytes());

    let mut cursor = BENCHMARK_HEADER_SIZE;
    let name_bytes = metrics.experiment_name.as_bytes();
    out[cursor..cursor + name_bytes.len()].copy_from_slice(name_bytes);
    cursor += name_bytes.len();

    let prec_bytes = metrics.precision.as_bytes();
    out[cursor..cursor + prec_bytes.len()].copy_from_slice(prec_bytes);
    cursor += prec_bytes.len();

    Ok(cursor)
}