Compare commits

...

3 Commits

Author SHA1 Message Date
Bill Thiede
2b1112d39e Print human friendly rays / second.
Some checks failed
continuous-integration/drone/push Build is failing
2019-10-12 17:47:19 -07:00
Bill Thiede
c440c518d2 Remove debug prints. 2019-10-12 17:45:19 -07:00
Bill Thiede
fa168966eb Import from upstream.
https://raw.githubusercontent.com/BobGneu/human-format-rs/master/src/lib.rs
2019-10-12 17:45:05 -07:00
6 changed files with 268 additions and 9 deletions

7
rtiow/Cargo.lock generated
View File

@ -795,6 +795,11 @@ name = "httparse"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "human_format"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "hyper"
version = "0.12.24"
@ -1606,6 +1611,7 @@ dependencies = [
"chrono 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"cpuprofiler 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
"criterion 0.2.10 (registry+https://github.com/rust-lang/crates.io-index)",
"human_format 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)",
"image 0.19.0 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
@ -2503,6 +2509,7 @@ dependencies = [
"checksum hostname 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "21ceb46a83a85e824ef93669c8b390009623863b5c195d1ba747292c0c72f94e"
"checksum http 0.1.16 (registry+https://github.com/rust-lang/crates.io-index)" = "fe67e3678f2827030e89cc4b9e7ecd16d52f132c0b940ab5005f88e821500f6a"
"checksum httparse 1.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "e8734b0cfd3bc3e101ec59100e101c2eecd19282202e87808b3037b442777a83"
"checksum human_format 1.0.2 (registry+https://github.com/rust-lang/crates.io-index)" = "3d5497bfab9681858cded590626cf58844034b453668f7d3700bac5ade28042d"
"checksum hyper 0.12.24 (registry+https://github.com/rust-lang/crates.io-index)" = "fdfa9b401ef6c4229745bb6e9b2529192d07b920eed624cdee2a82348cd550af"
"checksum hyper-tls 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "32cd73f14ad370d3b4d4b7dce08f69b81536c82e39fcc89731930fe5788cd661"
"checksum idna 0.1.5 (registry+https://github.com/rust-lang/crates.io-index)" = "38f09e0f0b1fb55fdee1f17470ad800da77af5186a1a76c026b679358b7e844e"

View File

@ -14,6 +14,7 @@ askama = "0.7.1"
chrono = "*"
cpuprofiler = { version = "0.0.3", optional = true }
image = "0.19.0"
human_format = "1.0.1"
lazy_static = "1.1.0"
log = "0.4.5"
num_cpus = "1.8.0"

View File

@ -36,8 +36,7 @@ lazy_static! {
#[cfg(not(feature = "prom"))]
fn push_metrics(_push_gateway_addr: &str, _instance: String, start_time: &DateTime<Utc>) {
let runtime = *start_time - Utc::now();
let runtime = runtime.to_std().unwrap();
let runtime = (Utc::now() - *start_time).to_std().unwrap();
info!(
"Render time {}.{} seconds",
runtime.as_secs(),

243
rtiow/src/human.rs Normal file
View File

@ -0,0 +1,243 @@
#![doc(html_root_url = "https://docs.rs/human_format")]
//! From https://raw.githubusercontent.com/BobGneu/human-format-rs/master/src/lib.rs
//! `human_format` provides facilitates creating a formatted string, converting between numbers that are beyond typical
//! needs for humans into a simpler string that conveys the gist of the meaning of the number.
//!
//! ## Setup
//!
//! Add the library to your dependencies listing
//!
//! ```toml
//! [dependencies]
//! human_format = "0.2"
//! ```
//!
//! Add the crate reference at your crate root
//!
//! ```rust
//! extern crate human_format;
//! ```
//!
//! Print some human readable strings
//!
//! ```rust
//! // "1.00 k"
//! let tmpStr = human_format::Formatter::new()
//! .format(1000.0);
//! # assert_eq!(tmpStr, "1.00 k");
//!
//! // "1.00 M"
//! let tmpStr2 = human_format::Formatter::new()
//! .format(1000000.0);
//! # assert_eq!(tmpStr2, "1.00 M");
//!
//! // "1.00 B"
//! let tmpStr3 = human_format::Formatter::new()
//! .format(1000000000.0);
//! # assert_eq!(tmpStr3, "1.00 B");
//! ```
//!
//! If you are so inspired you can even try playing with units and customizing your `Scales`
//!
//! For more examples you should review the examples on github: [tests/demo.rs](https://github.com/BobGneu/human-format-rs/blob/master/tests/demo.rs)
//!
#[derive(Debug)]
struct ScaledValue {
value: f32,
suffix: String,
}
/// Entry point to the lib. Use this to handle your formatting needs.
#[derive(Debug)]
pub struct Formatter {
decimals: usize,
separator: String,
scales: Scales,
forced_units: String,
forced_suffix: String,
}
/// Provide a customized scaling scheme for your own modeling.
#[derive(Debug)]
pub struct Scales {
base: u32,
suffixes: Vec<String>,
}
impl Formatter {
/// Initializes a new `Formatter` with default values.
pub fn new() -> Self {
Formatter {
decimals: 2,
separator: " ".to_owned(),
scales: Scales::SI(),
forced_units: "".to_owned(),
forced_suffix: "".to_owned(),
}
}
/// Sets the decimals value for formatting the string.
pub fn with_decimals(&mut self, decimals: usize) -> &mut Self {
self.decimals = decimals;
self
}
/// Sets the separator value for formatting the string.
pub fn with_separator(&mut self, separator: &str) -> &mut Self {
self.separator = separator.to_owned();
self
}
/// Sets the scales value.
pub fn with_scales(&mut self, scales: Scales) -> &mut Self {
self.scales = scales;
self
}
/// Sets the units value.
pub fn with_units(&mut self, units: &str) -> &mut Self {
self.forced_units = units.to_owned();
self
}
/// Sets the expected suffix value.
pub fn with_suffix(&mut self, suffix: &str) -> &mut Self {
self.forced_suffix = suffix.to_owned();
self
}
/// Formats the number into a string
pub fn format(&self, value: f64) -> String {
if value < 0.0 {
return format!("-{}", self.format(value * -1.0));
}
let scaled_value = self.scales.to_scaled_value(value);
format!(
"{:.width$}{}{}{}",
scaled_value.value,
self.separator,
scaled_value.suffix,
self.forced_units,
width = self.decimals
)
}
/// Parse a string back into a float value.
pub fn parse(&self, value: &str) -> f64 {
let v: Vec<&str> = value.split(&self.separator).collect();
let result = v.get(0).unwrap().parse::<f64>().unwrap();
let mut suffix = v.get(1).unwrap().to_string();
let new_len = suffix.len() - self.forced_units.len();
suffix.truncate(new_len);
let magnitude_multiplier = self.scales.get_magnitude_multipler(&suffix);
(result * magnitude_multiplier)
}
}
impl Scales {
/// Instantiates a new `Scales` with SI keys
pub fn new() -> Self {
Scales::SI()
}
/// Instantiates a new `Scales` with SI keys
pub fn SI() -> Self {
Scales {
base: 1000,
suffixes: vec![
"".to_owned(),
"k".to_owned(),
"M".to_owned(),
"B".to_owned(),
"T".to_owned(),
"P".to_owned(),
"E".to_owned(),
"Z".to_owned(),
"Y".to_owned(),
],
}
}
/// Instantiates a new `Scales` with Binary keys
pub fn Binary() -> Self {
Scales {
base: 1000,
suffixes: vec![
"".to_owned(),
"ki".to_owned(),
"Mi".to_owned(),
"Gi".to_owned(),
"Ti".to_owned(),
"Pi".to_owned(),
"Ei".to_owned(),
"Zi".to_owned(),
"Yi".to_owned(),
],
}
}
/// Sets the base for the `Scales`
pub fn with_base(&mut self, base: u32) -> &mut Self {
self.base = base;
self
}
/// Sets the suffixes listing appropriately
pub fn with_suffixes(&mut self, suffixes: Vec<&str>) -> &mut Self {
self.suffixes = Vec::new();
for suffix in suffixes {
// This should be to_owned to be clear about intent.
// https://users.rust-lang.org/t/to-string-vs-to-owned-for-string-literals/1441/6
self.suffixes.push(suffix.to_owned());
}
self
}
fn get_magnitude_multipler(&self, value: &str) -> f64 {
let ndx = 0;
for ndx in 0..self.suffixes.len() {
if value == self.suffixes[ndx] {
return self.base.pow(ndx as u32) as f64;
}
}
return 0.0;
}
fn to_scaled_value(&self, value: f64) -> ScaledValue {
let mut index: usize = 0;
let mut _value: f64 = value;
loop {
if _value < (self.base as f64) {
break;
}
_value /= self.base as f64;
index += 1;
}
ScaledValue {
value: (value / self.base.pow((index) as u32) as f64) as f32,
suffix: self.suffixes[index].to_owned(),
}
}
}

View File

@ -6,6 +6,7 @@ pub mod cuboid;
pub mod flip_normals;
pub mod hitable;
pub mod hitable_list;
mod human;
pub mod kdtree;
pub mod material;
pub mod moving_sphere;

View File

@ -23,6 +23,7 @@ use rand::Rng;
use crate::camera::Camera;
use crate::hitable::Hit;
use crate::human;
use crate::ray::Ray;
use crate::scenes;
use crate::texture::EnvMap;
@ -42,6 +43,7 @@ impl MockPrometheus {
fn inc(&self) {}
}
static RAY_COUNT: AtomicUsize = AtomicUsize::new(0);
#[cfg(not(feature = "prom"))]
static RAY_COUNTER: MockPrometheus = MockPrometheus {};
@ -194,6 +196,7 @@ fn color(
global_illumination: bool,
env_map: &Option<EnvMap>,
) -> Vec3 {
RAY_COUNT.fetch_add(1, Ordering::SeqCst);
RAY_COUNTER.with_label_values(&[&depth.to_string()]).inc();
if let Some(rec) = world.hit(r, 0.001, std::f32::MAX) {
let (u, v) = rec.uv;
@ -284,7 +287,7 @@ fn render_worker(
let job = { input_chan.lock().unwrap().recv() };
match job {
Err(err) => {
info!("Shutting down render_worker {}: {}", tid, err);
trace!("Shutting down render_worker {}: {}", tid, err);
return;
}
Ok(req) => match req {
@ -301,7 +304,6 @@ fn render_worker(
},
}
}
trace!(target: "renderer", "Shutting down worker {}", tid);
}
pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::io::Error> {
@ -344,22 +346,28 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i
thread::spawn(move || {
let mut last_time = time::Instant::now();
let mut last_pixel_count = PIXEL_COUNT.load(Ordering::SeqCst);
let mut last_ray_count = RAY_COUNT.load(Ordering::SeqCst);
let human = human::Formatter::new();
loop {
let sleep_time = time::Duration::from_secs(1);
thread::sleep(sleep_time);
let now = time::Instant::now();
let mut pixel_count = PIXEL_COUNT.load(Ordering::SeqCst);
let pixel_count = PIXEL_COUNT.load(Ordering::SeqCst);
let ray_count = RAY_COUNT.load(Ordering::SeqCst);
let time_diff = now - last_time;
let pixel_diff = pixel_count - last_pixel_count;
let ray_diff = ray_count - last_ray_count;
info!(
"{} / {} ({}%) pixels rendered {} p/s",
pixel_count,
pixel_total,
"{} / {} ({}%) pixels {} pixels/s {} rays/s",
human.format(pixel_count as f64),
human.format(pixel_total as f64),
100 * pixel_count / pixel_total,
pixel_diff as u64 / time_diff.as_secs()
human.format(pixel_diff as f64 / time_diff.as_secs_f64()),
human.format(ray_diff as f64 / time_diff.as_secs_f64())
);
last_time = now;
last_pixel_count = pixel_count;
last_ray_count = ray_count;
}
});