Object-based Discrete-Event Modeling for Rust
Odem-rs is a discrete-event simulation library for Rust that uses async/await to model concurrent agents. It provides a deterministic, extensible framework for building Monte Carlo-style simulation models where agents interact through scheduled jobs.
Key Features
- Process-Based Simulation: Models simulation entities as asynchronous agents with isolated state and internally concurrent jobs.
- Event-Driven Execution: Skips directly between significant events rather than executing at fixed time intervals.
- Deterministic & Portable: Uses deterministic PRNGs and cooperative concurrency for reproducible results.
- Flexible & Extensible: Provides library traits to tailor simulators and data structures for custom needs.
- Safe & Sound: Validated with Miri to detect undefined behavior and enforce stacked borrow rules.
- Integrated: Integrates seamlessly with
tracing,uom,rand, andrayon. - Embedded-friendly: Can be used in bare-metal environments with a reduced feature-set.
Try the interactive simulation dashboard to experiment with example models in your browser.
Getting Started
Installation
Add odem-rs to your Cargo.toml:
[]
= "0.3"
Example: Barbershop Simulation
To get you started quickly, here is an example scenario featuring a simple barbershop model. Customers arrive at random intervals and request service from a single barber. Once a customer arrives, they occupy the barber for a random duration simulating the haircut, then release the barber for the next customer. The simulation will run for 12 hours.
use ;
use pin;
;
async
More examples can be found in the examples directory.
Execution Model
Odem-rs follows a discrete-event execution model, where simulation advances incrementally based on scheduled events. At any given model time, all continuations (representing agents and jobs) that are scheduled for execution are processed instantaneously in terms of model time before the clock is advanced. Thus, the passing of model time is explicit, allowing for deterministic execution. The execution order is determined by:
- Model time: Monotonically increasing time preserves cause-and-effect relationships between processes.
- Rank (between agents): Defines execution priority among different agents.
- Precedence (between jobs): Ensures the correct sequencing of dependent jobs within one agent.
- Insertion Order: Resolves ties between jobs with equal precedence by executing them in the order they were scheduled.
Once all tasks at a given model time have executed, the simulation clock jumps to the next scheduled event. This execution model is managed by an event calendar integrated into the async/await runtime executor, ensuring deterministic ordering while leveraging Rust's native concurrency.
Feature Flags
Odem-rs uses Cargo feature flags to control optional functionality. All flags listed as "default" are enabled when you add odem-rs as a dependency without further configuration. To start from a minimal base, set default-features = false and enable only what you need.
| Feature | Default | Description |
|---|---|---|
std |
yes | Standard library support (implies alloc). |
alloc |
yes | Heap allocation for dynamic data structures. |
tracing |
yes | Structured instrumentation via the tracing crate. |
debug-tracing |
no | Debug-level trace output for internal state machines. |
uom |
yes | Type-safe SI quantities for model time. |
rand_pcg |
yes | PCG-family pseudo-random number generators. |
rand_xoshiro |
no | XoShiRo-family pseudo-random number generators. |
rayon |
yes | Parallel iteration for independent simulation runs. |
libm |
no | Software math functions for no_std environments. |
See the API documentation for detailed descriptions of each feature flag.
Re-exported Crates
Odem-rs re-exports its ecosystem dependencies so you can use version-compatible crates without adding them separately.
| Crate | Version | Feature |
|---|---|---|
rand |
0.10 | always |
intrusive_collections |
0.10 | always |
uom |
0.38 | uom |
tracing |
0.1 | tracing |
rayon |
1 | rayon |
typed_arena |
2 | alloc |
rand_pcg |
0.10 | rand_pcg |
rand_xoshiro |
0.8 | rand_xoshiro |
use rand; // rand 0.10
use uom; // uom 0.38 (requires feature "uom")
use rayon; // rayon 1 (requires feature "rayon")
Contributors & Acknowledgments
Odem-rs is the result of doctoral research and has benefited from contributions by:
- Lukas Markeffsky, with whom I enjoyed in-depth discussions on Rust's type system and whose incredible insight and sharp mind helped a lot to find and resolve soundness issues in addition to improving the ergonomics of the library.
- Paula Wiesner, with whom I performed early prototyping of agent-based approaches and who is still interested in the progress of this project, despite having successfully moved past academia. I appreciate the enthusiasm!
I welcome contributions, feedback, and feature requests! Open an issue or submit a PR.
License
Odem-rs is licensed under MIT. See LICENSE for details.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in odem-rs by you, shall be licensed as MIT, without any additional terms or conditions.