Skip to content

Commit

Permalink
benches
Browse files Browse the repository at this point in the history
  • Loading branch information
JeroenGar committed Feb 13, 2024
1 parent 6ac1032 commit ebe928f
Show file tree
Hide file tree
Showing 9 changed files with 205 additions and 128 deletions.
4 changes: 2 additions & 2 deletions jaguars/src/entities/problems/bin_packing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,12 @@ impl ProblemGeneric for BPProblem {
self.layout_has_changed(layout_id);
}

fn remove_item(&mut self, layout_index: LayoutIndex, pi_uid: &PlacedItemUID) {
fn remove_item(&mut self, layout_index: LayoutIndex, pi_uid: &PlacedItemUID, commit_instantly: bool) {
match layout_index {
LayoutIndex::Existing(i) => {
self.layout_has_changed(self.layouts[i].id());
let layout = &mut self.layouts[i];
layout.remove_item(pi_uid, false);
layout.remove_item(pi_uid, commit_instantly);
if layout.is_empty() {
//if layout is empty, remove it
self.unregister_layout(layout_index);
Expand Down
2 changes: 1 addition & 1 deletion jaguars/src/entities/problems/problem.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ pub trait ProblemGeneric: ProblemGenericPrivate {
fn place_item(&mut self, i_opt: &PlacingOption);

/// Removes an item with a specific `PlacedItemUID` from a specific `Layout`
fn remove_item(&mut self, layout_index: LayoutIndex, pi_uid: &PlacedItemUID);
fn remove_item(&mut self, layout_index: LayoutIndex, pi_uid: &PlacedItemUID, commit_instantly: bool);

/// Saves the current state into a `Solution`.
fn create_solution(&mut self, old_solution: &Option<Solution>) -> Solution;
Expand Down
4 changes: 2 additions & 2 deletions jaguars/src/entities/problems/strip_packing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -111,9 +111,9 @@ impl ProblemGeneric for SPProblem {
self.register_included_item(item_id);
}

fn remove_item(&mut self, layout_index: LayoutIndex, pi_uid: &PlacedItemUID) {
fn remove_item(&mut self, layout_index: LayoutIndex, pi_uid: &PlacedItemUID, commit_instantly: bool) {
assert_eq!(layout_index, LayoutIndex::Existing(0), "strip packing problems only have a single layout");
self.layout.remove_item(pi_uid, false);
self.layout.remove_item(pi_uid, commit_instantly);
self.unregister_included_item(pi_uid.item_id);
}

Expand Down
6 changes: 3 additions & 3 deletions lbf/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,9 @@ harness = false
name = "fast_fail_bench"
harness = false

[[bench]]
name = "edge_sensitivity_bench"
harness = false
#[[bench]]
#name = "edge_sensitivity_bench"
#harness = false

[[bench]]
name = "hpg_bench"
Expand Down
8 changes: 5 additions & 3 deletions lbf/benches/edge_sensitivity_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ use lbf::io;
use lbf::io::svg_util::SvgDrawOptions;
use lbf::samplers::hpg_sampler::HPGSampler;
use lbf::samplers::uniform_rect_sampler::UniformAARectSampler;
use crate::util::{N_ITEMS_REMOVED, N_SAMPLES, SWIM_PATH};
use crate::util::{N_ITEMS_REMOVED, N_SAMPLES_PER_ITER, N_TOTAL_SAMPLES, SWIM_PATH};

criterion_main!(benches);
criterion_group!(benches, edge_sensitivity_bench_no_ff, edge_sensitivity_bench_with_ff);
Expand Down Expand Up @@ -77,11 +77,13 @@ fn edge_sensitivity_bench(config: Config, mut g: BenchmarkGroup<WallTime>) {

let samples = {
let hpg_sampler = HPGSampler::new(instance.item(0), layout).expect("should be able to create HPGSampler");
(0..N_SAMPLES).map(
(0..N_TOTAL_SAMPLES).map(
|_| hpg_sampler.sample(&mut rng)
).collect_vec()
};

let mut samples_cycler = samples.chunks(N_SAMPLES_PER_ITER).cycle();

let mut n_invalid: i64 = 0;
let mut n_valid: i64 = 0;

Expand All @@ -91,7 +93,7 @@ fn edge_sensitivity_bench(config: Config, mut g: BenchmarkGroup<WallTime>) {
let pi_uid = &selected_pi_uids[i];
let item = instance.item(pi_uid.item_id);
let mut buffer_shape = item.shape().clone();
for transf in &samples {
for transf in samples_cycler.next().unwrap() {
let collides = match layout.cde().surrogate_collides(item.shape().surrogate(), transf, &[]) {
true => true,
false => {
Expand Down
41 changes: 22 additions & 19 deletions lbf/benches/fast_fail_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,15 @@ use lbf::io::svg_util::SvgDrawOptions;
use lbf::lbf_optimizer::LBFOptimizer;
use lbf::samplers::hpg_sampler::HPGSampler;
use lbf::samplers::uniform_rect_sampler::UniformAARectSampler;
use crate::util::{create_base_config, N_ITEMS_REMOVED, N_SAMPLES, SWIM_PATH};
use crate::util::{create_base_config, N_ITEMS_REMOVED, N_SAMPLES_PER_ITER, N_TOTAL_SAMPLES, SWIM_PATH};

criterion_main!(benches);
criterion_group!(benches, fast_fail_query_bench);

mod util;

const FF_POLE_RANGE: RangeInclusive<usize> = 0..=4;
const FF_PIER_RANGE: RangeInclusive<usize> = 0..=0;
const FF_PIER_RANGE: RangeInclusive<usize> = 0..=4;

/// Benchmark the query operation of the quadtree for different depths
/// We validate 1000 sampled transformations for each of the 5 removed items
Expand Down Expand Up @@ -84,33 +84,36 @@ fn fast_fail_query_bench(c: &mut Criterion) {
.map(|item_id| {
let item = instance.item(item_id);
let sampler = HPGSampler::new(item, layout).unwrap();
(0..N_SAMPLES).map(
(0..N_TOTAL_SAMPLES).map(
|_| sampler.sample(&mut rng)
).collect_vec()
}).collect_vec();

let mut samples_cycler = samples.iter().map(|s| s.chunks(N_SAMPLES_PER_ITER).cycle()).collect_vec();

let mut n_invalid: i64 = 0;
let mut n_valid : i64 = 0;

let mut i_cycler = (0..N_ITEMS_REMOVED).cycle();

group.bench_function(BenchmarkId::from_parameter(format!("{n_ff_poles}_poles_{n_ff_piers}_piers")), |b| {
b.iter(|| {
for i in 0..N_ITEMS_REMOVED {
let pi_uid = &selected_pi_uids[i];
let item = instance.item(pi_uid.item_id);
let surrogate = &custom_surrogates[i];
let mut buffer_shape = item.shape().clone();
for transf in samples[i].iter() {
let collides = match layout.cde().surrogate_collides(surrogate, transf, &[]) {
true => true,
false => {
buffer_shape.transform_from(item.shape(), transf);
layout.cde().shape_collides(&buffer_shape, &[])
}
};
match collides {
true => n_invalid += 1,
false => n_valid += 1
let i = i_cycler.next().unwrap();
let pi_uid = &selected_pi_uids[i];
let item = instance.item(pi_uid.item_id);
let surrogate = &custom_surrogates[i];
let mut buffer_shape = item.shape().clone();
for transf in samples_cycler[i].next().unwrap() {
let collides = match layout.cde().surrogate_collides(surrogate, transf, &[]) {
true => true,
false => {
buffer_shape.transform_from(item.shape(), transf);
layout.cde().shape_collides(&buffer_shape, &[])
}
};
match collides {
true => n_invalid += 1,
false => n_valid += 1
}
}
})
Expand Down
114 changes: 101 additions & 13 deletions lbf/benches/hpg_bench.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,9 @@ use itertools::Itertools;
use rand::prelude::IteratorRandom;
use rand::rngs::SmallRng;
use rand::SeedableRng;
use jaguars::entities::layout::Layout;

use jaguars::entities::instance::{Instance, InstanceGeneric};
use jaguars::entities::placed_item::PlacedItemUID;
use jaguars::entities::placing_option::PlacingOption;
use jaguars::entities::problems::problem::{LayoutIndex, ProblemGeneric};
use jaguars::entities::problems::strip_packing::SPProblem;
Expand All @@ -24,7 +24,7 @@ use lbf::samplers::hpg_sampler::HPGSampler;
use crate::util::{create_base_config, N_ITEMS_REMOVED, N_VALID_SAMPLES, SWIM_PATH};

criterion_main!(benches);
criterion_group!(benches, hpg_bench);
criterion_group!(benches, hpg_update_bench, hpg_query_bench);

mod util;

Expand All @@ -33,15 +33,15 @@ mod util;
pub const N_HPG_CELLS: [usize; 6] = [100, 500, 1000, 5000, 10000, 20000];
pub const SELECTED_ITEM_ID: usize = 1; // relatively small and "round" item, guaranteed to find valid samples even without HPG

fn hpg_bench(c: &mut Criterion) {
fn hpg_query_bench(c: &mut Criterion) {
///HPG density has side effects on the LBF optimize, so we create a single problem instance and create a solution from it.
let json_instance: JsonInstance = serde_json::from_reader(BufReader::new(File::open(SWIM_PATH).unwrap())).unwrap();
let mut base_config = create_base_config();
let base_instance = util::create_instance(&json_instance, base_config.cde_config, base_config.poly_simpl_config);
let (mut base_problem, removed_items) = util::create_blf_problem(base_instance.clone(), base_config, N_ITEMS_REMOVED);
let base_pi_uids = base_problem.get_layout(LayoutIndex::Existing(0)).placed_items().iter().map(|pi| pi.uid().clone()).collect_vec();

let mut group = c.benchmark_group("hpg_bench");
let mut group = c.benchmark_group("hpg_bench_query");
for n_hpg_cells in N_HPG_CELLS {
let mut config = base_config;
config.cde_config.haz_prox = HazProxConfig::Enabled { n_cells: n_hpg_cells };
Expand All @@ -62,15 +62,15 @@ fn hpg_bench(c: &mut Criterion) {
}

{
let draw_options = SvgDrawOptions{
quadtree: false,
surrogate: false,
haz_prox_grid: true,
..SvgDrawOptions::default()
};
let svg = io::layout_to_svg::layout_to_svg(problem.get_layout(LayoutIndex::Existing(0)), &instance, draw_options);
io::write_svg(&svg, Path::new(&format!("removed_items_{n_hpg_cells}.svg")));
}
let draw_options = SvgDrawOptions {
quadtree: false,
surrogate: false,
haz_prox_grid: true,
..SvgDrawOptions::default()
};
let svg = io::layout_to_svg::layout_to_svg(problem.get_layout(LayoutIndex::Existing(0)), &instance, draw_options);
io::write_svg(&svg, Path::new(&format!("removed_items_{n_hpg_cells}.svg")));
}


let mut rng = SmallRng::seed_from_u64(0);
Expand Down Expand Up @@ -102,4 +102,92 @@ fn hpg_bench(c: &mut Criterion) {
});
}
group.finish();
}

fn hpg_update_bench(c: &mut Criterion) {
///HPG density has side effects on the LBF optimize, so we create a single problem instance and create a solution from it.
let json_instance: JsonInstance = serde_json::from_reader(BufReader::new(File::open(SWIM_PATH).unwrap())).unwrap();
let mut base_config = create_base_config();
let base_instance = util::create_instance(&json_instance, base_config.cde_config, base_config.poly_simpl_config);
let (mut base_problem, removed_items) = util::create_blf_problem(base_instance.clone(), base_config, N_ITEMS_REMOVED);
let base_pi_uids = base_problem.get_layout(LayoutIndex::Existing(0)).placed_items().iter().map(|pi| pi.uid().clone()).collect_vec();

let mut group = c.benchmark_group("hpg_bench_update");
for n_hpg_cells in N_HPG_CELLS {
let mut config = base_config;
config.cde_config.haz_prox = HazProxConfig::Enabled { n_cells: n_hpg_cells };
//create the instance and problem with the specific HPG config
let instance = util::create_instance(&json_instance, config.cde_config, config.poly_simpl_config);
let mut problem = match instance.clone() {
Instance::BP(_) => panic!("Expected SPInstance"),
Instance::SP(instance) => SPProblem::new(instance, base_problem.strip_width(), config.cde_config)
};
// Place the items in exactly the same way as the base problem
for pi_uid in base_pi_uids.iter() {
problem.place_item(&PlacingOption {
layout_index: LayoutIndex::Existing(0),
item_id: pi_uid.item_id,
transf: pi_uid.d_transf.compose(),
d_transf: pi_uid.d_transf.clone(),
});
}

{
let draw_options = SvgDrawOptions {
quadtree: false,
surrogate: false,
haz_prox_grid: true,
..SvgDrawOptions::default()
};
let svg = io::layout_to_svg::layout_to_svg(problem.get_layout(LayoutIndex::Existing(0)), &instance, draw_options);
io::write_svg(&svg, Path::new(&format!("removed_items_{n_hpg_cells}.svg")));
}

let mut rng = SmallRng::seed_from_u64(0);

// Search N_VALID_SAMPLES for each item
let item = instance.item(SELECTED_ITEM_ID);
let layout = problem.get_layout(LayoutIndex::Existing(0));
let surrogate = item.shape().surrogate();
let mut buffer_shape = item.shape().clone();
let sampler = HPGSampler::new(item, layout).unwrap();
println!("[{}] sampler coverage: {:.3}% with {} samplers", n_hpg_cells, sampler.coverage_area / layout.bin().bbox().area() * 100.0, sampler.cell_samplers.len());

//collect N_VALID_SAMPLES
let mut valid_placements = vec![];
while valid_placements.len() < N_VALID_SAMPLES {
let transf = sampler.sample(&mut rng);
if !layout.cde().surrogate_collides(surrogate, &transf, &[]) {
buffer_shape.transform_from(item.shape(), &transf);
if !layout.cde().shape_collides(&buffer_shape, &[]) {
let d_transf = transf.decompose();
valid_placements.push(PlacingOption {
layout_index: LayoutIndex::Existing(0),
item_id: SELECTED_ITEM_ID,
transf,
d_transf,
});
}
}
}

let mut valid_samples_cycler = valid_placements.iter().cycle();

group.bench_function(BenchmarkId::from_parameter(n_hpg_cells), |b| {
b.iter(|| {
let opt = valid_samples_cycler.next().unwrap();
problem.place_item(opt);
problem.remove_item(
LayoutIndex::Existing(0),
&PlacedItemUID {
item_id: opt.item_id,
d_transf: opt.d_transf.clone(),
},
true,
);
problem.flush_changes();
})
});
}
group.finish();
}
Loading

0 comments on commit ebe928f

Please sign in to comment.