API reference¶
This page summarizes the public qbalance Python API and the lower-level modules most users extend or call directly.
Package root: qbalance¶
The package root exports the primary workflow and dataset APIs:
Symbol |
Description |
|---|---|
|
Dataset container with root path and records. |
|
Load a dataset directory containing |
|
Persist circuits and metadata as a qbalance dataset. |
|
Load built-in datasets such as |
|
Fluent workflow entry point. |
|
Result object returned by |
|
Reconstruct a saved balanced workload directory produced by |
|
Runtime selection object containing a |
|
Immutable strategy model. |
|
Load, validate, normalize, and de-duplicate strategy specs from JSON. |
|
Validate, normalize, and de-duplicate in-memory strategies. |
Example:
from qbalance import StrategySpec, Workload, load_balanced_workload, load_data
balanced = (
Workload.from_dataset(load_data("tiny"))
.set_target("fake:generic:5")
.adjust(strategies=[StrategySpec(optimization_level=1, routing_method="sabre")])
)
balanced.save("./balanced", overwrite=True)
reloaded = load_balanced_workload("./balanced")
assert reloaded.backend_spec == balanced.backend_spec
Strategies: qbalance.strategies¶
StrategySpec¶
StrategySpec is frozen and hashable, so it can be used for caching, de-duplication, and reproducible serialization.
Important validation rules:
optimization_levelmust be0..3.Boolean values are rejected for integer-like fields:
optimization_level,num_twirls,zne_degree,max_subcircuit_qubits,resilience_level,seed_transpiler, andseed_suppression.num_twirls >= 1.zne_degree >= 0; whenzne=True, it must also be at least1and smaller thanlen(zne_factors).When
zne=True,zne_factorsmust be non-empty, finite, sorted, all>= 1.0, and include1.0.When
cutting=True,max_subcircuit_qubitsis required.If
max_subcircuit_qubitsis provided, it must be an integer>= 1.resilience_levelmust beNone,0,1, or2.
load_strategy_specs(path: Path | str) -> list[StrategySpec]¶
Loads JSON strategy definitions from these supported shapes:
a single strategy object,
a list of strategy objects,
{"strategies": [...]},saved balanced workload results with
{"selections": {name: {"spec": ...}}},matrix results with
{"results": [{"strategy": ...}]}.
The function rejects malformed JSON, unreadable files, unsupported container shapes, non-object entries, and invalid strategy field combinations. Duplicate strategies are removed while preserving first-seen order.
coerce_strategy_specs(strategies: Iterable[StrategySpec | Mapping[str, Any]]) -> list[StrategySpec]¶
Normalizes an in-memory iterable of StrategySpec instances or mapping objects. Strings/bytes and non-iterables are rejected. Empty iterables are rejected. Duplicate normalized strategies are removed.
Objectives: qbalance.objectives¶
Objective(weights): immutable weighted minimization objective. Non-finite or non-numeric weights/metric values are ignored during scoring.default_objective(): returns the built-in depth/two-qubit/error/compile-time weighting used byWorkload.adjust(...)when no custom objective is supplied.load_objective(path): loads objective weights from JSON. The file may be a direct metric-to-weight object such as{"depth": 1.0}, an object with aweightsmapping, or a saved-results-style object with anobjectivemapping; malformed files, empty mappings, blank metric names, booleans, non-numeric weights, and non-finite weights raiseValueError.
Workflow: qbalance.workflow.workload¶
Workload¶
Constructors:
Workload.from_dataset(dataset)Workload.from_path(dataset_dir)
Methods:
set_target(backend_spec) -> Workloadadjust(...) -> BalancedWorkload
adjust parameters:
Parameter |
Default |
Description |
|---|---|---|
|
|
Objective instance; defaults to |
|
|
Candidate ordering mode: |
|
|
If true, select from the Pareto front before objective tie-break. |
|
|
Number of generated candidates when |
|
|
Number of randomly ordered candidates evaluated before bandit proposals. |
|
|
Execute compiled circuits and collect counts/mitigation metrics. Mitigation strategies such as M3/ZNE also trigger execution. |
|
|
Positive integer execution-shot count. Boolean values are rejected. |
|
|
Enable pass-level transpiler profiling. |
|
|
Optional compiled-circuit cache root. |
|
|
Integer seed for deterministic candidate ordering and execution helpers. Boolean values are rejected. |
|
|
Explicit iterable of strategies. If provided, |
|
|
Boolean safety rail. When |
Validation and edge-case behavior:
searchmust be exactly"grid"or"bandit".shotsmust be a positive integer;seedmust be an integer;warmupmust be a non-negative integer. Integral scalar types are accepted, but booleans are rejected.max_candidatesmust be a positive integer when generated candidates are used. It is not consulted when explicitstrategiesare supplied.At least one candidate strategy must be available after generated or explicit strategy normalization.
allow_regressionmust be a real boolean (TrueorFalse).search="bandit"evaluates up towarmupshuffled candidates first, then asks the bandit model to propose the remaining candidates one at a time, observing each evaluation before the next proposal. Non-finite objective scores are not observed by the bandit model, but they remain in the evaluated candidates and are handled by final selection.With
allow_regression=False, qbalance still records the full candidate evaluation history. Only the final selected strategy changes: if the selected candidate score is worse than the baseline score, the saved selection uses the baseline spec and baseline metrics plus guard metadata (selected_by_regression_guard,rejected_candidate_spec, andrejected_candidate_objective_score).
BalancedWorkload¶
Properties:
datasetbackend_specselections: mapping from circuit name to the selectedStrategy.baseline_metrics: mapping from circuit name to baseline compile metrics.objective: the objective used to score candidates.evaluation_history: optional mapping from circuit name to every evaluated candidateStrategy, in evaluation order. This is empty for legacy artifacts that predate candidate-history persistence.
Methods:
summary() -> str: human-readable baseline-vs-balanced aggregate summary. Whenevaluation_historyis present, the summary includes total and mean candidate-evaluation counts. When objective scores are comparable, it also reports the mean selected-minus-baseline objective delta and the number of comparable circuits whose objective improved.selection_diagnostics() -> dict: per-circuit baseline-vs-selected diagnostics computed from already stored metrics. Each entry includesbaseline_objective_score,selected_objective_score,objective_delta,objective_improved, per-objectiveobjective_terms,evaluated_candidates, andmetric_deltasfordepth,two_qubit_ops,estimated_error, andcompile_time_s. Missing, non-numeric, NaN, and infinite metric values are normalized toNone; objective scores areNonewhen no finite weighted term contributes, so invalid metrics are not mistaken for zero-cost candidates.candidate_rankings() -> dict: per-circuit candidate leaderboards derived fromevaluation_history, sorted by the same finite-safe selection score used by final strategy selection and then by original evaluation order. Each row containsrank,original_index, serializedspec, diagnosticobjective_score, JSON-safeselection_score, finite weightedobjective_terms, and aselectedmarker.objective_scoreis recomputed from finite objective terms for review;selection_scoremirrors selection semantics, including stored finitemetrics["objective_score"]when it is valid. Candidates with malformed, missing, or non-finite objective information getselection_score=Nonein the exported leaderboard and sort after comparable candidates. Ifallow_regression=Falsefalls back to a baseline that was not part of the candidate list, the baseline is included as the selected ranking row withoriginal_index: nullso saved audit artifacts still identify the final selection exactly once.covars() -> dict: EMD/CVM/KS diagnostics for depth, two-qubit ops, and estimated error. Missing, non-numeric, NaN, and infinite metric values are treated as0.0for these distribution-distance summaries.save(out_dir, overwrite=False) -> None: save dataset copy,results.json, andsummary.txt. The results file contains selections, baselines, objective weights,selection_diagnostics,candidate_rankings, andevaluation_history.to_download(zip_path, overwrite=False) -> Path: save a ZIP bundle.
load_balanced_workload(out_dir: Path | str) -> BalancedWorkload¶
Reloads a directory written by BalancedWorkload.save(...). The loader reconstructs the copied dataset, selected Strategy objects, baseline metrics, full candidate evaluation history, and Objective weights without re-running compilation or execution. Per-circuit selection diagnostics and candidate rankings are recomputed from the loaded metrics/history, so older artifacts that omit selection_diagnostics or candidate_rankings remain loadable. Artifacts written before evaluation_history existed also remain loadable; missing or null history is treated as an empty mapping. It validates the saved payload before returning:
results.jsonmust be a JSON object with a non-empty stringbackend_spec;objective,selections,metrics,baseline_metrics, andevaluation_historyentries must have the expected JSON shapes where present;saved
selection_diagnosticsandcandidate_rankings, if present, are treated as derived metadata and are not required for loading;every saved selection and evaluation-history entry must contain a strategy
specobject and optional metrics object;every saved strategy spec must pass
StrategySpecvalidation;selection names must exactly match the bundled dataset records;
baseline metric names and evaluation-history names, if present, must refer to bundled dataset records.
Use it for offline inspection or follow-up processing of saved adjustment results:
from qbalance import load_balanced_workload
balanced = load_balanced_workload("./balanced")
print(balanced.summary())
Benchmarking: qbalance.benchmarking¶
run_matrix(dataset_dir, backend_specs, strategies, out_json, execute=False, shots=1024, seed=0, profile=False) -> Path¶
Evaluates every (backend, circuit, strategy) combination and writes matrix JSON. It validates:
shotsis a positive integer and not a boolean,seedis an integer and not a boolean,backend_specsis a non-empty sequence of backend specs, not a single string/bytes value,strategiesis a non-empty sequence of strategy objects, not a single string/bytes value,loaded circuit count matches dataset record count.
The JSON payload contains version, metadata, and results. metadata records dataset_dir, backends, execute, shots, seed, and profile so matrix artifacts are self-describing. When execute=True, each result’s metrics can include counts and shot totals. If a strategy has zne=True, qbalance also runs folded circuits for zne_factors and stores extrapolated probabilities.
Search: qbalance.search¶
default_candidate_strategies(max_candidates=24, seed=0): deterministic default candidate pool.pareto_front(evals, keys): finite-safe Pareto filtering over metric keys.BanditSearcher: Thompson-sampling-style adaptive candidate ordering used bysearch="bandit".
Transpilation: qbalance.transpile¶
compile_one(circuit, backend, spec, profile=False): compile a circuit under one strategy and return(compiled_circuit, metrics).build_dd_pass_manager(backend, sequence="XY4"): create a dynamical-decoupling pass manager where Qiskit support is available.apply_pauli_twirling(circuit, num_twirls=1, seed=None): best-effort Pauli twirling transform.qbalance.transpile.suppression.apply_measurement_untwirl_counts(counts, flip_map): reverse measurement-twirling bit flips on counts.
Common compile metrics include depth, size, two-qubit operation count, estimated error, compile time, optional measurement flip maps, and optional pass profiles.
Execution and mitigation¶
qbalance.execution.run_counts(backend, circuit, shots=1024, seed_simulator=None): execute a circuit on a backend-like object and return counts.qbalance.mitigation.apply_mthree_mitigation(...): optional M3 mitigation integration.qbalance.mitigation.fold_global(circuit, factor): global folding helper for ZNE.qbalance.mitigation.zne_extrapolate_counts(factors, counts_per_factor, degree=1): extrapolate probability distributions back to zero noise.
Backend plugins¶
Backends are resolved by backend spec strings and entry-point plugins.
Built-in entry points include:
fake:fake:generic:<num_qubits>(optionallyfake:generic:<num_qubits>:<calibration_seed>; calibration data is seeded deterministically, seed 0 by default) andfake:ibm:<name>device snapshots viaqiskit-ibm-runtimewhere available.aer: qiskit-aer backends when theaerextra is installed.
Third-party packages can register qbalance.backends entry points. qbalance plugins list shows discovered plugin groups.
Reports¶
qbalance.reports.markdown.render_markdown(matrix_json, out_dir) -> Pathqbalance.reports.html.render_html(matrix_json, out_dir) -> Path
Markdown reports require only base dependencies. HTML reports require the optional report dependencies.