Execution#

Selects how Project::evaluate_with runs the candidates: one after another on the calling thread, or on parallel worker threads. The variant changes only how the work is spread. Results are identical either way, in input order. The default is Execution::Sequential, which is what Project::evaluate uses.

Declaration#

#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub enum Execution {
    #[default]
    Sequential,
    Parallel {
        threads: Option<std::num::NonZeroUsize>,
    },
}

Variants#

Variant Description
Sequential Default. Scores the candidates one by one on the calling thread.
Parallel { threads } Scores the candidates on scoped worker threads. threads: Some(n) sets the number of workers; None uses std::thread::available_parallelism(). Each worker holds one candidate copy at a time.
Note

Execution compiles on every target. For the targets evaluate_with is available on, see Project::evaluate_with.

Example#

use std::num::NonZeroUsize;
use plen_core::{
    Candidate, DateTime, EvaluateOptions, Execution, Patch, Project, ProjectData,
    ProjectOptions, SchedulingChanges, SolveOptions, TaskData, TaskUpdate,
};

fn main() -> Result<(), Box<dyn std::error::Error>> {
    let monday = DateTime::from_ymd_hm(2026, 8, 10, 8, 0).ok_or("invalid date")?;
    let mut task = TaskData::new(1);
    task.start_date = Some(monday);
    task.duration = Some(2.0);
    let data = ProjectData {
        tasks: vec![task],
        ..Default::default()
    };

    let mut project = Project::new(ProjectOptions::default());
    project.solve(Some(data), &SolveOptions::default())?;

    let candidates: Vec<Candidate> = [3.0, 4.0]
        .into_iter()
        .enumerate()
        .map(|(i, duration)| {
            let mut update = TaskUpdate::new(1);
            update.duration = Patch::Value(duration);
            let mut changes = SchedulingChanges::default();
            changes.tasks.update.push(update);
            Candidate { id: (i as i32).into(), changes }
        })
        .collect();

    let execution = Execution::Parallel {
        threads: NonZeroUsize::new(2),
    };
    let result = project.evaluate_with(&candidates, &EvaluateOptions::default(), execution)?;

    for candidate in &result.candidates {
        println!("candidate {}: cost {:?}", candidate.id, candidate.cost);
    }
    Ok(())
}