//! Detection model benchmarks //! //! Comprehensive performance benchmarks for: //! - YOLO v8/v9 variants (Nano, Small, Medium, Large, XLarge) //! - R-CNN family (Fast R-CNN, Faster R-CNN, Mask R-CNN) //! - 3D object detection (PointRCNN, VoxelNet) //! - Real-time vs accuracy trade-offs use criterion::{BenchmarkId, Criterion, Throughput, criterion_group, criterion_main}; use rtx_tensor::{DType, Device, Tensor}; use rtx_vision_advanced::*; /// Benchmark helper for creating test data struct BenchmarkHelper; impl BenchmarkHelper { fn create_image(batch_size: usize, height: usize, width: usize) -> Tensor { Tensor::randn(&[batch_size, 3, height, width], &Device::default()) .expect("Failed to create benchmark image") } fn create_point_cloud(num_points: usize) -> Tensor { Tensor::randn(&[num_points, 4], &Device::default()) .expect("Failed to create benchmark point cloud") } } /// Benchmark YOLO v8 detection variants fn bench_yolo_variants(c: &mut Criterion) { let mut group = c.benchmark_group("yolo_detection"); let yolo_variants = vec![ ("nano", detection::YOLOSize::Nano, (640, 640)), ("small", detection::YOLOSize::Small, (640, 640)), ("medium", detection::YOLOSize::Medium, (640, 640)), ("large", detection::YOLOSize::Large, (640, 640)), ("xlarge", detection::YOLOSize::XLarge, (640, 640)), ]; for (name, size, input_dims) in yolo_variants { let config = detection::YOLOConfig { model_size: size, num_classes: 80, confidence_threshold: 0.25, nms_threshold: 0.45, input_size: input_dims, }; let mut detector = detection::YOLOv8::new(config).expect("Failed to create YOLO detector"); let test_image = BenchmarkHelper::create_image(1, input_dims.0, input_dims.1); group.throughput(Throughput::Elements(1)); group.bench_with_input( BenchmarkId::new("single_image", name), &test_image, |b, image| { b.iter(|| detector.detect(image).expect("Detection failed")); }, ); // Batch processing benchmark let batch_image = BenchmarkHelper::create_image(8, input_dims.0, input_dims.1); group.throughput(Throughput::Elements(8)); group.bench_with_input( BenchmarkId::new("batch_8", name), &batch_image, |b, image| { b.iter(|| { detector .detect_batch(image) .expect("Batch detection failed") }); }, ); } group.finish(); } /// Benchmark R-CNN family models fn bench_rcnn_family(c: &mut Criterion) { let mut group = c.benchmark_group("rcnn_detection"); // Faster R-CNN benchmark let mut faster_rcnn = detection::rcnn::FasterRCNN::new(80).expect("Failed to create Faster R-CNN"); let test_image = BenchmarkHelper::create_image(1, 800, 1333); group.throughput(Throughput::Elements(1)); group.bench_function("faster_rcnn_single", |b| { b.iter(|| faster_rcnn.detect(&test_image).expect("Detection failed")); }); // Mask R-CNN benchmark (instance segmentation) let mut mask_rcnn = segmentation::MaskRCNN::new(80).expect("Failed to create Mask R-CNN"); let segmentation_config = segmentation::SegmentationConfig::default(); group.bench_function("mask_rcnn_single", |b| { b.iter(|| { mask_rcnn .segment(&test_image, &segmentation_config) .expect("Segmentation failed") }); }); group.finish(); } /// Benchmark 3D object detection for autonomous vehicles fn bench_3d_detection(c: &mut Criterion) { let mut group = c.benchmark_group("3d_detection"); let point_cloud_sizes = vec![("small", 10000), ("medium", 50000), ("large", 100000)]; let mut detector = detection::three_d::PointRCNN::new().expect("Failed to create 3D detector"); for (size_name, num_points) in point_cloud_sizes { let point_cloud = BenchmarkHelper::create_point_cloud(num_points); group.throughput(Throughput::Elements(num_points as u64)); group.bench_with_input( BenchmarkId::new("pointrcnn", size_name), &point_cloud, |b, pc| { b.iter(|| detector.detect_3d(pc).expect("3D detection failed")); }, ); } group.finish(); } /// Benchmark real-time detection performance fn bench_realtime_performance(c: &mut Criterion) { let mut group = c.benchmark_group("realtime_detection"); // Test different input resolutions for real-time performance let resolutions = vec![ ("320p", 320, 320), ("480p", 480, 640), ("720p", 720, 1280), ("1080p", 1080, 1920), ]; let config = detection::YOLOConfig { model_size: detection::YOLOSize::Small, // Optimized for speed num_classes: 80, confidence_threshold: 0.25, nms_threshold: 0.45, input_size: (640, 640), // Will be overridden }; for (res_name, height, width) in resolutions { let mut config = config.clone(); config.input_size = (height, width); let mut detector = detection::YOLOv8::new(config).expect("Failed to create real-time detector"); let test_image = BenchmarkHelper::create_image(1, height, width); let pixels = (height * width) as u64; group.throughput(Throughput::Elements(pixels)); group.bench_with_input( BenchmarkId::new("realtime_yolo", res_name), &test_image, |b, image| { b.iter(|| detector.detect(image).expect("Real-time detection failed")); }, ); } group.finish(); } /// Benchmark video object tracking fn bench_video_tracking(c: &mut Criterion) { let mut group = c.benchmark_group("video_tracking"); let mut tracker = detection::video::MultiObjectTracker::new().expect("Failed to create video tracker"); // Simulate different numbers of objects to track let object_counts = vec![1, 5, 10, 20, 50]; for num_objects in object_counts { let mut detections = Vec::new(); // Create dummy detections for i in 0..num_objects { detections.push(BoundingBox::new( i as f32 * 50.0, i as f32 * 30.0, 40.0, 60.0, 0.8, i % 3, // Cycle through 3 classes )); } group.throughput(Throughput::Elements(num_objects as u64)); group.bench_with_input( BenchmarkId::new("multi_object_tracking", num_objects), &detections, |b, dets| { b.iter(|| tracker.update(dets, 0.0).expect("Tracking failed")); }, ); } group.finish(); } /// Benchmark detection accuracy vs speed trade-offs fn bench_accuracy_speed_tradeoff(c: &mut Criterion) { let mut group = c.benchmark_group("accuracy_speed_tradeoff"); // Different model configurations representing accuracy vs speed trade-offs let configs = vec![ ("speed_optimized", detection::YOLOSize::Nano, 0.5, 0.6), // Fast, lower accuracy ("balanced", detection::YOLOSize::Small, 0.25, 0.45), // Balanced ("accuracy_optimized", detection::YOLOSize::Large, 0.1, 0.35), // Slower, higher accuracy ]; let test_image = BenchmarkHelper::create_image(1, 640, 640); for (config_name, model_size, conf_thresh, nms_thresh) in configs { let config = detection::YOLOConfig { model_size, num_classes: 80, confidence_threshold: conf_thresh, nms_threshold: nms_thresh, input_size: (640, 640), }; let mut detector = detection::YOLOv8::new(config).expect("Failed to create detector"); group.bench_with_input( BenchmarkId::new("tradeoff", config_name), &test_image, |b, image| { b.iter(|| detector.detect(image).expect("Detection failed")); }, ); } group.finish(); } /// Benchmark memory usage during detection fn bench_memory_usage(c: &mut Criterion) { let mut group = c.benchmark_group("memory_usage"); // Test memory usage with different batch sizes let batch_sizes = vec![1, 4, 8, 16, 32]; let config = detection::YOLOConfig::default(); let mut detector = detection::YOLOv8::new(config).expect("Failed to create detector"); for batch_size in batch_sizes { let batch_image = BenchmarkHelper::create_image(batch_size, 640, 640); group.throughput(Throughput::Elements(batch_size as u64)); group.bench_with_input( BenchmarkId::new("memory_batch", batch_size), &batch_image, |b, image| { b.iter(|| { detector .detect_batch(image) .expect("Batch detection failed") }); }, ); } group.finish(); } criterion_group!( benches, bench_yolo_variants, bench_rcnn_family, bench_3d_detection, bench_realtime_performance, bench_video_tracking, bench_accuracy_speed_tradeoff, bench_memory_usage ); criterion_main!(benches);