From 074aed616152275fde985dc0d11246b6571553f5 Mon Sep 17 00:00:00 2001 From: Russel Arbore <russel.jma@gmail.com> Date: Tue, 18 Feb 2025 21:32:29 -0600 Subject: [PATCH 1/3] some refactoring --- juno_samples/edge_detection/Cargo.toml | 4 + juno_samples/edge_detection/src/lib.rs | 255 +++++++++++++++++++++ juno_samples/edge_detection/src/main.rs | 286 +----------------------- 3 files changed, 260 insertions(+), 285 deletions(-) create mode 100644 juno_samples/edge_detection/src/lib.rs diff --git a/juno_samples/edge_detection/Cargo.toml b/juno_samples/edge_detection/Cargo.toml index a3825eed..bd2ae5c9 100644 --- a/juno_samples/edge_detection/Cargo.toml +++ b/juno_samples/edge_detection/Cargo.toml @@ -13,6 +13,10 @@ name = "juno_edge_detection" path = "src/main.rs" required-features = ["opencv"] +[lib] +path = "src/lib.rs" +required-features = ["opencv"] + [build-dependencies] juno_build = { path = "../../juno_build" } diff --git a/juno_samples/edge_detection/src/lib.rs b/juno_samples/edge_detection/src/lib.rs new file mode 100644 index 00000000..f675d5f5 --- /dev/null +++ b/juno_samples/edge_detection/src/lib.rs @@ -0,0 +1,255 @@ +#![feature(concat_idents)] + +mod edge_detection_rust; + +use hercules_rt::{runner, HerculesImmBox, HerculesImmBoxTo, HerculesMutBox}; + +use std::slice::from_raw_parts; + +use clap::Parser; + +use opencv::core::{Mat, Size, CV_32F, CV_8U}; +use opencv::highgui::{imshow, wait_key}; +use opencv::imgproc::{cvt_color_def, ColorConversionCodes}; +use opencv::prelude::{MatTraitConst, VideoCaptureTrait, VideoCaptureTraitConst}; +use opencv::videoio::{VideoCapture, VideoCaptureProperties, VideoWriter, VideoWriterTrait}; + +juno_build::juno!("edge_detection"); + +#[derive(Parser)] +#[clap(author, version, about, long_about = None)] +pub struct EdgeDetectionInputs { + pub input: String, + #[clap(short, long)] + pub display: bool, + #[clap(short, long, value_name = "PATH")] + pub output: Option<String>, + #[clap(short, long)] + pub verify: bool, + #[clap(long = "display-verify")] + pub display_verify: bool, + #[clap(long = "output-verify", value_name = "PATH")] + pub output_verify: Option<String>, + #[clap(short, long, value_name = "COUNT")] + pub frames: Option<usize>, +} + +fn load_frame(video: &mut VideoCapture) -> Mat { + let mut frame = Mat::default(); + + let Ok(true) = video.read(&mut frame) else { + panic!("Failed to load frame"); + }; + let result = if frame.channels() == 3 { + let mut converted = Mat::default(); + let () = cvt_color_def( + &frame, + &mut converted, + ColorConversionCodes::COLOR_BGR2GRAY.into(), + ) + .expect("Failure in conversion to grayscale"); + let mut result = Mat::default(); + let () = converted + .convert_to(&mut result, CV_32F, 1.0 / 255.0, 0.0) + .expect("Failure in conversion to f32"); + result + } else if frame.channels() == 1 { + let mut result = Mat::default(); + let () = frame + .convert_to(&mut result, CV_32F, 1.0 / 255.0, 0.0) + .expect("Failure in conversion to f32"); + result + } else { + panic!("Expected either RGB or grayscale image"); + }; + + assert!(result.is_continuous()); + result +} + +fn frame_from_slice(frame: &[f32], height: usize, width: usize) -> Mat { + let result = Mat::from_slice(frame) + .expect("Failed to create matrix from result") + .reshape(1, height as i32) + .expect("Failed to reshape result matrix") + .clone_pointee(); + assert!(result.cols() == width as i32); + + // Convert to u8 since the VideoWriter seems to require that + let mut converted = Mat::default(); + let () = result + .convert_to(&mut converted, CV_8U, 255.0, 0.0) + .expect("Failure in conversion to u8"); + + converted +} + +pub fn edge_detection_harness(args: EdgeDetectionInputs) { + let EdgeDetectionInputs { + input, + display, + output, + verify, + display_verify, + output_verify, + frames, + } = args; + + let gs: usize = 7; + let gaussian_filter: Vec<f32> = vec![ + 0.000036, 0.000363, 0.001446, 0.002291, 0.001446, 0.000363, 0.000036, 0.000363, 0.003676, + 0.014662, 0.023226, 0.014662, 0.003676, 0.000363, 0.001446, 0.014662, 0.058488, 0.092651, + 0.058488, 0.014662, 0.001446, 0.002291, 0.023226, 0.092651, 0.146768, 0.092651, 0.023226, + 0.002291, 0.001446, 0.014662, 0.058488, 0.092651, 0.058488, 0.014662, 0.001446, 0.000363, + 0.003676, 0.014662, 0.023226, 0.014662, 0.003676, 0.000363, 0.000036, 0.000363, 0.001446, + 0.002291, 0.001446, 0.000363, 0.000036, + ]; + let gaussian_filter_h = HerculesImmBox::from(gaussian_filter.as_slice()); + + let sz: usize = 3; + let structure: Vec<f32> = vec![1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]; + let structure_h = HerculesImmBox::from(structure.as_slice()); + + let sb: usize = 3; + let sx: Vec<f32> = vec![-1.0, 0.0, 1.0, -2.0, 0.0, 2.0, -1.0, 0.0, 1.0]; + let sx_h = HerculesImmBox::from(sx.as_slice()); + + let sy: Vec<f32> = vec![-1.0, -2.0, -1.0, 0.0, 0.0, 0.0, 1.0, 2.0, 1.0]; + let sy_h = HerculesImmBox::from(sy.as_slice()); + + let theta: f32 = 0.1; + + let mut video = VideoCapture::from_file_def(&input).expect("Error loading video"); + assert!(video.is_opened().unwrap()); + + let fps = video + .get(VideoCaptureProperties::CAP_PROP_FPS.into()) + .expect("Error getting fps"); + + let num_frames = video + .get(VideoCaptureProperties::CAP_PROP_FRAME_COUNT.into()) + .expect("Error getting number of frames") as usize; + let width = video + .get(VideoCaptureProperties::CAP_PROP_FRAME_WIDTH.into()) + .expect("Error getting width") as usize; + let height = video + .get(VideoCaptureProperties::CAP_PROP_FRAME_HEIGHT.into()) + .expect("Error getting height") as usize; + + let num_frames = if let Some(frames) = frames { + usize::min(frames, num_frames) + } else { + num_frames + }; + + let mut r = runner!(edge_detection); + + let mut output = output.map(|filename| { + VideoWriter::new( + &filename, + VideoWriter::fourcc('m', 'p', '4', 'v').unwrap(), + fps, + Size { + width: width as i32, + height: height as i32, + }, + false, + ) + .expect("Error opening output video") + }); + + let mut output_verify = output_verify.map(|filename| { + VideoWriter::new( + &filename, + VideoWriter::fourcc('m', 'p', '4', 'v').unwrap(), + fps, + Size { + width: width as i32, + height: height as i32, + }, + false, + ) + .expect("Error opening output video") + }); + + for i in 0..num_frames { + let frame = load_frame(&mut video); + let ptr = frame.ptr_def().unwrap() as *const f32; + + assert!(frame.rows() as usize == height); + assert!(frame.cols() as usize == width); + + let input = unsafe { from_raw_parts(ptr, height * width) }; + + let input_h = HerculesImmBox::from(input); + + let result = async_std::task::block_on(async { + HerculesMutBox::from( + r.run( + height as u64, + width as u64, + gs as u64, + sz as u64, + sb as u64, + input_h.to(), + gaussian_filter_h.to(), + structure_h.to(), + sx_h.to(), + sy_h.to(), + theta, + ) + .await, + ) + }) + .as_slice() + .to_vec(); + + if display { + let result = frame_from_slice(&result, height, width); + let () = imshow("Juno", &result).expect("Failure in displaying image"); + } + if let Some(ref mut output) = output { + let result = frame_from_slice(&result, height, width); + let () = output.write(&result).expect("Failure in writing frame"); + } + + if verify { + let rust_result = edge_detection_rust::edge_detection( + height, + width, + gs, + sz, + sb, + input, + &gaussian_filter, + &structure, + &sx, + &sy, + theta, + ); + + assert_eq!(result, rust_result); + println!("Frames {} match", i); + + if display_verify { + let rust_result = frame_from_slice(&rust_result, height, width); + let () = imshow("Rust", &rust_result).expect("Failure in displaying image"); + } + if let Some(ref mut output) = output_verify { + let result = frame_from_slice(&rust_result, height, width); + let () = output.write(&result).expect("Failure in writing frame"); + } + } + + if display || (verify && display_verify) { + let _ = wait_key(0); + } + } + + if let Some(mut output) = output { + let () = output.release().expect("Failure releasing output video"); + } + if let Some(mut output) = output_verify { + let () = output.release().expect("Failure releasing output video"); + } +} diff --git a/juno_samples/edge_detection/src/main.rs b/juno_samples/edge_detection/src/main.rs index 60ccb515..23c4903a 100644 --- a/juno_samples/edge_detection/src/main.rs +++ b/juno_samples/edge_detection/src/main.rs @@ -1,290 +1,6 @@ -#![feature(concat_idents)] - -mod edge_detection_rust; - -use hercules_rt::{runner, HerculesImmBox, HerculesImmBoxTo, HerculesMutBox}; - -use std::slice::from_raw_parts; - use clap::Parser; -use opencv::core::{Mat, Size, CV_32F, CV_8U}; -use opencv::highgui::{imshow, wait_key}; -use opencv::imgproc::{cvt_color_def, ColorConversionCodes}; -use opencv::prelude::{MatTraitConst, VideoCaptureTrait, VideoCaptureTraitConst}; -use opencv::videoio::{VideoCapture, VideoCaptureProperties, VideoWriter, VideoWriterTrait}; - -juno_build::juno!("edge_detection"); - -#[derive(Parser)] -#[clap(author, version, about, long_about = None)] -struct EdgeDetectionInputs { - input: String, - #[clap(short, long)] - display: bool, - #[clap(short, long, value_name = "PATH")] - output: Option<String>, - #[clap(short, long)] - verify: bool, - #[clap(long = "display-verify")] - display_verify: bool, - #[clap(long = "output-verify", value_name = "PATH")] - output_verify: Option<String>, - #[clap(short, long, value_name = "COUNT")] - frames: Option<usize>, -} - -fn load_frame(video: &mut VideoCapture) -> Mat { - let mut frame = Mat::default(); - - let Ok(true) = video.read(&mut frame) else { - panic!("Failed to load frame"); - }; - let result = if frame.channels() == 3 { - let mut converted = Mat::default(); - let () = cvt_color_def( - &frame, - &mut converted, - ColorConversionCodes::COLOR_BGR2GRAY.into(), - ) - .expect("Failure in conversion to grayscale"); - let mut result = Mat::default(); - let () = converted - .convert_to(&mut result, CV_32F, 1.0 / 255.0, 0.0) - .expect("Failure in conversion to f32"); - result - } else if frame.channels() == 1 { - let mut result = Mat::default(); - let () = frame - .convert_to(&mut result, CV_32F, 1.0 / 255.0, 0.0) - .expect("Failure in conversion to f32"); - result - } else { - panic!("Expected either RGB or grayscale image"); - }; - - assert!(result.is_continuous()); - result -} - -fn frame_from_slice(frame: &[f32], height: usize, width: usize) -> Mat { - let result = Mat::from_slice(frame) - .expect("Failed to create matrix from result") - .reshape(1, height as i32) - .expect("Failed to reshape result matrix") - .clone_pointee(); - assert!(result.cols() == width as i32); - - // Convert to u8 since the VideoWriter seems to require that - let mut converted = Mat::default(); - let () = result - .convert_to(&mut converted, CV_8U, 255.0, 0.0) - .expect("Failure in conversion to u8"); - - converted -} - -async fn safe_run<'a, 'b, 'c, 'd, 'e, 'f>( - runner: &'a mut HerculesRunner_edge_detection, - n: u64, - m: u64, - gs: u64, - sz: u64, - sb: u64, - input: &'b HerculesImmBox<'b, f32>, - gaussian_filter: &'c HerculesImmBox<'c, f32>, - structure: &'d HerculesImmBox<'d, f32>, - sx: &'e HerculesImmBox<'e, f32>, - sy: &'f HerculesImmBox<'f, f32>, - theta: f32, -) -> HerculesMutBox<'a, f32> { - HerculesMutBox::from( - runner - .run( - n, - m, - gs, - sz, - sb, - input.to(), - gaussian_filter.to(), - structure.to(), - sx.to(), - sy.to(), - theta, - ) - .await, - ) -} - -fn edge_detection_harness(args: EdgeDetectionInputs) { - let EdgeDetectionInputs { - input, - display, - output, - verify, - display_verify, - output_verify, - frames, - } = args; - - let gs: usize = 7; - let gaussian_filter: Vec<f32> = vec![ - 0.000036, 0.000363, 0.001446, 0.002291, 0.001446, 0.000363, 0.000036, 0.000363, 0.003676, - 0.014662, 0.023226, 0.014662, 0.003676, 0.000363, 0.001446, 0.014662, 0.058488, 0.092651, - 0.058488, 0.014662, 0.001446, 0.002291, 0.023226, 0.092651, 0.146768, 0.092651, 0.023226, - 0.002291, 0.001446, 0.014662, 0.058488, 0.092651, 0.058488, 0.014662, 0.001446, 0.000363, - 0.003676, 0.014662, 0.023226, 0.014662, 0.003676, 0.000363, 0.000036, 0.000363, 0.001446, - 0.002291, 0.001446, 0.000363, 0.000036, - ]; - let gaussian_filter_h = HerculesImmBox::from(gaussian_filter.as_slice()); - - let sz: usize = 3; - let structure: Vec<f32> = vec![1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]; - let structure_h = HerculesImmBox::from(structure.as_slice()); - - let sb: usize = 3; - let sx: Vec<f32> = vec![-1.0, 0.0, 1.0, -2.0, 0.0, 2.0, -1.0, 0.0, 1.0]; - let sx_h = HerculesImmBox::from(sx.as_slice()); - - let sy: Vec<f32> = vec![-1.0, -2.0, -1.0, 0.0, 0.0, 0.0, 1.0, 2.0, 1.0]; - let sy_h = HerculesImmBox::from(sy.as_slice()); - - let theta: f32 = 0.1; - - let mut video = VideoCapture::from_file_def(&input).expect("Error loading video"); - assert!(video.is_opened().unwrap()); - - let fps = video - .get(VideoCaptureProperties::CAP_PROP_FPS.into()) - .expect("Error getting fps"); - - let num_frames = video - .get(VideoCaptureProperties::CAP_PROP_FRAME_COUNT.into()) - .expect("Error getting number of frames") as usize; - let width = video - .get(VideoCaptureProperties::CAP_PROP_FRAME_WIDTH.into()) - .expect("Error getting width") as usize; - let height = video - .get(VideoCaptureProperties::CAP_PROP_FRAME_HEIGHT.into()) - .expect("Error getting height") as usize; - - let num_frames = if let Some(frames) = frames { - usize::min(frames, num_frames) - } else { - num_frames - }; - - let mut r = runner!(edge_detection); - - let mut output = output.map(|filename| { - VideoWriter::new( - &filename, - VideoWriter::fourcc('m', 'p', '4', 'v').unwrap(), - fps, - Size { - width: width as i32, - height: height as i32, - }, - false, - ) - .expect("Error opening output video") - }); - - let mut output_verify = output_verify.map(|filename| { - VideoWriter::new( - &filename, - VideoWriter::fourcc('m', 'p', '4', 'v').unwrap(), - fps, - Size { - width: width as i32, - height: height as i32, - }, - false, - ) - .expect("Error opening output video") - }); - - for i in 0..num_frames { - let frame = load_frame(&mut video); - let ptr = frame.ptr_def().unwrap() as *const f32; - - assert!(frame.rows() as usize == height); - assert!(frame.cols() as usize == width); - - let input = unsafe { from_raw_parts(ptr, height * width) }; - - let input_h = HerculesImmBox::from(input); - - let result = async_std::task::block_on(async { - safe_run( - &mut r, - height as u64, - width as u64, - gs as u64, - sz as u64, - sb as u64, - &input_h, - &gaussian_filter_h, - &structure_h, - &sx_h, - &sy_h, - theta, - ) - .await - }) - .as_slice() - .to_vec(); - - if display { - let result = frame_from_slice(&result, height, width); - let () = imshow("Juno", &result).expect("Failure in displaying image"); - } - if let Some(ref mut output) = output { - let result = frame_from_slice(&result, height, width); - let () = output.write(&result).expect("Failure in writing frame"); - } - - if verify { - let rust_result = edge_detection_rust::edge_detection( - height, - width, - gs, - sz, - sb, - input, - &gaussian_filter, - &structure, - &sx, - &sy, - theta, - ); - - assert_eq!(result, rust_result); - println!("Frames {} match", i); - - if display_verify { - let rust_result = frame_from_slice(&rust_result, height, width); - let () = imshow("Rust", &rust_result).expect("Failure in displaying image"); - } - if let Some(ref mut output) = output_verify { - let result = frame_from_slice(&rust_result, height, width); - let () = output.write(&result).expect("Failure in writing frame"); - } - } - - if display || (verify && display_verify) { - let _ = wait_key(0); - } - } - - if let Some(mut output) = output { - let () = output.release().expect("Failure releasing output video"); - } - if let Some(mut output) = output_verify { - let () = output.release().expect("Failure releasing output video"); - } -} +use juno_edge_detection::{edge_detection_harness, EdgeDetectionInputs}; fn main() { let args = EdgeDetectionInputs::parse(); -- GitLab From 62d760d707e2ee8eac05a9850362245c02666e65 Mon Sep 17 00:00:00 2001 From: Russel Arbore <russel.jma@gmail.com> Date: Tue, 18 Feb 2025 21:51:51 -0600 Subject: [PATCH 2/3] Bench for edge detection --- Cargo.lock | 1 + juno_samples/edge_detection/Cargo.toml | 7 ++ .../benches/edge_detection_bench.rs | 102 ++++++++++++++++++ juno_samples/edge_detection/src/lib.rs | 4 +- 4 files changed, 112 insertions(+), 2 deletions(-) create mode 100644 juno_samples/edge_detection/benches/edge_detection_bench.rs diff --git a/Cargo.lock b/Cargo.lock index 1973fbbe..ebe621e8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1338,6 +1338,7 @@ version = "0.1.0" dependencies = [ "async-std", "clap", + "criterion", "hercules_rt", "juno_build", "opencv", diff --git a/juno_samples/edge_detection/Cargo.toml b/juno_samples/edge_detection/Cargo.toml index bd2ae5c9..fc5fb451 100644 --- a/juno_samples/edge_detection/Cargo.toml +++ b/juno_samples/edge_detection/Cargo.toml @@ -27,3 +27,10 @@ async-std = "*" clap = { version = "*", features = ["derive"] } with_builtin_macros = "0.1.0" opencv = { version = "*", features = ["clang-runtime"], optional = true } + +[dev-dependencies] +criterion = { version = "0.5", features = ["html_reports"] } + +[[bench]] +name = "edge_detection_bench" +harness = false diff --git a/juno_samples/edge_detection/benches/edge_detection_bench.rs b/juno_samples/edge_detection/benches/edge_detection_bench.rs new file mode 100644 index 00000000..f7f00410 --- /dev/null +++ b/juno_samples/edge_detection/benches/edge_detection_bench.rs @@ -0,0 +1,102 @@ +#![feature(concat_idents)] +use std::slice::from_raw_parts; + +use criterion::{criterion_group, criterion_main, Criterion}; + +use opencv::core::{Mat, Size, CV_32F, CV_8U}; +use opencv::imgproc::{cvt_color_def, ColorConversionCodes}; +use opencv::prelude::{MatTraitConst, VideoCaptureTrait, VideoCaptureTraitConst}; +use opencv::videoio::{VideoCapture, VideoCaptureProperties, VideoWriter, VideoWriterTrait}; + +use hercules_rt::{runner, HerculesImmBox, HerculesImmBoxTo}; + +use juno_edge_detection::*; + +juno_build::juno!("edge_detection"); + +fn edge_detection_bench(c: &mut Criterion) { + let mut group = c.benchmark_group("edge detection bench"); + group.sample_size(10); + + let input = "examples/formula1_scaled.mp4"; + + let gs: usize = 7; + let gaussian_filter: Vec<f32> = vec![ + 0.000036, 0.000363, 0.001446, 0.002291, 0.001446, 0.000363, 0.000036, 0.000363, 0.003676, + 0.014662, 0.023226, 0.014662, 0.003676, 0.000363, 0.001446, 0.014662, 0.058488, 0.092651, + 0.058488, 0.014662, 0.001446, 0.002291, 0.023226, 0.092651, 0.146768, 0.092651, 0.023226, + 0.002291, 0.001446, 0.014662, 0.058488, 0.092651, 0.058488, 0.014662, 0.001446, 0.000363, + 0.003676, 0.014662, 0.023226, 0.014662, 0.003676, 0.000363, 0.000036, 0.000363, 0.001446, + 0.002291, 0.001446, 0.000363, 0.000036, + ]; + let gaussian_filter_h = HerculesImmBox::from(gaussian_filter.as_slice()); + + let sz: usize = 3; + let structure: Vec<f32> = vec![1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0]; + let structure_h = HerculesImmBox::from(structure.as_slice()); + + let sb: usize = 3; + let sx: Vec<f32> = vec![-1.0, 0.0, 1.0, -2.0, 0.0, 2.0, -1.0, 0.0, 1.0]; + let sx_h = HerculesImmBox::from(sx.as_slice()); + + let sy: Vec<f32> = vec![-1.0, -2.0, -1.0, 0.0, 0.0, 0.0, 1.0, 2.0, 1.0]; + let sy_h = HerculesImmBox::from(sy.as_slice()); + + let theta: f32 = 0.1; + + let mut video = VideoCapture::from_file_def(&input).expect("Error loading video"); + assert!(video.is_opened().unwrap()); + + let fps = video + .get(VideoCaptureProperties::CAP_PROP_FPS.into()) + .expect("Error getting fps"); + + let _num_frames = video + .get(VideoCaptureProperties::CAP_PROP_FRAME_COUNT.into()) + .expect("Error getting number of frames") as usize; + let width = video + .get(VideoCaptureProperties::CAP_PROP_FRAME_WIDTH.into()) + .expect("Error getting width") as usize; + let height = video + .get(VideoCaptureProperties::CAP_PROP_FRAME_HEIGHT.into()) + .expect("Error getting height") as usize; + let num_frames = 5; + + let mut r = runner!(edge_detection); + + group.bench_function("edge detection bench", |b| { + b.iter(|| { + for i in 0..num_frames { + let frame = load_frame(&mut video); + let ptr = frame.ptr_def().unwrap() as *const f32; + + assert!(frame.rows() as usize == height); + assert!(frame.cols() as usize == width); + + let input = unsafe { from_raw_parts(ptr, height * width) }; + + let input_h = HerculesImmBox::from(input); + + let result = async_std::task::block_on(async { + r.run( + height as u64, + width as u64, + gs as u64, + sz as u64, + sb as u64, + input_h.to(), + gaussian_filter_h.to(), + structure_h.to(), + sx_h.to(), + sy_h.to(), + theta, + ) + .await + }); + } + }) + }); +} + +criterion_group!(benches, edge_detection_bench); +criterion_main!(benches); diff --git a/juno_samples/edge_detection/src/lib.rs b/juno_samples/edge_detection/src/lib.rs index f675d5f5..37268b56 100644 --- a/juno_samples/edge_detection/src/lib.rs +++ b/juno_samples/edge_detection/src/lib.rs @@ -34,7 +34,7 @@ pub struct EdgeDetectionInputs { pub frames: Option<usize>, } -fn load_frame(video: &mut VideoCapture) -> Mat { +pub fn load_frame(video: &mut VideoCapture) -> Mat { let mut frame = Mat::default(); let Ok(true) = video.read(&mut frame) else { @@ -67,7 +67,7 @@ fn load_frame(video: &mut VideoCapture) -> Mat { result } -fn frame_from_slice(frame: &[f32], height: usize, width: usize) -> Mat { +pub fn frame_from_slice(frame: &[f32], height: usize, width: usize) -> Mat { let result = Mat::from_slice(frame) .expect("Failed to create matrix from result") .reshape(1, height as i32) -- GitLab From 8292e6dfb008e84b59fccd528776cef8ab455e93 Mon Sep 17 00:00:00 2001 From: Russel Arbore <russel.jma@gmail.com> Date: Tue, 18 Feb 2025 21:54:06 -0600 Subject: [PATCH 3/3] Fix bench --- juno_samples/edge_detection/benches/edge_detection_bench.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/juno_samples/edge_detection/benches/edge_detection_bench.rs b/juno_samples/edge_detection/benches/edge_detection_bench.rs index f7f00410..806a8865 100644 --- a/juno_samples/edge_detection/benches/edge_detection_bench.rs +++ b/juno_samples/edge_detection/benches/edge_detection_bench.rs @@ -64,10 +64,12 @@ fn edge_detection_bench(c: &mut Criterion) { let mut r = runner!(edge_detection); + let frames: Vec<_> = (0..num_frames).map(|_| load_frame(&mut video)).collect(); + group.bench_function("edge detection bench", |b| { b.iter(|| { for i in 0..num_frames { - let frame = load_frame(&mut video); + let frame = &frames[i]; let ptr = frame.ptr_def().unwrap() as *const f32; assert!(frame.rows() as usize == height); -- GitLab