Skip to content

Commit

Permalink
Reorganize the order of items in the Rust code for consistency
Browse files Browse the repository at this point in the history
  • Loading branch information
Dekker1 committed Nov 25, 2024
1 parent 93fc486 commit d7657cb
Show file tree
Hide file tree
Showing 39 changed files with 4,269 additions and 4,297 deletions.
101 changes: 53 additions & 48 deletions crates/fzn-huub/benches/fzn_huub_benchmarks.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
#![expect(
unused_crate_dependencies,
reason = "only dependencies for benchmarking are used in this file"
)]

//! A Benchmarking framework for the full fzn-huub solver.
//!
//! Note that these benchmarks run through the full solver, providing the
//! instances as file input, and reading the output from its output stream. The
//! total time taken is repeatedly measured.
#![expect(
unused_crate_dependencies,
reason = "only dependencies for benchmarking are used in this file"
)]
use std::{
io::Write,
path::{Path, PathBuf},
Expand All @@ -21,44 +22,48 @@ use expect_test::expect_file;
use fzn_huub::Cli;
use pico_args::Arguments;

/// A configuration for instances that run for a few seconds.
const FEW_SECONDS_CONFIG: CriterionConfig = CriterionConfig {
sampling_mode: Some(SamplingMode::Flat),
sample_size: Some(10),
measurement_time: Some(Duration::from_secs(60)),
};

/// The string that is printed when the solver has proven that no more/better
/// solutions exist.
const FZN_COMPLETE: &str = "==========\n";

/// The string that is printed after every solution.
const FZN_SEPERATOR: &str = "----------\n";

/// The string that is printed when the solver has proven that the instance is
/// unsatisfiable.
// const FZN_UNSATISFIABLE: &str = "=====UNSATISFIABLE=====\n";

#[derive(Debug, Clone)]
/// Configuration of criterion for a specific benchmark.
struct CriterionConfig {
/// The [`SamplingMode`] to use, or none to use the default.
sampling_mode: Option<SamplingMode>,
/// The number of samples to take, or none to use the default.
sample_size: Option<usize>,
/// The time to measure for, or none to use the default.
measurement_time: Option<Duration>,
}

/// A configuration for instances that run in a few milliseconds.
const INSTANT_CONFIG: CriterionConfig = CriterionConfig {
sampling_mode: None,
sample_size: Some(60),
measurement_time: None,
};

/// A configuration for instances that run in less than a second.
const MILLISECONDS_CONFIG: CriterionConfig = CriterionConfig {
sampling_mode: Some(SamplingMode::Flat),
sample_size: Some(20),
measurement_time: Some(Duration::from_secs(20)),
};
/// A configuration for instances that run for a few seconds.
const FEW_SECONDS_CONFIG: CriterionConfig = CriterionConfig {
sampling_mode: Some(SamplingMode::Flat),
sample_size: Some(10),
measurement_time: Some(Duration::from_secs(60)),
};

#[derive(Debug, Clone)]
/// Configuration of criterion for a specific benchmark.
struct CriterionConfig {
/// The [`SamplingMode`] to use, or none to use the default.
sampling_mode: Option<SamplingMode>,
/// The number of samples to take, or none to use the default.
sample_size: Option<usize>,
/// The time to measure for, or none to use the default.
measurement_time: Option<Duration>,
}

#[derive(Debug, Clone, Copy)]
/// Output stream that immediately discards all data.
Expand All @@ -73,17 +78,6 @@ enum InstanceType {
Satisfaction,
}

/// Run the solver on the given instance and return the output as raw bytes.
fn run_solver(fzn: &Path) -> Vec<u8> {
let args = Arguments::from_vec(vec![fzn.into()]);
let cli: Cli<_, _> = args.try_into().unwrap();
let mut out = Vec::new();
let mut cli = cli.with_stdout(&mut out).with_stderr(|| DummyOutput, false);
cli.run()
.expect("unexpected error while running the solver");
out
}

/// Run the solver on the given instance and check the output.
fn check_final(name: &str, instance_type: InstanceType) {
let base = PathBuf::from("./corpus/").join(name);
Expand All @@ -109,6 +103,19 @@ fn check_final(name: &str, instance_type: InstanceType) {
}
}

/// Main function that runs the specified benchmarks (in [`optimization`] and
/// [`satisfaction`]) using the criterion library.
///
/// This is the manually expanded version of the `criterion_group!(benches,
/// optimization, satisfaction);` and `criterion_main!(benches);` macros.
fn main() {
let mut criterion: Criterion<_> = Criterion::default().configure_from_args();
optimization(&mut criterion);
satisfaction(&mut criterion);

Criterion::default().configure_from_args().final_summary();
}

/// Benchmarks of optimization problems (finding the optimal solution).
///
/// Note that it is assumed that the solver will always find the same optimal
Expand Down Expand Up @@ -136,6 +143,17 @@ fn optimization(c: &mut Criterion) {
group.finish();
}

/// Run the solver on the given instance and return the output as raw bytes.
fn run_solver(fzn: &Path) -> Vec<u8> {
let args = Arguments::from_vec(vec![fzn.into()]);
let cli: Cli<_, _> = args.try_into().unwrap();
let mut out = Vec::new();
let mut cli = cli.with_stdout(&mut out).with_stderr(|| DummyOutput, false);
cli.run()
.expect("unexpected error while running the solver");
out
}

/// Benchmarks of satisfaction problems (finding any correct solution).
///
/// Note that it is assumed that the solver will always find the same solution,
Expand All @@ -158,19 +176,6 @@ fn satisfaction(c: &mut Criterion) {
group.finish();
}

/// Main function that runs the specified benchmarks (in [`optimization`] and
/// [`satisfaction`]) using the criterion library.
///
/// This is the manually expanded version of the `criterion_group!(benches,
/// optimization, satisfaction);` and `criterion_main!(benches);` macros.
fn main() {
let mut criterion: Criterion<_> = Criterion::default().configure_from_args();
optimization(&mut criterion);
satisfaction(&mut criterion);

Criterion::default().configure_from_args().final_summary();
}

impl CriterionConfig {
/// Apply the configuration to the given [`BenchmarkGroup`].
fn apply<M: Measurement>(&self, group: &mut BenchmarkGroup<'_, M>) {
Expand All @@ -187,10 +192,10 @@ impl CriterionConfig {
}

impl Write for DummyOutput {
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
Ok(buf.len())
}
fn flush(&mut self) -> std::io::Result<()> {
Ok(())
}
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
Ok(buf.len())
}
}
44 changes: 23 additions & 21 deletions crates/fzn-huub/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,26 @@
//! FlatZinc command line interface for the Huub solver.
/// Write a message to an output stream, similar to `print!`.
///
/// Note that this differs from `write!` in that it will panic if writing to the
/// stream fails.
macro_rules! output {
($($arg:tt)*) => {
write!($($arg)*).expect("unable to write to output stream")
};
}

/// Write a message to an output stream with an added newline, similar to
/// `println!`.
///
/// Note that this differs from `write!` in that it will panic if writing to the
/// stream fails.
macro_rules! outputln {
($($arg:tt)*) => {
writeln!($($arg)*).expect("unable to write to output stream")
};
}

mod trace;

use std::{
Expand Down Expand Up @@ -38,27 +60,6 @@ const FZN_UNKNOWN: &str = "=====UNKNOWN=====";
/// Status message to output when a problem is proven to be unsatisfiable.
const FZN_UNSATISFIABLE: &str = "=====UNSATISFIABLE=====";

/// Write a message to an output stream, similar to `print!`.
///
/// Note that this differs from `write!` in that it will panic if writing to the
/// stream fails.
macro_rules! output {
($($arg:tt)*) => {
write!($($arg)*).expect("unable to write to output stream")
};
}

/// Write a message to an output stream with an added newline, similar to
/// `println!`.
///
/// Note that this differs from `write!` in that it will panic if writing to the
/// stream fails.
macro_rules! outputln {
($($arg:tt)*) => {
writeln!($($arg)*).expect("unable to write to output stream")
};
}

/// FlatZinc command line interface for the Huub solver
///
/// This interface is intended to connect Huub with MiniZinc
Expand Down Expand Up @@ -554,6 +555,7 @@ where

impl TryFrom<Arguments> for Cli<io::Stdout, fn() -> io::Stderr> {
type Error = String;

fn try_from(mut args: Arguments) -> Result<Self, Self::Error> {
let mut verbose = 0;
while args.contains(["-v", "--verbose"]) {
Expand Down
Loading

0 comments on commit d7657cb

Please sign in to comment.