Getting Started
This guide walks you through setting up your first benchmark with Luna Bench, from installation to running a full evaluation pipeline.
Installation
Luna Bench requires Python 3.13 or later.
Note
Luna Bench depends on Luna Model for model handling. It will be installed automatically as a dependency.
Creating a Model Set
A ModelSet is a named collection of optimization models that your benchmark will evaluate. Models are created using the Model class from Luna Quantum.
from luna_quantum import Model, Variable, Vtype, Bounds, Unbounded
from luna_bench import ModelSet
# Build a model: maximize 3x + 2y subject to a couple of constraints
model = Model("problem1")
with model.environment:
x = Variable("x", vtype=Vtype.REAL, bounds=Bounds(lower=0, upper=Unbounded))
y = Variable("y", vtype=Vtype.REAL, bounds=Bounds(lower=0, upper=Unbounded))
model.objective = 3 * x + 2 * y
model.constraints += x + y <= 10
model.constraints += 2 * x + y >= 5
# Create a model set and add the model
model_set = ModelSet.create("my-models")
model_set.add(model)
Persistence
Model sets are automatically persisted in a local SQLite database. You can reload them in any future session using ModelSet.load("my-models") without needing access to the original files.
Setting Up a Benchmark
A Benchmark ties together a model set, one or more algorithms, features, metrics, and plots into a single evaluation pipeline.
Create the benchmark and assign a model set
Add algorithms
Algorithms are the solvers you want to compare. Each algorithm is registered with a unique name. Here we compare two QAOA configurations with different circuit depths (reps controls the number of QAOA layers).
Add features
Features extract properties from each model before the algorithms run. These properties can be used later in plots and analysis.
Add metrics
Metrics evaluate the quality of each algorithm's results.
from luna_bench.metrics import (
Runtime,
ApproximationRatio,
FeasibilityRatio,
BestSolutionFound,
TimeToSolution,
FractionOfOverallBestSolution,
)
bench.add_metric("runtime", Runtime())
bench.add_metric("approx-ratio", ApproximationRatio())
bench.add_metric("feasibility", FeasibilityRatio())
bench.add_metric("best-solution", BestSolutionFound())
bench.add_metric("time-to-solution", TimeToSolution())
bench.add_metric("fraction-best", FractionOfOverallBestSolution())
Running the Pipeline
Luna Bench executes a four-stage pipeline in order:
graph LR
A[Features] --> B[Algorithms]
B --> C[Metrics]
C --> D[Plots]
Run the full pipeline
The simplest way to run a benchmark is to execute all stages at once:
Run individual stages
If you need finer control, you can run each stage independently:
# Stage 1: Extract features from all models
bench.run_features()
# Stage 2: Execute all algorithms on all models
bench.run_algorithms()
# Stage 3: Compute metrics from algorithm results
bench.run_metrics()
# Stage 4: Generate plots
bench.run_plots()
Tip
Running individual stages is useful when you want to add new metrics or plots to an existing benchmark without re-running the algorithms, which is typically the most time-consuming stage.
Loading Previous Results
All benchmark data: configurations, model sets, algorithm results, and metrics: is automatically persisted in SQLite databases. You can reload any previous benchmark or model set by name.
# Load an existing model set
model_set = ModelSet.load("my-models")
# Load an existing benchmark (with all its results)
bench = Benchmark.load("my-benchmark")
# Or open it: load if it exists, otherwise create a fresh one
bench = Benchmark.open("my-benchmark")
This makes it straightforward to:
- Resume an interrupted benchmark run.
- Add new algorithms or metrics to a previously completed benchmark.
- Share benchmark results across team members by distributing the database file.
Complete Example
Here is a full working example that ties everything together:
from luna_quantum import Model, Variable, Vtype, Bounds, Unbounded
from luna_quantum.solve.parameters.algorithms import QAOA
from luna_bench import Benchmark, ModelSet
from luna_bench.features import VarNumberFeature, OptSolFeature
from luna_bench.metrics import Runtime, ApproximationRatio, FeasibilityRatio
from luna_bench.plots import AverageRuntimePlot
# --- Model ---
model = Model("problem1")
with model.environment:
x = Variable("x", vtype=Vtype.REAL, bounds=Bounds(lower=0, upper=Unbounded))
y = Variable("y", vtype=Vtype.REAL, bounds=Bounds(lower=0, upper=Unbounded))
model.objective = 3 * x + 2 * y
model.constraints += x + y <= 10
model.constraints += 2 * x + y >= 5
# --- Model Set ---
model_set = ModelSet.create("getting-started-models")
model_set.add(model)
# --- Benchmark ---
bench = Benchmark.create("getting-started-benchmark")
bench.set_modelset(model_set)
# Algorithms: compare two QAOA configurations with different circuit depths
bench.add_algorithm("qaoa-2", QAOA(reps=2))
bench.add_algorithm("qaoa-4", QAOA(reps=4))
# Features
bench.add_feature("num-vars", VarNumberFeature())
bench.add_feature("optimal-solution", OptSolFeature())
# Metrics
bench.add_metric("runtime", Runtime())
bench.add_metric("approx-ratio", ApproximationRatio())
bench.add_metric("feasibility", FeasibilityRatio())
# Plots
bench.add_plot("avg-runtime", AverageRuntimePlot())
# Run the full pipeline: features -> algorithms -> metrics -> plots
bench.run()
Next Steps
-
Architecture
Understand the layered design and pipeline execution model.
-
Model Sets
Learn how to create, manage, and share model sets.
-
Algorithms
Explore built-in solvers and learn how to register custom algorithms.
-
Metrics
Dive into the available metrics and how to create your own.
-
Features
Extract and use model properties in your analysis.
-
Plots
Visualize benchmark results with built-in and custom plots.