Expand description
Tantale core contains the foundational abstractions and building blocks used throughout the library. It defines the modeling layer (domains, variables, search spaces, solutions), the optimization layer (objectives, optimizers, stop criteria), and the execution layer (experiments, recorders, checkpointing).
§Main building blocks
- Modeling:
Domain,Var,Searchspace,Solution - Objective:
Objective,Outcome,Stepped - Optimization:
Optimizer,BatchOptimizer,SingleOptimizer - Execution:
Runable,Recorder,Checkpointer,Stop
Most of these items are re-exported at the crate root for convenience.
§Module map
domain: Domain definitions and codomains (objective outputs).sampler: Sampling utilities and distributions.variable:Varto relate objective and optimizer domains.searchspace: Composition of variables into aSearchspace.solution: Solution shapes, identifiers, solution metadata, and computed wrappers.objective: Objective functions, steps, and outcomes.optimizer: Optimizer traits and state metadata.stop: Stop criteria and lifecycle signals.experiment: Execution pipelines and orchestration.recorder: Recording utilities (e.g., CSV).checkpointer: Checkpointing primitives.
§Execution contexts
Tantale provides multiple execution contexts through Runable:
MonoExperimentfor single-threaded runs.ThrExperimentfor multi-threaded runs.- [
MPIExperiment] for distributed runs (requires thempifeature).
§Feature flags
mpi: Enables MPI-based distributed execution and related utilities.
§Dependencies and integration
Tantale core relies on a few external crates:
serde: Most core types implementSerializeandDeserializeto support checkpointing.rand: Domains and samplers use RNG traits to generate valid values.mpi(optional): Distributed experiments are enabled behind thempifeature flag and expose MPI-specific execution helpers.rayon: Parallel evaluation and orchestration in multi-threaded runs. Used in synchrnous batched optimization, andSpParutilities.csv: CSV-backedRecorder, withCSVRecorderas the main implementation.rmp-serde: MessagePack serialization used by the default checkpointer. Used byMessagePackfor compact checkpointing of experiment state.bincode: Compact binary serialization for checkpointing and transport. Used by MPI-distributed optimization to create messages fromUncomputedandOutcome.bitvec: Efficient bit-level storage in domain and solution utilities. Used by MPI-distributed optimization withinIdleWorkerto track idle workers.num_cpus: Detects available CPU cores to size thread pools. Used in multi-threaded execution contexts, for asynchrnous multi-threaded optimization, to determine pool size of threads.indexmap: Provides a hashmap preserving iteration order. It used to managa function states, for FIFO discarding of old states to save memory.
§Examples
§Define a searchspace with objective!
The objective! macro builds a Searchspace and wraps a user-defined
function into an Objective. The example below mirrors the evaluator
pattern used in the test suite.
The objective macro and the function must be defined within another module than the main function, to avoid issues with the generated code.
The macro generates a searchspace based on the variables defined in the function body, and an objective that wraps the user function.
The searchspace and objective can then be created via generated function: my_module::get_searchspace() and my_module::get_function().
use tantale::core::{Bool, Cat, Int, Nat, Real, Bernoulli, Uniform};
use tantale::macros::{objective, Outcome, CSVWritable};
use serde::{Serialize, Deserialize};
#[derive(Outcome, CSVWritable, Debug, Serialize, Deserialize)]
struct OutExample {
#[maximize]
obj: f64,
info: f64,
}
objective!(
pub fn example() -> OutExample {
let _a = [! a | Int(0,100, Uniform) | !];
let _b = [! b | Nat(0,100, Uniform) | !];
let _c = [! c | Cat(["relu", "tanh", "sigmoid"], Uniform) | !];
let _d = [! d | Bool(Bernoulli(0.5)) | !];
let e = [! e | Real(1000.0,2000.0, Uniform) | !];
// ... more variables and computation ...
OutExample{
obj: e,
info: [! f | Real(10.0,20.0, Uniform) | !],
}
}
);
// The macro expands to helpers like:
// let sp = example::get_searchspace();
// let obj = example::get_function();§Define a searchspace with objective! for Stepped function
Stepped functions is similar to Objective except that the user-defined function
can be evaluated by Step. Hence, the function must maintain an internal state that is updated at each step.
To trigger the wrapping within a Stepped objective, the user must defined an Outcome containing a Step.
First, the user defines the function state by implementing the FuncState trait,
which requires implementing the save and load methods for checkpointing.
Then, the user defines an outcome struct that contains a field of type Step.
Finally, the user can use the objective! macro to define the function, and manage the internal state and evaluation step within the function body.
use tantale::core::{FuncState, Bool, Cat, Int, Nat, Real, Bernoulli, Uniform, Step};
use tantale::macros::{objective, Outcome, CSVWritable};
use serde::{Serialize, Deserialize};
#[derive(Outcome, CSVWritable, Debug, Serialize, Deserialize)]
struct OutExample {
#[maximize]
obj: f64,
info: f64,
#[step]
step: Step,
}
#[derive(Serialize, Deserialize)]
pub struct FnState {
pub something: isize,
}
// The user must implement the saving and loading logic of the function state,
// to enable checkpointing of the internal state of the function.
// The input is a folder path where the checkpoint is stored, and the user can decide how to serialize the state (e.g., using rmp_serde or bincode).
impl FuncState for FnState {
fn save(&self, path: std::path::PathBuf) -> std::io::Result<()>{
let mut file = std::fs::File::create(path.join("fn_state.mp"))?;
rmp_serde::encode::write(&mut file, &self).unwrap();
Ok(())
}
fn load(path: std::path::PathBuf) -> std::io::Result<Self> {
let file_path = path.join("fn_state.mp");
let file = std::fs::File::open(file_path)?;
let state = rmp_serde::decode::from_read(file).unwrap();
Ok(state)
}
}
objective!(
pub fn example() -> (OutExample, FnState) {
let _a = [! a | Int(0,100, Uniform) | !];
let _b = [! b | Nat(0,100, Uniform) | !];
let _c = [! c | Cat(["relu", "tanh", "sigmoid"], Uniform) | !];
let _d = [! d | Bool(Bernoulli(0.5)) | !];
let e = [! e | Real(1000.0,2000.0, Uniform) | !];
// ... more variables and computation ...
// Manage the internal state
let mut state = if let Some(s) = [! STATE !] {
s
} else {
FnState { something: 0 }
};
state.something += 1;
let evalstep = if state.something == 5 {Step::Evaluated} else{Step::Partially(state.something)};
(
OutExample{
obj: e,
info: [! f | Real(10.0,20.0, Uniform) | !],
step: evalstep,
},
state
)
}
);§Batch run with checkpointing (mono)
use tantale::core::{
CSVRecorder, FolderConfig, MessagePack, Objective, SingleCodomain,
experiment::{Runable, mono}, stop::Calls,
};
use tantale::algos::BatchRandomSearch;
let sp = my_module::get_searchspace();
let obj = my_module::get_function();
let opt = BatchRandomSearch::new(7);
let stop = Calls::new(50);
let config = FolderConfig::new("run_batch").init();
let rec = CSVRecorder::new(config.clone(), true, true, true, true);
let check = MessagePack::new(config);
let exp = mono(sp, obj, opt, stop, (rec, check));
exp.run();§Sequential run with threaded execution
use tantale::core::{
CSVRecorder, FolderConfig, MessagePack, Objective,
experiment::{Runable, threaded}, stop::Calls,
};
use tantale::algos::RandomSearch;
let sp = my_module::get_searchspace();
let obj = my_module::get_function();
let opt = RandomSearch::new();
let stop = Calls::new(50);
let config = FolderConfig::new("run_seq_threads").init();
let rec = CSVRecorder::new(config.clone(), true, true, true, true);
let check = MessagePack::new(config);
let exp = threaded(sp, obj, opt, stop, (rec, check));
exp.run();§Multi-fidelity batch run
use tantale::core::{
CSVRecorder, FolderConfig, MessagePack, experiment::{Runable, mono}, stop::Calls,
};
use tantale::algos::{random_searcatchRandomSearch;
let sp = my_module::get_searchspace();
let obj = my_module::get_function();
let opt = BatchRandomSearch::new(7);
let stop = Calls::new(50);
let config = FolderConfig::new("run_fidelity").init();
let rec = CSVRecorder::new(config.clone(), true, true, true, true);
let check = MessagePack::new(config);
let exp = mono(sp, obj, opt, stop, (rec, check));
exp.run();Re-exports§
pub use config::FolderConfig;pub use config::SaverConfig;pub use domain::Accumulator;pub use domain::BestAccumulator;pub use domain::Bool;pub use domain::Bounded;pub use domain::Cat;pub use domain::Codomain;pub use domain::ConstCodomain;pub use domain::ConstMultiCodomain;pub use domain::Constrained;pub use domain::Cost;pub use domain::CostCodomain;pub use domain::CostConstCodomain;pub use domain::CostConstMultiCodomain;pub use domain::CostMultiCodomain;pub use domain::Criteria;pub use domain::Domain;pub use domain::Dominate;pub use domain::FidCriteria;pub use domain::Grid;pub use domain::GridDom;pub use domain::GridInt;pub use domain::GridNat;pub use domain::GridReal;pub use domain::Int;pub use domain::LinkObj;pub use domain::LinkOpt;pub use domain::LinkTyObj;pub use domain::LinkTyOpt;pub use domain::Linked;pub use domain::Mixed;pub use domain::MixedTypeDom;pub use domain::Multi;pub use domain::MultiCodomain;pub use domain::Nat;pub use domain::NoDomain;pub use domain::Onto;pub use domain::OntoDom;pub use domain::ParetoAccumulator;pub use domain::Real;pub use domain::Single;pub use domain::SingleCodomain;pub use domain::TypeAcc;pub use domain::TypeCodom;pub use domain::Unit;pub use sampler::Bernoulli;pub use sampler::BoolDistribution;pub use sampler::BoundedDistribution;pub use sampler::DomainSampler;pub use sampler::GridDomDistribution;pub use sampler::Uniform;pub use variable::var::Var;pub use solution::BaseSol;pub use solution::Batch;pub use solution::Computed;pub use solution::Fidelity;pub use solution::FidelitySol;pub use solution::Id;pub use solution::IntoComputed;pub use solution::IntoComputedShape;pub use solution::Lone;pub use solution::OutBatch;pub use solution::Pair;pub use solution::ParSId;pub use solution::SId;pub use solution::SolInfo;pub use solution::Solution;pub use solution::SolutionShape;pub use solution::StepId;pub use solution::StepSId;pub use solution::Uncomputed;pub use solution::Xy;pub use solution::shape::RawObj;pub use searchspace::CompShape;pub use searchspace::OptionCompShape;pub use searchspace::Searchspace;pub use searchspace::Sp;pub use searchspace::SpPar;pub use crate::objective::EvalStep;pub use crate::objective::FidOutcome;pub use crate::objective::FuncWrapper;pub use crate::objective::Objective;pub use crate::objective::Outcome;pub use crate::objective::Step;pub use crate::objective::Stepped;pub use crate::objective::outcome::FuncState;pub use crate::optimizer::BatchOptimizer;pub use crate::optimizer::BatchSampler;pub use crate::optimizer::EmptyInfo;pub use crate::optimizer::OptInfo;pub use crate::optimizer::OptState;pub use crate::optimizer::Optimizer;pub use crate::optimizer::Sampler;pub use crate::optimizer::SingleOptimizer;pub use crate::optimizer::SingleSampler;pub use crate::optimizer::opt::CompBatch;pub use stop::Calls;pub use stop::Evaluated;pub use stop::Stop;pub use experiment::CompAcc;pub use experiment::MonoExperiment;pub use experiment::Pool;pub use experiment::PoolMode;pub use experiment::Runable;pub use experiment::ThrExperiment;pub use experiment::mono;pub use experiment::mono_with_pool;pub use experiment::threaded;pub use experiment::threaded_with_pool;pub use recorder::BatchRecorder;pub use recorder::CSVRecorder;pub use recorder::CSVWritable;pub use recorder::NoSaver;pub use recorder::Recorder;pub use recorder::SeqRecorder;pub use checkpointer::Checkpointer;pub use checkpointer::MessagePack;pub use checkpointer::MonoCheckpointer;pub use checkpointer::ThrCheckpointer;pub use has_trait::HasFidelity;pub use has_trait::HasId;pub use has_trait::HasInfo;pub use has_trait::HasSolInfo;pub use has_trait::HasStep;pub use has_trait::HasStepId;pub use has_trait::HasUncomputed;pub use has_trait::HasVariables;pub use has_trait::HasX;pub use has_trait::HasY;
Modules§
- checkpointer
- Checkpointing
- config
- Saver Configuration
- domain
- Domain
- errors
- experiment
- Experiment orchestration and optimization loops.
- has_
trait - objective
- Objective Functions and Evaluation State
- optimizer
- Optimizers
- recorder
- Recorder
- sampler
- Domain Samplers
- searchspace
- Searchspace
- solution
- Solution
- stop
- Stop criteria for an experiment.
- variable
- A
Varties together two relatedDomaintypes.
Macros§
- load
- Macro for loading experiments from checkpoints with simplified syntax.
Structs§
- Global
Parameters - Serializable snapshot of global counters for checkpointing.