Skip to content

Commit 076e0d0

Browse files
committed
Add benchmark instances into the integration test suite
1 parent 2d3f537 commit 076e0d0

File tree

4 files changed

+104
-163
lines changed

4 files changed

+104
-163
lines changed

crates/fzn-huub/benches/fzn_huub_benchmarks.rs

+14-77
Original file line numberDiff line numberDiff line change
@@ -9,18 +9,17 @@
99
reason = "only dependencies for benchmarking are used in this file"
1010
)]
1111

12-
use std::{
13-
io::Write,
14-
path::{Path, PathBuf},
15-
time::Duration,
16-
};
12+
#[path = "../tests/helpers/mod.rs"]
13+
mod helpers;
14+
15+
use std::{path::PathBuf, time::Duration};
1716

1817
use codspeed_criterion_compat::{
1918
criterion_main, measurement::Measurement, BenchmarkGroup, BenchmarkId, Criterion, SamplingMode,
2019
};
2120
use expect_test::expect_file;
22-
use fzn_huub::Cli;
23-
use pico_args::Arguments;
21+
22+
use crate::helpers::check_final;
2423

2524
/// A configuration for instances that run for a few seconds.
2625
const FEW_SECONDS_CONFIG: CriterionConfig = CriterionConfig {
@@ -29,17 +28,6 @@ const FEW_SECONDS_CONFIG: CriterionConfig = CriterionConfig {
2928
measurement_time: Some(Duration::from_secs(60)),
3029
};
3130

32-
/// The string that is printed when the solver has proven that no more/better
33-
/// solutions exist.
34-
const FZN_COMPLETE: &str = "==========\n";
35-
36-
/// The string that is printed after every solution.
37-
const FZN_SEPERATOR: &str = "----------\n";
38-
39-
// /// The string that is printed when the solver has proven that the instance is
40-
// /// unsatisfiable.
41-
// const FZN_UNSATISFIABLE: &str = "=====UNSATISFIABLE=====\n";
42-
4331
/// A configuration for instances that run in a few milliseconds.
4432
const INSTANT_CONFIG: CriterionConfig = CriterionConfig {
4533
sampling_mode: None,
@@ -65,43 +53,6 @@ struct CriterionConfig {
6553
measurement_time: Option<Duration>,
6654
}
6755

68-
#[derive(Debug, Clone, Copy)]
69-
/// Output stream that immediately discards all data.
70-
struct DummyOutput;
71-
72-
#[derive(Debug, Clone, Copy)]
73-
/// What the goal is when running the solver on an instance.
74-
enum InstanceType {
75-
/// An optimal solution should be found.
76-
Optimization,
77-
/// A correct solution should be found.
78-
Satisfaction,
79-
}
80-
81-
/// Run the solver on the given instance and check the output.
82-
fn check_final(name: &str, instance_type: InstanceType) {
83-
let base = PathBuf::from("./corpus/").join(name);
84-
let fzn = base.with_extension("fzn.json");
85-
let out = run_solver(&fzn);
86-
let mut slice: &str = std::str::from_utf8(&out).expect("invalid utf-8");
87-
if let InstanceType::Optimization = instance_type {
88-
assert!(
89-
slice.ends_with(FZN_COMPLETE),
90-
"Solver did not finish with complete marker: ```\n{}\n'''",
91-
slice
92-
);
93-
slice = &slice[..slice.len() - FZN_COMPLETE.len()];
94-
}
95-
assert!(
96-
slice.ends_with(FZN_SEPERATOR),
97-
"Solution did not end with a seperator: ```\n{}\n'''",
98-
slice
99-
);
100-
slice = &slice[..slice.len() - FZN_SEPERATOR.len()];
101-
let sol = base.with_extension("sol").canonicalize().unwrap();
102-
expect_file![sol].assert_eq(slice);
103-
}
104-
10556
/// Benchmarks of optimization problems (finding the optimal solution).
10657
///
10758
/// Note that it is assumed that the solver will always find the same optimal
@@ -124,23 +75,15 @@ fn optimization(c: &mut Criterion) {
12475
for (instance, config) in instances {
12576
config.apply(&mut group);
12677
let _ = group.bench_with_input(BenchmarkId::from_parameter(instance), &instance, |b, s| {
127-
b.iter(|| check_final(s, InstanceType::Optimization));
78+
let base = PathBuf::from("./corpus/").join(s);
79+
let fzn = base.with_extension("fzn.json");
80+
let sol = base.with_extension("sol").canonicalize().unwrap();
81+
b.iter(|| check_final(&fzn, true, expect_file![&sol]));
12882
});
12983
}
13084
group.finish();
13185
}
13286

133-
/// Run the solver on the given instance and return the output as raw bytes.
134-
fn run_solver(fzn: &Path) -> Vec<u8> {
135-
let args = Arguments::from_vec(vec![fzn.into()]);
136-
let cli: Cli<_, _> = args.try_into().unwrap();
137-
let mut out = Vec::new();
138-
let mut cli = cli.with_stdout(&mut out).with_stderr(|| DummyOutput, false);
139-
cli.run()
140-
.expect("unexpected error while running the solver");
141-
out
142-
}
143-
14487
/// Benchmarks of satisfaction problems (finding any correct solution).
14588
///
14689
/// Note that it is assumed that the solver will always find the same solution,
@@ -157,7 +100,10 @@ fn satisfaction(c: &mut Criterion) {
157100
for (instance, config) in instances {
158101
config.apply(&mut group);
159102
let _ = group.bench_with_input(BenchmarkId::from_parameter(instance), &instance, |b, s| {
160-
b.iter(|| check_final(s, InstanceType::Satisfaction));
103+
let base = PathBuf::from("./corpus/").join(s);
104+
let fzn = base.with_extension("fzn.json");
105+
let sol = base.with_extension("sol").canonicalize().unwrap();
106+
b.iter(|| check_final(&fzn, false, expect_file![&sol]));
161107
});
162108
}
163109
group.finish();
@@ -178,15 +124,6 @@ impl CriterionConfig {
178124
}
179125
}
180126

181-
impl Write for DummyOutput {
182-
fn flush(&mut self) -> std::io::Result<()> {
183-
Ok(())
184-
}
185-
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
186-
Ok(buf.len())
187-
}
188-
}
189-
190127
/// Module to capture the generated criterion code (which cannot be documented).
191128
mod criterion_gen {
192129
use codspeed_criterion_compat::criterion_group;

crates/fzn-huub/tests/flatzinc_tests.rs

+17-3
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,6 @@ mod tests {
3232
assert_first_solution!(warm_start_in_seq_search);
3333
assert_first_solution!(warm_start_success);
3434

35-
assert_optimal!(jobshop_la05);
36-
assert_optimal!(jobshop_newspaper);
37-
3835
assert_search_order!(bool_indomain_max);
3936
assert_search_order!(bool_indomain_min);
4037
assert_search_order!(int_indomain_max_1);
@@ -49,4 +46,21 @@ mod tests {
4946
assert_search_order!(int_indomain_min_5);
5047

5148
assert_unsat!(int_lin_eq_prop);
49+
50+
// ../benches/fzn_huub_benchmarks
51+
assert_first_solution!(amaze3_2012_03_19);
52+
assert_first_solution!(steiner_t3_k4_N8);
53+
assert_first_solution!(steiner_t6_k6_N7);
54+
assert_first_solution!(sudoku_p48);
55+
56+
assert_optimal!(jobshop_la01);
57+
assert_optimal!(jobshop_la02);
58+
assert_optimal!(jobshop_la03);
59+
assert_optimal!(jobshop_la04);
60+
assert_optimal!(jobshop_la05);
61+
assert_optimal!(jobshop_newspaper);
62+
assert_optimal!(portal_10_9_10);
63+
assert_optimal!(radiation_i6_9);
64+
assert_optimal!(radiation_i8_9);
65+
assert_optimal!(svrp_s4_v2_c3);
5266
}

0 commit comments

Comments
 (0)