Compare commits

...

7 Commits

Author SHA1 Message Date
690048cbef Add build vs watch scripts, tell drone to build_all_features.
Some checks failed
continuous-integration/drone/push Build is failing
2019-10-13 08:25:47 -07:00
fcc22b24cd Cleanup more lint.
Add script for building all configs with all lint as errors.
2019-10-13 08:23:07 -07:00
90c4e15ad1 Cleaned up lint when building with prom or profile features. 2019-10-13 08:04:49 -07:00
38317de40d Cleanup lint in human. 2019-10-13 07:55:06 -07:00
92c8f1980c Cleanup lint in renderer. 2019-10-13 07:51:16 -07:00
5d5f3c7244 Lint cleanup when prometheus not enabled. 2019-10-12 20:42:41 -07:00
051482e7fe Plumb --adaptive flag for adaptive subsampling. 2019-10-12 20:41:07 -07:00
9 changed files with 60 additions and 37 deletions

View File

@ -13,7 +13,7 @@ steps:
commands:
- sccache -s
- apt-get update && apt-get install -y libgoogle-perftools-dev
- (cd rtiow && cargo build --verbose --all)
- (cd rtiow && ./build_all_features.sh)
- (cd rtiow && cargo test --verbose --all)
- sccache -s

6
rtiow/build_all_features.sh Executable file
View File

@ -0,0 +1,6 @@
set -e
export RUSTFLAGS="-D warnings"
cargo build
cargo build --features=prom
cargo build --features=profile
cargo build --features=prom,profile

View File

