Getting started¶
Installation¶
SimulSI needs Python 3.11 or newer.
python -m venv .venv && source .venv/bin/activate
pip install "simulsi[viz]" # core + matplotlib, from PyPI
| Extra | Adds |
|---|---|
| (none) | engine, experiments, statistics, CLI (NumPy, SciPy, pydantic, PyYAML) |
viz |
matplotlib plots |
plotly |
interactive Plotly figures |
pandas |
ExperimentResult.to_dataframe() |
parquet |
Parquet export (pandas + pyarrow) |
all |
all of the above |
dev |
test, lint and type-check tooling |
Docker¶
The image contains the CLI and the dashboard:
docker run --rm -p 127.0.0.1:8642:8642 ghcr.io/yashjindal11/simulsi
docker run --rm -v "$PWD:/work" ghcr.io/yashjindal11/simulsi run model.py -p servers=3
docker run --rm -p 127.0.0.1:8642:8642 -v "$PWD:/work" ghcr.io/yashjindal11/simulsi \
ui results/ --model model.py --host 0.0.0.0 --port 8642 --no-browser
The dashboard has no authentication, so publish the port on 127.0.0.1
only, and keep the host and container port numbers the same (the server
rejects requests whose Host header names another port). Build the image
yourself with docker build -t simulsi ..
Check the install¶
simulsi --version
simulsi run builtin:mmc --duration 1000
Your first simulation¶
A simulation has a clock, an event queue and components. Processes are
Python generators: each yield waits for something - a duration, a resource,
an item in a queue - and the engine resumes the generator when it is ready.
from simulsi import Simulation
sim = Simulation(seed=42)
server = sim.resource("server", capacity=1)
def customer(sim, name, arrive, service):
yield arrive # hold until the arrival time
req = yield sim.request(server) # wait for the server
print(f"{sim.now:5.1f} {name} starts after waiting {req.waiting_time:.1f}")
yield service # being served
sim.release(req)
for i, (arrive, service) in enumerate([(0, 4), (1, 3), (2, 2)]):
sim.process(customer(sim, f"c{i}", arrive, service))
result = sim.run(until=20)
print(result.metrics["resource.server.utilization"]) # 9 busy time units / 20 = 0.45
result.metrics is a flat dictionary of everything SimulSI measured
automatically (utilization, waiting times, queue lengths, throughput, ...)
plus anything you recorded yourself.
Randomness, the reproducible way¶
Never use random or numpy.random globals in a model. Ask the simulation
for a named stream; it is derived from the seed and the name only.
from simulsi import Simulation
from simulsi.randomness import Exponential
sim = Simulation(seed=7)
arrivals = sim.stream("arrivals")
gap = Exponential(rate=0.5)
print([round(gap.sample(arrivals), 3) for _ in range(3)]) # same numbers every run
Your first model and experiment¶
Wrap the setup in a model - a build function plus parameters and a run length - so it can be replicated, compared and analysed:
from simulsi import Experiment, Parameter, Scenario, Simulation, model
from simulsi.randomness import Exponential
@model(
duration=1000.0,
warmup=100.0,
parameters=[
Parameter("arrival_rate", 0.8, "float", low=0.0),
Parameter("servers", 1, "int", low=1),
],
)
def clinic(sim: Simulation, p):
desk = sim.resource("desk", capacity=p.servers)
arrivals, service = sim.stream("arrivals"), sim.stream("service")
def patient(sim):
yield from sim.use(desk, Exponential(mean=1.0).sample(service))
def source(sim):
while True:
yield Exponential(rate=p.arrival_rate).sample(arrivals)
sim.process(patient(sim))
sim.process(source(sim))
experiment = Experiment(
clinic,
[Scenario("baseline"), Scenario("two_desks", {"servers": 2})],
replications=10,
seed=1,
)
result = experiment.run()
print(result.format_summary(["resource.desk.wait.mean", "resource.desk.utilization"]))
print(result.compare("baseline", metrics=["resource.desk.wait.mean"]).format())
Each replication gets an independent seed derived from the experiment seed;
both scenarios use the same replication seeds, so the comparison is paired.
Save everything (results + provenance) with result.save("results/clinic").
From the command line¶
simulsi init my-study && cd my-study
simulsi validate experiment.yaml
simulsi experiment experiment.yaml
simulsi analyze results/service-desk --precision 0.05
simulsi visualize results/service-desk --out plots
Next: Core concepts and Experiments and analysis.