Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
20 changes: 11 additions & 9 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -174,15 +174,17 @@ Common data processing libraries natively support this format, e.g., [Polars](ht

By default, we record the following columns:

| Name | Description |
|--------------|----------------------------------------------------------------------------------|
| `s_key` | Unique key within a run. If the instance logs are kept, the folder has this name |
| `s_name` | Name of the instance as indicated by the `#s name` line |
| `s_instance` | Path to instance file |
| `s_idigest` | Hash value if instance is registered in the global stride database |
| `s_solution` | Path to solution file (stdout) |
| `s_score` | If `s_result` indicates a valid solution, report the number of tree in the MAF. |
| ... | [Profiling](#profiling) related columns |
| Name | Description |
|--------------|------------------------------------------------------------------------------------------------------------------|
| `s_key` | Unique key within a run. If the instance logs are kept, the folder has this name |
| `s_name` | Name of the instance as indicated by the `#s name` line |
| `s_instance` | Path to instance file |
| `s_idigest` | Hash value if instance is registered in the STRIDE database |
| `s_solution` | Path to solution file (stdout) |
| `s_score` | If `s_result` indicates a valid solution, report the number of tree in the MAF. |
| `s_prev_best` | Best known score according to STRIDE server without accounting for this run |
| `s_heuristic_score` | Scoring function of PACE26 Heuristic Track (using min(`s_score`, `s_prev_score`) as best known solution |
| ... | [Profiling](#profiling) related columns |

The column `s_result` can take the following values:
- `Valid`: the return solution is a feasible agreement forest (size is ignored)
Expand Down
21 changes: 20 additions & 1 deletion src/commands/run/command.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ use std::{fs::File, sync::Arc};
use thiserror::Error;
use tracing::{error, trace};

use crate::commands::run::pace::compute_pace_heuristic_score;
use crate::commands::run::upload::{JobResultUploadAggregation, UploadError, UploadToStride};
use crate::instances::instance::{InstanceError, collect_instances, sort_instances};
use crate::instances::parser::InstanceSourceParser;
Expand Down Expand Up @@ -277,9 +278,27 @@ async fn task_main(
None
};

let pace_heuristic_score = if let Some(best_known) = best_known
&& let Some(solver_score) = score
&& let Some(num_leaves) = instance.num_leaves()
{
let heuristic_score =
compute_pace_heuristic_score(solver_score as usize, best_known as usize, num_leaves);
context.display.stride_add_heuristic_score(heuristic_score);
Some(heuristic_score)
} else {
None
};

if let Err(e) = context
.summary_writer
.add_entry(&instance, job_result, opt_info, best_known)
.add_entry(
&instance,
job_result,
opt_info,
best_known,
pace_heuristic_score,
)
.await
{
error!("SummaryWriter error: {e:?}");
Expand Down
24 changes: 21 additions & 3 deletions src/commands/run/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ use indicatif::{MultiProgress, ProgressBar, ProgressStyle};
use std::sync::atomic::{AtomicU64, Ordering};
use std::time::Duration;
use tokio::time::Instant;
const HEURISTIC_SCORE_SCALER: f64 = (1u64 << 32) as f64;

pub struct ProgressDisplay {
mpb: MultiProgress,
status_line: ProgressBar,
Expand All @@ -20,6 +22,10 @@ pub struct ProgressDisplay {
num_solvererror: AtomicU64,
num_timeout: AtomicU64,

// heuristic score is actually a f64 (values between 0..1); since there are no atomic floats
// we use fixed precision by with a scaler of HEURISTIC_SCORE_SCALER
sum_heuristic_score: AtomicU64,

num_stride_instances: AtomicU64,
num_stride_queued: AtomicU64,
num_stride_best_known: AtomicU64,
Expand Down Expand Up @@ -60,6 +66,7 @@ impl ProgressDisplay {
num_solvererror: Default::default(),
num_timeout: Default::default(),
num_emptysolution: Default::default(),
sum_heuristic_score: Default::default(),

num_stride_instances: Default::default(),
num_stride_queued: Default::default(),
Expand Down Expand Up @@ -131,7 +138,7 @@ impl ProgressDisplay {
format_num!(num_timeout, "Timeout", yellow),
format_num!(num_syntaxerror, "SyntErr", red),
format_num!(num_solvererror, "SolvErr ", red),
format_num!(num_systemerror, "SysErr", red),
format_num!(num_systemerror, "SystemErr ", red),
format!("Running: {running}"),
];

Expand All @@ -147,8 +154,13 @@ impl ProgressDisplay {
format_num!(num_stride_best_known, "Best ", green),
format_num!(num_stride_new_best_known, "New Best", yellow),
format_num!(num_stride_suboptimal, "Subopt", red, CRITICAL),
format_num!(num_stride_no_response, "No Resp", yellow),
format_num!(num_stride_queued, "Transmit Queue ", green),
format!(
"Heuristic Score: {:>10.5}",
self.sum_heuristic_score.load(Ordering::Acquire) as f64
/ HEURISTIC_SCORE_SCALER
),
format_num!(num_stride_queued, "Transmit Queue", green),
format_num!(num_stride_no_response, "NoResponse", yellow),
format_num!(num_stride_instances, "STRIDE Instances", white),
];

Expand Down Expand Up @@ -229,6 +241,12 @@ impl ProgressDisplay {
self.num_stride_queued.fetch_sub(1, Ordering::AcqRel);
self.num_stride_suboptimal.fetch_add(1, Ordering::AcqRel);
}

pub fn stride_add_heuristic_score(&self, score: f64) {
let score_int = (score.clamp(0.0, 1.0) * HEURISTIC_SCORE_SCALER) as u64;
self.sum_heuristic_score
.fetch_add(score_int, Ordering::AcqRel);
}
}

pub struct JobProgressBar {
Expand Down
1 change: 1 addition & 0 deletions src/commands/run/mod.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
pub mod command;
pub mod display;
pub use command::*;
mod pace;
pub mod summary_writer;
pub mod upload;
26 changes: 26 additions & 0 deletions src/commands/run/pace.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
pub fn compute_pace_heuristic_score(
solver_score: usize,
best_known: usize,
num_leaves: usize,
) -> f64 {
let best_known = best_known.min(solver_score);
let upper = num_leaves.min(2 * best_known);

((upper - solver_score) as f64 / (upper - best_known) as f64)
.max(0.0)
.powi(2)
}

#[cfg(test)]
mod test {
use crate::commands::run::pace::compute_pace_heuristic_score;

#[test]
fn heuristic_score() {
assert_eq!(compute_pace_heuristic_score(2, 2, 5), 1.0);
assert_eq!(compute_pace_heuristic_score(2, 3, 5), 1.0);
assert_eq!(compute_pace_heuristic_score(5, 3, 5), 0.0);
assert_eq!(compute_pace_heuristic_score(4, 2, 5), 0.0);
assert!((0.1..0.9).contains(&compute_pace_heuristic_score(3, 2, 5)));
}
}
11 changes: 9 additions & 2 deletions src/commands/run/summary_writer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ const JSON_KEY_INSTANCE_HASH: &str = "s_idigest";
const JSON_KEY_JOB_RESULT: &str = "s_result";
const JSON_KEY_SOLUTION_SIZE: &str = "s_score";

const JSON_KEY_PACE_HEURISTIC_SCORE: &str = "s_heuristic_score";

const JSON_KEY_PREV_BEST_KNOWN: &str = "s_prev_best";

/// Maintains a machine-readable log file where each line corresponds to an completed task in JSON format
Expand All @@ -35,6 +37,7 @@ impl SummaryWriter {
job_result: JobResult,
opt_infos: Option<SolutionInfos>,
prev_best_known: Option<u32>,
pace_heuristic_score: Option<f64>,
) -> Result<(), SummaryWriterError> {
let mut row = Map::with_capacity(10);

Expand All @@ -55,9 +58,13 @@ impl SummaryWriter {
row.insert(JSON_KEY_INSTANCE_NAME.into(), Value::String(name.clone()));
}
if let Some(prev_best) = prev_best_known {
row.insert(JSON_KEY_PREV_BEST_KNOWN.into(), prev_best.into());
}

if let Some(pace_heuristic_score) = pace_heuristic_score {
row.insert(
JSON_KEY_PREV_BEST_KNOWN.into(),
Value::Number(prev_best.into()),
JSON_KEY_PACE_HEURISTIC_SCORE.into(),
pace_heuristic_score.into(),
);
}

Expand Down
Loading