@ -153,7 +153,7 @@ fn render_noise(noise_params: NoiseParams) -> image::GrayImage {
const SEED: [u8; 16] = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15];
let rng: &mut XorShiftRng = &mut SeedableRng::from_seed(SEED);
let mut img = image::GrayImage::new(noise_params.width, noise_params.height);
let tex: NoiseTexture<Box<noise::NoiseSource>> = match noise_params.noise_source {
let tex: NoiseTexture<Box<dyn noise::NoiseSource>> = match noise_params.noise_source {
NoiseSource::Perlin => {
NoiseTexture::new(Box::new(Perlin::new(rng)), noise_params.noise_type)
}

View File

@ -8,13 +8,13 @@ extern crate rtiow;
extern crate stderrlog;
extern crate structopt;
#[macro_use]
#[cfg(feature = "prom")]
extern crate lazy_static;
#[macro_use]
#[cfg(feature = "prom")]
extern crate prometheus;
use std::fs;
use std::time::Instant;
use chrono::DateTime;
use chrono::Utc;
@ -46,7 +46,7 @@ fn push_metrics(_push_gateway_addr: &str, _instance: String, start_time: &DateTi
#[cfg(feature = "prom")]
fn push_metrics(push_gateway_addr: &str, instance: String, start_time: &DateTime<Utc>) {
let runtime = start_instant.elapsed();
let runtime = (Utc::now() - *start_time).to_std().unwrap();
info!(
"Render time {}.{} seconds",
runtime.as_secs(),
@ -88,8 +88,10 @@ fn push_metrics(push_gateway_addr: &str, instance: String, start_time: &DateTime
}
}
#[cfg(not(feature = "profile"))]
struct MockTimer;
#[cfg(not(feature = "profile"))]
impl MockTimer {
fn start<T: Into<Vec<u8>>>(&self, _: T) -> Result<(), ()> {
Ok(())
@ -99,8 +101,10 @@ impl MockTimer {
}
}
#[cfg(not(feature = "profile"))]
struct MockProfiler;
#[cfg(not(feature = "profile"))]
impl MockProfiler {
fn lock(&self) -> Option<MockTimer> {
Some(MockTimer {})
@ -117,7 +121,6 @@ fn main() -> Result<(), std::io::Error> {
.init()
.unwrap();
let start_time: DateTime<Utc> = Utc::now();
let start_instant = Instant::now();
let opt = Opt::from_args();
let scene = opt.model.scene(&opt);
fs::create_dir_all(&opt.output)?;

View File

@ -1,3 +1,4 @@
#![allow(dead_code)]
#![doc(html_root_url = "https://docs.rs/human_format")]
//! From https://raw.githubusercontent.com/BobGneu/human-format-rs/master/src/lib.rs
@ -72,7 +73,7 @@ impl Formatter {
Formatter {
decimals: 2,
separator: " ".to_owned(),
scales: Scales::SI(),
scales: Scales::si(),
forced_units: "".to_owned(),
forced_suffix: "".to_owned(),
}
@ -151,11 +152,11 @@ impl Formatter {
impl Scales {
/// Instantiates a new `Scales` with SI keys
pub fn new() -> Self {
Scales::SI()
Scales::si()
}
/// Instantiates a new `Scales` with SI keys
pub fn SI() -> Self {
pub fn si() -> Self {
Scales {
base: 1000,
suffixes: vec![
@ -173,7 +174,7 @@ impl Scales {
}
/// Instantiates a new `Scales` with Binary keys
pub fn Binary() -> Self {
pub fn binary() -> Self {
Scales {
base: 1000,
suffixes: vec![
@ -211,8 +212,6 @@ impl Scales {
}
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;

View File

@ -31,7 +31,5 @@ extern crate structopt;
#[macro_use]
extern crate serde_derive;
#[macro_use]
extern crate lazy_static;
#[macro_use]
#[cfg(feature = "prom")]
extern crate prometheus;

View File

@ -15,6 +15,8 @@ use std::time;
use image;
use image::RgbImage;
#[cfg(feature = "prom")]
use lazy_static::lazy_static;
use num_cpus;
use rand;
use rand::Rng;
@ -36,7 +38,9 @@ lazy_static! {
register_counter_vec!("rays", "Number of rays fired", &["level"]).unwrap();
}
#[cfg(not(feature = "prom"))]
struct MockPrometheus;
#[cfg(not(feature = "prom"))]
impl MockPrometheus {
fn with_label_values(&self, _: &[&str]) -> &MockPrometheus {
self
@ -146,9 +150,12 @@ pub struct Opt {
/// Sub-samples per pixel
#[structopt(short = "s", long = "subsample", default_value = "8")]
pub subsamples: usize,
/// Use adaptive subsampling
#[structopt(long = "adaptive")]
pub adaptive_subsampling: bool,
/// Select scene to render, one of: "bench", "book", "tutorial", "bvh", "test", "cornell_box",
/// "cornell_smoke", "perlin_debug", "final"
#[structopt(long = "model", default_value = "perlin_debug")]
#[structopt(long = "model", default_value = "book")]
pub model: Model,
/// Path to store pprof profile data, i.e. /tmp/cpuprofile.pprof
#[structopt(long = "pprof", parse(from_os_str))]
@ -180,6 +187,8 @@ pub struct Scene {
pub world: Box<dyn Hit>,
pub camera: Camera,
pub subsamples: usize,
/// overrides subsamples setting.
pub adaptive_subsampling: bool,
pub num_threads: Option<usize>,
pub width: usize,
pub height: usize,
@ -214,6 +223,7 @@ impl Default for Scene {
)),
camera,
subsamples: 0,
adaptive_subsampling: false,
num_threads: None,
width: 0,
height: 0,
@ -288,26 +298,22 @@ enum Request {
}
enum Response {
Pixel {
x: usize,
y: usize,
pixel: Vec3,
},
Line {
width: usize,
y: usize,
pixels: Vec<Vec3>,
},
Pixel { x: usize, y: usize, pixel: Vec3 },
Line { y: usize, pixels: Vec<Vec3> },
}
static PIXEL_COUNT: AtomicUsize = AtomicUsize::new(0);
fn render_pixel(scene: &Scene, x: usize, y: usize) -> Vec3 {
let mut pixel: Vec3 = Default::default();
for _ in 0..scene.subsamples {
pixel = pixel + trace_pixel(x, y, scene);
}
pixel = pixel / scene.subsamples as f32;
let pixel = if scene.adaptive_subsampling {
Default::default()
} else {
for _ in 0..scene.subsamples {
pixel = pixel + trace_pixel(x, y, scene);
}
pixel / scene.subsamples as f32
};
// Gamma correct, use gamma 2 correction, which is 1/gamma where gamma=2 which is 1/2 or
// sqrt.
PIXEL_COUNT.fetch_add(1, Ordering::SeqCst);
@ -331,12 +337,16 @@ fn render_worker(
Request::Line { width, y } => {
trace!("tid {} width {} y {}", tid, width, y);
let pixels = (0..width).map(|x| render_pixel(scene, x, y)).collect();
output_chan.send(Response::Line { width, y, pixels });
output_chan
.send(Response::Line { y, pixels })
.expect("failed to send pixel response");
}
Request::Pixel { x, y } => {
trace!("tid {} x {} y {}", tid, x, y);
let pixel = render_pixel(scene, x, y);
output_chan.send(Response::Pixel { x, y, pixel });
output_chan
.send(Response::Pixel { x, y, pixel })
.expect("failed to send line response");
}
},
}
@ -351,6 +361,7 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i
let scene = Arc::new(scene);
let pixel_req_rx = Arc::new(Mutex::new(pixel_req_rx));
info!("Creating {} render threads", num_threads);
info!("Adaptive subsampling: {}", scene.adaptive_subsampling);
for i in 0..num_threads {
let s = sync::Arc::clone(&scene);
let pixel_req_rx = pixel_req_rx.clone();
@ -367,12 +378,16 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i
let batch_line_requests = true;
if batch_line_requests {
for y in 0..h {
pixel_req_tx.send(Request::Line { width: w, y });
pixel_req_tx
.send(Request::Line { width: w, y })
.expect("failed to send line request");
}
} else {
for y in 0..h {
for x in 0..w {
pixel_req_tx.send(Request::Pixel { x, y });
pixel_req_tx
.send(Request::Pixel { x, y })
.expect("failed to send pixel request");
}
}
}
@ -424,11 +439,7 @@ pub fn render(scene: Scene, output_dir: &Path) -> std::result::Result<(), std::i
]),
);
}
Response::Line {
width: _,
y,
pixels,
} => {
Response::Line { y, pixels } => {
for (x, pixel) in pixels.iter().enumerate() {
let y_inv = scene.height - y - 1;
img.put_pixel(

View File

@ -51,6 +51,7 @@ pub fn new(opt: &Opt) -> Scene {
camera,
world,
subsamples: opt.subsamples,
adaptive_subsampling: opt.adaptive_subsampling,
num_threads: opt.num_threads,
width: opt.width,
height: opt.height,

5
rtiow/watch_all_features.sh Executable file
View File

@ -0,0 +1,5 @@
export RUSTFLAGS="-D warnings"
cargo watch -x 'build' \
-x 'build --features=prom' \
-x 'build --features=profile' \
-x 'build --features=prom,profile'