Something went wrong. Try again.
iterative image reconstruction using random cubic bézier strokes, accelerated on metal
metal graphics rust
Something went wrong. Try again.
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576use std::fmt::Arguments;use std::sync::atomic::{AtomicU8, Ordering};
static LEVEL: AtomicU8 = AtomicU8::new(1);
pub fn set_level(level: u8) { LEVEL.store(level.min(3), Ordering::Relaxed); }
pub fn level() -> u8 { LEVEL.load(Ordering::Relaxed) }
pub fn l1(args: Arguments) { emit(1, args); }pub fn l2(args: Arguments) { emit(2, args); }
fn emit(min: u8, args: Arguments) { if level() >= min { eprintln!("{args}"); } }
pub struct BatchInfo { pub batch_idx : u64 , pub accepted_total : u32 , pub max_splines : u32 , pub accepted_now : u32 , pub batch_size : u32 , pub remaining : u32 , pub consecutive_stagnant : u32 , pub max_stagnant_batches : u32 , pub elapsed_s : f64 }
pub struct BatchLogger { rate_avg : Option<f64> , accept_ratio_avg : Option<f64> , alpha : f64 , last_elapsed : f64 }
impl BatchLogger { pub fn new() -> Self { Self { rate_avg: None, accept_ratio_avg: None, alpha: 0.25, last_elapsed: 0.0, } }
pub fn log_batch(&mut self, info: BatchInfo) { let stop = info.consecutive_stagnant >= info.max_stagnant_batches; let delta = (info.elapsed_s - self.last_elapsed).max(0.0); self.last_elapsed = info.elapsed_s;
let rate_sample = if delta > 0.0 { info.accepted_now as f64 / delta } else { 0.0 }; let ratio_sample = if info.batch_size > 0 { info.accepted_now as f64 / info.batch_size as f64 } else { 0.0 };
self.rate_avg = Some(self.update_ema(self.rate_avg, rate_sample)); self.accept_ratio_avg = Some(self.update_ema(self.accept_ratio_avg, ratio_sample));
let rate_avg = self.rate_avg.unwrap_or(0.0); let accept_avg = self.accept_ratio_avg.unwrap_or(0.0);
self.emit(&info, ratio_sample, rate_avg, accept_avg, stop); }
fn update_ema(&self, current: Option<f64>, sample: f64) -> f64 { match current { Some(prev) => prev * (1.0 - self.alpha) + sample * self.alpha, None => sample, } }
fn emit(&self, info: &BatchInfo, batch_ratio: f64, rate_avg: f64, accept_avg: f64, stop: bool) { let lv = level(); let stop_note = if stop { " stop:stagnant" } else { "" };
if lv >= 3 { eprintln!( "b:{} t:{:.1}s acc:{}/{} (+{}, {:.3}) stagnant:{}/{} rem:{} avg_rate:{:.2}/s avg_accept:{:.3}{}", info.batch_idx, info.elapsed_s, info.accepted_total, info.max_splines, info.accepted_now, batch_ratio, info.consecutive_stagnant, info.max_stagnant_batches, info.remaining, rate_avg, accept_avg, stop_note ); }
else if lv >= 2 { eprintln!( "b:{} t:{:.1}s acc:{}/{} (+{}, {:.3}) stagnant:{}/{} avg_rate:{:.2}/s avg_accept:{:.3}{}", info.batch_idx, info.elapsed_s, info.accepted_total, info.max_splines, info.accepted_now, batch_ratio, info.consecutive_stagnant, info.max_stagnant_batches, rate_avg, accept_avg, stop_note ); }
else if lv >= 1 && (info.accepted_now > 0 || stop) { eprintln!( "{}/{} (+{}) stagnant:{}/{}{}", info.accepted_total, info.max_splines, info.accepted_now, info.consecutive_stagnant, info.max_stagnant_batches, stop_note ); } } }