Skip to content
Snippets Groups Projects
Commit 74aedc81 authored by Russel Arbore's avatar Russel Arbore
Browse files

use criterion to benchmark cava

parent 309ae295
No related branches found
No related tags found
1 merge request!190Set up cava benchmark
Pipeline #201755 passed
#![feature(concat_idents)]
use criterion::{criterion_group, criterion_main, Criterion}; use criterion::{criterion_group, criterion_main, Criterion};
use juno_cava::{cava_harness, CavaInputs}; use hercules_rt::{runner, HerculesImmBoxTo};
use juno_cava::*;
juno_build::juno!("cava");
fn cava_bench(c: &mut Criterion) {
let mut group = c.benchmark_group("cava bench");
group.sample_size(10);
let args = CavaInputs {
input: "examples/raw_tulip-small.bin".to_string(),
output: None,
verify: false,
output_verify: None,
cam_model: "cam_models/NikonD7000".to_string(),
crop_rows: Some(144),
crop_cols: Some(192),
};
let (raw_image, cam_model) = make_raw_image_and_cam_model(&args);
let (rows, cols, num_ctrl_pts, image, tstw, ctrl_pts, weights, coefs, tonemap) =
prepare_hercules_inputs(&raw_image, &cam_model);
let mut r = runner!(cava);
group.bench_function("cava bench small", |b| {
b.iter(|| {
async_std::task::block_on(r.run(
rows as u64,
cols as u64,
num_ctrl_pts as u64,
image.to(),
tstw.to(),
ctrl_pts.to(),
weights.to(),
coefs.to(),
tonemap.to(),
));
})
});
let args = CavaInputs {
input: "examples/raw_tulips.bin".to_string(),
output: None,
verify: true,
output_verify: None,
cam_model: "cam_models/NikonD7000".to_string(),
crop_rows: None,
crop_cols: None,
};
let (raw_image, cam_model) = make_raw_image_and_cam_model(&args);
let (rows, cols, num_ctrl_pts, image, tstw, ctrl_pts, weights, coefs, tonemap) =
prepare_hercules_inputs(&raw_image, &cam_model);
let mut r = runner!(cava);
fn cava_bench_small(c: &mut Criterion) { group.bench_function("cava bench full", |b| {
c.bench_function("cava_bench_small", |b| {
b.iter(|| { b.iter(|| {
cava_harness(CavaInputs { async_std::task::block_on(r.run(
input: "examples/raw_tulip-small.bin".to_string(), rows as u64,
output: None, cols as u64,
verify: false, num_ctrl_pts as u64,
output_verify: None, image.to(),
cam_model: "cam_models/NikonD7000".to_string(), tstw.to(),
crop_rows: Some(144), ctrl_pts.to(),
crop_cols: Some(192), weights.to(),
}) coefs.to(),
tonemap.to(),
));
}) })
}); });
} }
criterion_group!(benches, cava_bench_small); criterion_group!(benches, cava_bench);
criterion_main!(benches); criterion_main!(benches);
...@@ -4,9 +4,9 @@ mod camera_model; ...@@ -4,9 +4,9 @@ mod camera_model;
mod cava_rust; mod cava_rust;
mod image_proc; mod image_proc;
use self::camera_model::*; pub use self::camera_model::*;
use self::cava_rust::CHAN; pub use self::cava_rust::CHAN;
use self::image_proc::*; pub use self::image_proc::*;
use hercules_rt::{runner, HerculesImmBox, HerculesImmBoxTo, HerculesMutBox}; use hercules_rt::{runner, HerculesImmBox, HerculesImmBoxTo, HerculesMutBox};
...@@ -16,82 +16,59 @@ use clap::Parser; ...@@ -16,82 +16,59 @@ use clap::Parser;
juno_build::juno!("cava"); juno_build::juno!("cava");
// Individual lifetimes are not needed in this example but should probably be generated for pub fn make_raw_image_and_cam_model(args: &CavaInputs) -> (RawImage, CamModel) {
// flexibility let raw_image =
async fn safe_run<'a, 'b: 'a, 'c: 'a, 'd: 'a, 'e: 'a, 'f: 'a, 'g: 'a>( read_raw(&args.input, args.crop_rows, args.crop_cols).expect("Error loading image");
runner: &'a mut HerculesRunner_cava, let cam_model = load_cam_model(&args.cam_model, CHAN).expect("Error loading camera model");
r: u64, println!(
c: u64, "Running cava with {} rows, {} columns, and {} control points.",
num_ctrl_pts: u64, raw_image.rows, raw_image.cols, cam_model.num_ctrl_pts
input: &'b HerculesImmBox<'b, u8>, );
tstw: &'c HerculesImmBox<'c, f32>, (raw_image, cam_model)
ctrl_pts: &'d HerculesImmBox<'d, f32>,
weights: &'e HerculesImmBox<'e, f32>,
coefs: &'f HerculesImmBox<'f, f32>,
tonemap: &'g HerculesImmBox<'g, f32>,
) -> HerculesMutBox<'a, u8> {
HerculesMutBox::from(
runner
.run(
r,
c,
num_ctrl_pts,
input.to(),
tstw.to(),
ctrl_pts.to(),
weights.to(),
coefs.to(),
tonemap.to(),
)
.await,
)
} }
fn run_cava( pub fn prepare_hercules_inputs<'a, 'b>(
rows: usize, raw_image: &'a RawImage,
cols: usize, cam_model: &'b CamModel,
num_ctrl_pts: usize, ) -> (
image: &[u8], usize,
tstw: &[f32], usize,
ctrl_pts: &[f32], usize,
weights: &[f32], HerculesImmBox<'a, u8>,
coefs: &[f32], HerculesImmBox<'b, f32>,
tonemap: &[f32], HerculesImmBox<'b, f32>,
) -> Box<[u8]> { HerculesImmBox<'b, f32>,
assert_eq!(image.len(), CHAN * rows * cols); HerculesImmBox<'b, f32>,
assert_eq!(tstw.len(), CHAN * CHAN); HerculesImmBox<'b, f32>,
assert_eq!(ctrl_pts.len(), num_ctrl_pts * CHAN); ) {
assert_eq!(weights.len(), num_ctrl_pts * CHAN); assert_eq!(
assert_eq!(coefs.len(), 4 * CHAN); raw_image.pixels.len(),
assert_eq!(tonemap.len(), 256 * CHAN); CHAN * raw_image.rows * raw_image.cols
);
let image = HerculesImmBox::from(image); assert_eq!(cam_model.tstw.len(), CHAN * CHAN);
let tstw = HerculesImmBox::from(tstw); assert_eq!(cam_model.ctrl_pts.len(), cam_model.num_ctrl_pts * CHAN);
let ctrl_pts = HerculesImmBox::from(ctrl_pts); assert_eq!(cam_model.weights.len(), cam_model.num_ctrl_pts * CHAN);
let weights = HerculesImmBox::from(weights); assert_eq!(cam_model.coefs.len(), 4 * CHAN);
let coefs = HerculesImmBox::from(coefs); assert_eq!(cam_model.tonemap.len(), 256 * CHAN);
let tonemap = HerculesImmBox::from(tonemap);
let image = HerculesImmBox::from(&raw_image.pixels as &[u8]);
let mut r = runner!(cava); let tstw = HerculesImmBox::from(&cam_model.tstw as &[f32]);
let ctrl_pts = HerculesImmBox::from(&cam_model.ctrl_pts as &[f32]);
async_std::task::block_on(async { let weights = HerculesImmBox::from(&cam_model.weights as &[f32]);
safe_run( let coefs = HerculesImmBox::from(&cam_model.coefs as &[f32]);
&mut r, let tonemap = HerculesImmBox::from(&cam_model.tonemap as &[f32]);
rows as u64,
cols as u64, (
num_ctrl_pts as u64, raw_image.rows,
&image, raw_image.cols,
&tstw, cam_model.num_ctrl_pts,
&ctrl_pts, image,
&weights, tstw,
&coefs, ctrl_pts,
&tonemap, weights,
) coefs,
.await tonemap,
}) )
.as_slice()
.to_vec()
.into_boxed_slice()
} }
enum Error { enum Error {
...@@ -154,62 +131,51 @@ pub struct CavaInputs { ...@@ -154,62 +131,51 @@ pub struct CavaInputs {
} }
pub fn cava_harness(args: CavaInputs) { pub fn cava_harness(args: CavaInputs) {
let CavaInputs { let (raw_image, cam_model) = make_raw_image_and_cam_model(&args);
input, let (rows, cols, num_ctrl_pts, image, tstw, ctrl_pts, weights, coefs, tonemap) =
output, prepare_hercules_inputs(&raw_image, &cam_model);
verify, let mut r = runner!(cava);
output_verify,
cam_model,
crop_rows,
crop_cols,
} = args;
let RawImage { rows, cols, pixels } =
read_raw(input, crop_rows, crop_cols).expect("Error loading image");
let CamModel {
tstw,
num_ctrl_pts,
ctrl_pts,
weights,
coefs,
tonemap,
} = load_cam_model(cam_model, CHAN).expect("Error loading camera model");
println!( let result = async_std::task::block_on(async {
"Running cava with {} rows, {} columns, and {} control points.", HerculesMutBox::from(
rows, cols, num_ctrl_pts r.run(
); rows as u64,
let result = run_cava( cols as u64,
rows, num_ctrl_pts as u64,
cols, image.to(),
num_ctrl_pts, tstw.to(),
&pixels, ctrl_pts.to(),
&tstw, weights.to(),
&ctrl_pts, coefs.to(),
&weights, tonemap.to(),
&coefs, )
&tonemap, .await,
); )
})
.as_slice()
.to_vec()
.into_boxed_slice();
if let Some(output) = output { if let Some(output) = args.output {
extern_image(rows, cols, &*result) extern_image(rows, cols, &*result)
.save(output) .save(output)
.expect("Error saving image"); .expect("Error saving image");
} }
if verify { if args.verify {
let cpu_result = cava_rust::cava( let cpu_result = cava_rust::cava(
rows, rows,
cols, cols,
num_ctrl_pts, num_ctrl_pts,
&pixels, &raw_image.pixels,
&tstw, &cam_model.tstw,
&ctrl_pts, &cam_model.ctrl_pts,
&weights, &cam_model.weights,
&coefs, &cam_model.coefs,
&tonemap, &cam_model.tonemap,
); );
if let Some(output) = output_verify { if let Some(output) = args.output_verify {
extern_image(rows, cols, &cpu_result) extern_image(rows, cols, &cpu_result)
.save(output) .save(output)
.expect("Error saving verification image"); .expect("Error saving verification image");
...@@ -227,5 +193,6 @@ pub fn cava_harness(args: CavaInputs) { ...@@ -227,5 +193,6 @@ pub fn cava_harness(args: CavaInputs) {
"Verification failed: maximum pixel difference of {} exceeds threshold of 3", "Verification failed: maximum pixel difference of {} exceeds threshold of 3",
max_diff max_diff
); );
println!("Verified!");
} }
} }
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment