Documentation · v0.1.0

Build with Limbo.

The developer SDK for multi-chip quantum computing. Ingest from Qiskit, Cirq, or OpenQASM 3; lint locally; compile once and amortize across a variational loop; submit to a local simulator, a hosted backend, or directly to IBM Quantum, AWS Braket, or Azure Quantum.

Available now
pip install limbo-quantum   ·   Apache 2.0 licensed   ·   Python 3.10+

Install

$ pip install limbo-quantum

The SDK itself is pure-Python with no required runtime dependencies. Pull in the circuit framework you'll feed in:

$ pip install 'limbo-quantum[qiskit]'   # most common
$ pip install 'limbo-quantum[cirq]'
$ pip install 'limbo-quantum[qasm3]'

To submit directly to a vendor cloud, install the corresponding backend extra:

$ pip install 'limbo-quantum[ibm]'      # IBM Quantum
$ pip install 'limbo-quantum[aws]'      # AWS Braket
$ pip install 'limbo-quantum[azure]'    # Azure Quantum
$ pip install 'limbo-quantum[all]'      # everything

Quickstart

DistributedCompilerSDK is the single entry point. Construct once with a provider, call .compile() for every circuit.

from qiskit import QuantumCircuit
from limbo_quantum import DistributedCompilerSDK, LocalSimulationProvider

# Local simulator — zero credentials, zero network.
sdk = DistributedCompilerSDK(
    provider=LocalSimulationProvider(),
    num_qpus=2,
    max_capacity_per_qpu=4,
)

qc = QuantumCircuit(4)
qc.h(0)
for i in range(3):
    qc.cx(0, i + 1)
qc.measure_all()

result = sdk.compile(qc, shots=1024)
print(result.counts)
print(result.compiled_qasm[0])

Execution backends

Limbo does not lock you into any one path. The SDK is structured around a narrow QuantumProvider interface with three shipped implementations plus a documented extension point. Pick the path that matches your workflow:

Path A — Local simulator (no account, no network)

from limbo_quantum import DistributedCompilerSDK, LocalSimulationProvider

sdk = DistributedCompilerSDK(
    provider=LocalSimulationProvider(),
    num_qpus=2, max_capacity_per_qpu=4,
)

Path B — Hosted Limbo backend (one account, multiple vendors)

CloudProductionProvider is an HTTP client for the hosted compile service. The service holds your IBM / AWS Braket / Azure Quantum credentials encrypted server-side and runs the multi-chip-aware partitioner + cross-chip scheduler. You manage one API key; the service brokers the rest. Generate a key from your dashboard.

from limbo_quantum import DistributedCompilerSDK, CloudProductionProvider

sdk = DistributedCompilerSDK(
    provider=CloudProductionProvider(
        api_key="lmb_live_YOUR_KEY_HERE",
        server_url="https://api.limbosys.dev",
    ),
    num_qpus=4, max_capacity_per_qpu=20,
)

For multi-environment workflows, auto_provider() reads LIMBO_API_KEY and LIMBO_SERVER_URL from the environment and falls back to the local simulator when neither is set:

from limbo_quantum import DistributedCompilerSDK, auto_provider

sdk = DistributedCompilerSDK(provider=auto_provider())

Path C — Direct to a vendor (IBM / AWS / Azure)

If you already have vendor quotas, the SDK ships first-class wrappers for the three major clouds. Install the right extra and pass an instance to the SDK — no subclassing required.

# IBM Quantum  ·  pip install 'limbo-quantum[ibm]'
from limbo_quantum import DistributedCompilerSDK, IBMProvider

sdk = DistributedCompilerSDK(
    provider=IBMProvider(token="...", backend_name="ibm_brisbane"),
    num_qpus=1, max_capacity_per_qpu=127,
)
# AWS Braket  ·  pip install 'limbo-quantum[aws]'
from limbo_quantum import DistributedCompilerSDK, AWSProvider

sdk = DistributedCompilerSDK(
    provider=AWSProvider(
        device_arn="arn:aws:braket:::device/quantum-simulator/amazon/sv1",
    ),
    num_qpus=1, max_capacity_per_qpu=34,
)
# AWS creds: standard boto3 chain — env vars, ~/.aws/credentials, IAM role.
# Azure Quantum  ·  pip install 'limbo-quantum[azure]'
from limbo_quantum import DistributedCompilerSDK, AzureProvider

sdk = DistributedCompilerSDK(
    provider=AzureProvider(
        subscription_id="...",
        resource_group="quantum-rg",
        workspace_name="my-workspace",
        location="eastus",
        target_name="ionq.qpu",
    ),
    num_qpus=1, max_capacity_per_qpu=23,
)
# Azure auth: DefaultAzureCredential (az login / managed identity / SP env vars).

All three providers handle QASM → vendor-circuit translation, job submission, status polling, and result decoding for you. They lazy-import their vendor SDK so import limbo_quantum stays fast even if you've installed only one of the extras.

Path D — Bring your own backend

If you're targeting something else (Quantinuum, IonQ direct, Rigetti, a self-hosted Aer cluster, anything), subclass QuantumProvider with three methods:

from limbo_quantum import QuantumProvider, Job, JobResult

class MyBackend(QuantumProvider):
    name = "mine"

    def submit(self, payload, *, shots=1024, **options) -> Job:
        """Send compiled QASM. Return a Job."""
        ...

    def _fetch_status(self, job_id: str) -> JobResult:
        """Poll. Return JobResult with status in
        {queued, running, completed, failed}."""
        ...

    def list_devices(self) -> list[dict]:
        """Optional device catalog for auto-routing. Can be []."""
        ...

The shipped IBM / AWS / Azure providers (limbo_quantum/vendors.py in the repo) are full reference implementations of this pattern — copy one as a starting point.

Which path to choose

ScenarioUse
Prototyping, CI, anything Aer can runPath A · LocalSimulationProvider
One bill, one credential, multi-chip-aware compile server-sidePath B · CloudProductionProvider
You already have IBM / AWS / Azure quotasPath C · IBMProvider / AWSProvider / AzureProvider
Anything else (Quantinuum, IonQ direct, custom)Path D · subclass QuantumProvider

Multi-framework ingestion

The same .compile() call accepts Qiskit circuits, Cirq circuits, or raw OpenQASM 3 source strings. Auto-dispatched by input type:

# Qiskit
from qiskit import QuantumCircuit
qc = QuantumCircuit(3); qc.h(0); qc.cx(0, 1); qc.cx(0, 2)
sdk.compile(qc)

# Cirq
import cirq
q0, q1, q2 = cirq.LineQubit.range(3)
cq = cirq.Circuit(cirq.H(q0), cirq.CNOT(q0, q1), cirq.CNOT(q0, q2))
sdk.compile(cq)

# OpenQASM 3 source string
qasm = """
OPENQASM 3.0;
include "stdgates.inc";
qubit[3] q;
h q[0];
cx q[0], q[1];
cx q[0], q[2];
"""
sdk.compile(qasm)

Local linting

The SDK linter runs before any network call. Capacity violations and interaction-graph hotspots are surfaced on your laptop with no cloud round-trip needed:

from limbo_quantum import CircuitParser, LocalStaticLinter, TopologyCapacityError

ir = CircuitParser.from_qiskit(qc)
linter = LocalStaticLinter(ir, num_qpus=2, max_capacity_per_qpu=4)
try:
    linter.capacity_audit()
except TopologyCapacityError as exc:
    # Caught locally. No paid API call burned.
    print(f"needed {exc.num_qubits} qubits, layout had {exc.target_capacity}")

linter.hotspot_detection(threshold_ratio=0.30)   # prints dashboard

Variational runtime (VQE / QAOA)

For parametric circuits, ParametricRuntime compiles the template once and binds parameters locally on each subsequent call. The cache key is a SHA-256 of the circuit's structural signature, so different parameter values share a cache entry but a different gate sequence forces a re-compile.

from qiskit import QuantumCircuit
from qiskit.circuit import Parameter
from limbo_quantum import ParametricRuntime, InProcessCompilerClient

theta = Parameter("theta")
qc = QuantumCircuit(2)
qc.ry(theta, 0)
qc.cx(0, 1)
qc.measure_all()

runtime = ParametricRuntime(qc, client=InProcessCompilerClient())

for theta_val in [0.0, 0.1, 0.2, 0.3]:
    result = runtime.run({theta: theta_val}, shots=512)
    # First call: heavy compile. Subsequent calls: bind-only.
    print(theta_val, result.counts)

Telemetry

The TelemetryLogger auto-detects Jupyter vs. terminal and prints a clean per-step timeline:

from limbo_quantum import (
    DistributedCompilerSDK, LocalSimulationProvider, TelemetryLogger,
)

sdk = DistributedCompilerSDK(
    provider=LocalSimulationProvider(),
    num_qpus=2, max_capacity_per_qpu=4,
    telemetry=TelemetryLogger(),
)
sdk.compile(qc, shots=1024)
# Prints step durations, payload sizes, and lint outcomes.

Correctness scope

Limbo is a faithful transport for circuits that fit on your chosen target device. If circuit_qubits ≤ device_qubits, the SDK ingests, optionally pre-optimizes (Qiskit passes only), transpiles against the device's coupling map, and submits via the provider's official SDK. The result is semantically identical to what direct Qiskit + the vendor's SDK would produce.

The multi-chip routing path (when your circuit doesn't fit on a single physical device and the SDK partitions across multiple QPUs) is research-grade. There is no commercial cloud QPU today that exposes a multi-chip interconnect, so the cross-chip operations the SDK produces can only be validated on a simulator. Don't ship a num_qpus > 1 configuration to a single-chip cloud backend and expect correct results — the cross-chip entanglement won't be implemented.

API reference

Top-level exports from limbo_quantum:

SymbolPurpose
DistributedCompilerSDKMaster client; one .compile() call drives the whole pipeline.
CompileResultDataclass returned by .compile() with counts, QASM, metrics, telemetry.
quickstart()One-liner for laptop dev (LocalSimulationProvider).
QuantumProviderAbstract base for custom execution backends.
LocalSimulationProviderIn-process qiskit-aer driver.
CloudProductionProviderHTTP client for the hosted Limbo backend.
IBMProviderDirect IBM Quantum execution via qiskit-ibm-runtime.
AWSProviderDirect AWS Braket execution via amazon-braket-sdk.
AzureProviderDirect Azure Quantum execution via azure-quantum.
auto_provider()Cloud if LIMBO_API_KEY / LIMBO_SERVER_URL set, else local.
CircuitParserMulti-framework parser → standardized JSON IR.
IRSchemaSchema descriptor for the JSON IR shape.
LocalStaticLinterCapacity audit + hotspot detection.
TopologyCapacityErrorRaised when the target layout can't host the circuit.
ParametricRuntimeCompile-once-bind-many runtime for variational workloads.
TopologicalTemplateCached structural compile for parametric circuits.
InProcessCompilerClientLocal compile client for ParametricRuntime.
HTTPCompilerClientHTTP compile client for ParametricRuntime against a hosted backend.
TelemetryLoggerJupyter / terminal step-timeline display.
Job · JobResultHandle + result-payload dataclasses returned by providers.

View on PyPI View on GitHub Join the waitlist for cloud backend access