API reference¶
This page documents the public API exported from quport.__all__ plus the most
commonly used lower-level helpers. It is intentionally descriptive rather than
auto-generated so it can explain validation, modeling assumptions, and how return
objects should be interpreted.
All public validators reject booleans where an integer or numeric value is expected.
This matters because Python treats bool as a subclass of int, but QuPort treats
boolean values as almost always accidental in numerical configuration.
Package marker¶
QuPort ships py.typed, so type checkers can consume the package’s inline type
annotations when it is installed from a built distribution. Public annotations are
therefore part of the developer-facing API and should not be weakened just to make
negative tests easier to write.
Configuration and architecture¶
MultiQPUConfig¶
MultiQPUConfig(
n_qpus=10,
compute_qubits_per_qpu=8,
comm_qubits_per_qpu=1,
intra_topology="clique",
inter_topology="switch",
inter_degree=2,
link_capacity=1,
switch_parallel_links=1_000_000,
switch_reconfig_delay=0.0,
async_classical=True,
async_overlap=0.5,
grid_rows=None,
grid_cols=None,
basis_gates=("rz", "sx", "x", "cx"),
optimization_level=3,
layout_method="sabre",
routing_method="sabre",
)
Primary architecture/transpiler configuration. Use total_physical_qubits() and
capacity_per_qpu() to derive aggregate sizes. The dataclass validates fields that
can be checked locally in __post_init__, while topology-specific validation occurs
when graph/coupling-map builders are invoked.
LatencyModel¶
LatencyModel(oneq=1.0, twoq=10.0, swap=30.0, epr_gen=200.0,
classical_rtt=20.0, remote_gate_overhead=50.0,
epr_success_prob=1.0)
Cost model used by mapping costs and schedule estimators. estimate_latency(...)
returns a finite non-negative scalar latency proxy. Coefficients are arbitrary units;
use consistent units within a study.
epr_success_prob is the heralded entanglement success probability per attempt, in
(0, 1]. expected_epr_time(hops) returns hops * epr_gen / epr_success_prob, the
expected time to distribute one pair across hops links. Only
estimate_entanglement_schedule reads it; the default of 1.0 models a
deterministic link, so estimate_cost and the older estimators are unaffected.
MultiQPUArchitecture¶
arch = MultiQPUArchitecture(cfg)
Builds physical and QPU-level topology from MultiQPUConfig.
Important methods:
qpu_of_phys(p) -> int: map a physical qubit index to a QPU id; rejects out-of-range indices.block_of_qpu(qpu_id) -> QPUBlock: return compute and communication qubits for one QPU.all_blocks() -> list[QPUBlock]: return all QPU blocks in QPU-id order.build_coupling_map() -> CouplingMap: build full directed global coupling map.build_intra_coupling_map(qpu_id) -> CouplingMap: build local directed coupling map.qpu_shortest_paths() -> QpuShortestPaths: compute QPU-level shortest paths.
QPUBlock has compute and comm lists. Those lists contain physical qubit indices,
not logical qubit indices.
topology_metrics¶
from quport import MultiQPUConfig, topology_metrics
from quport.network import build_qpu_graph
metrics = topology_metrics(build_qpu_graph(MultiQPUConfig(inter_topology="ring")))
Computes validated inter-QPU graph diagnostics as a TopologyMetrics dataclass.
Fields include n_qpus, edges, min_degree, max_degree, average_degree,
connected, components, diameter, average_shortest_path, and
unreachable_pairs. Distances are calculated over reachable unordered QPU pairs;
unreachable_pairs makes disconnected or zero-port topologies explicit instead of
folding them into the average.
Mapping pipeline¶
map_and_transpile¶
map_and_transpile(qc, cfg, latency=None, seed=None, strategy="balanced",
temporal_decay=None) -> MapResult
End-to-end global mapping flow:
validate circuit capacity and optional non-negative integer seed;
translate to configured basis gates;
partition logical qubits;
compute layout hints;
run Qiskit transpilation on the global coupling map;
compute metrics and cost.
Supported strategies: balanced, cluster, ebit, tpccap, tpccap_sa.
temporal_decay selects the interaction weighting for the topology-aware
strategies and applies to tpccap, tpccap_sa, and ebit alike, so a run isolates
the annealing rather than also changing the objective’s inputs. Leaving it None
keeps the historical split, in which tpccap uses uniform counts while
tpccap_sa and ebit use a decay of 0.98; that default is unchanged so existing
benchmark numbers do not move. See
Partitioning strategies for why this
matters when interpreting benchmark output.
MapResult fields:
Field |
Meaning |
|---|---|
|
routed Qiskit |
|
architecture config used for the run |
|
logical-qubit-to-QPU assignment |
|
cut of |
|
partitioning strategy name |
|
topology-aware diagnostics when available |
|
partition/layout-hint time |
|
Qiskit transpilation time |
|
|
|
|
Important edge cases:
If
qc.num_qubits > cfg.total_physical_qubits(),ValueErroris raised.If
seedis provided, it must be a non-negative integer and not a boolean.Unknown strategies are rejected before layout/transpilation.
benchmark_random_circuits¶
benchmark_random_circuits(cfg, n_logical, depth, trials, seed=0,
latency=None, out_csv=None,
strategies=("baseline", "balanced", "tpccap"))
Runs random-circuit benchmarks and optionally writes a numeric-friendly CSV.
Strategies may include baseline, balanced, cluster, ebit, tpccap, and tpccap_sa.
The returned rows include trial, seed, method id, strategy, SWAPs, remote-2Q count,
depth, size, costs, and timing columns.
Validation highlights:
n_logical,depth,trials, andseedmust be non-negative integers.strategiesmust be a non-string sequence of strings.Duplicate and unknown strategies are rejected.
Zero trials are allowed and still write a header when
out_csvis provided.
sweep_topologies¶
sweep_topologies(n_logical, depth, trials, seed, out_csv,
intra_topologies=("clique", "line", "ring"),
inter_topologies=("switch", "ring", "degree_d", "clos"),
comm_ports=(1, 2), compute_per_qpu=8,
n_qpus=10, inter_degree=2,
strategies=("baseline", "balanced", "tpccap"))
Sweeps topology and communication-port settings and writes a summary CSV with mean
SWAPs, remote 2Q operations, depth, cost, and transpilation time, plus the median
cost, which is skewed enough across random circuits to need both. Configurations
whose physical capacity cannot fit n_logical are skipped.
Distributed compilation¶
compile_distributed¶
compile_distributed(qc, cfg, latency=None, seed=None,
strategy="tpccap_sa", temporal_decay=0.98) -> DistributedCompileResult
Distributed compilation flow that preserves cross-QPU operations as explicit remote
events. The optional seed is validated as a non-negative integer before Qiskit calls.
Supported strategies: balanced, cluster, ebit, tpccap, tpccap_sa.
The temporal_decay argument is used for topology-aware strategies. It must be in
(0, 1] when applicable. Values closer to 1 behave more like uniform interaction
weights; smaller values emphasize earlier two-qubit interactions more strongly.
DistributedCompileResult fields:
Field |
Meaning |
|---|---|
|
basis-translated, physically laid-out circuit without global routing |
|
the circuit after basis translation, before layout: what |
|
architecture config |
|
partitioning strategy |
|
logical-qubit-to-QPU assignment |
|
cut of |
|
topology-aware partition diagnostics when available |
|
simulated annealing diagnostics for |
|
|
|
per-QPU locally routed circuits |
|
remote-op manifest re-expressed in |
|
metrics on the physical, not globally routed, circuit |
|
per-QPU operation counts after local routing |
|
topology-aware schedule summary |
|
detailed layer/round schedule trace |
|
distributable packets of the basis-translated circuit |
|
|
|
|
|
|
|
partition/layout time |
|
local per-QPU transpilation time |
split_into_qpus¶
split_into_qpus(mapped, arch) -> DistributedProgram
remap_remote_ops_to_routed(remote_ops, local_routed) -> list[RemoteOp]
Each RemoteOp also carries qpu0_marker and qpu1_marker: the position of
its synchronization barrier among all barriers of that QPU’s program, counting
from zero. Emitted QASM carries no labels, and routing can reorder barriers that
sit on disjoint qubits, so these are what let a consumer pair a manifest entry
with the right barrier.
Re-expresses a manifest in the labelling of routed local programs. Routing
permutes qubits inside a QPU unless the intra-QPU topology is a clique, so a
manifest recorded before routing points at the wrong qubits afterwards. The
routed circuits carry the answer: split_into_qpus labels each synchronization
barrier with the operation it marks, and the transpiler remaps those barriers
along with everything else. compile_distributed applies this automatically and
returns the result as routed_remote_ops.
Splits a mapped physical circuit into per-QPU local circuits and ordered remote
operation metadata. Local one-qubit and intra-QPU two-qubit operations are appended
to the owning QPU circuit. Cross-QPU operations become RemoteOp entries and
barriers are inserted on involved local circuits to mark synchronization points.
Zero-qubit operations are broadcast to all local circuits unless they are barriers, which are represented as barriers. Multi-qubit operations that span multiple QPUs are conservatively represented as remote composite operations.
DistributedProgram¶
DistributedProgram(local_circuits: dict[int, QuantumCircuit],
remote_ops: list[RemoteOp])
Methods:
remote_ops_payload() -> list[dict[str, Any]]: JSON-safe remote-operation payload.
The local circuits currently use the full physical register for clarity. Downstream consumers may shrink circuits if their execution environment prefers per-QPU local registers only.
RemoteOp¶
RemoteOp(name, q0_phys, q1_phys, qpu0, qpu1, params, clbits, index,
qpu0_marker=None, qpu1_marker=None)
Represents one remote operation placeholder. to_dict() validates fields and
returns a deterministic JSON-safe representation. Non-finite floats, complex values,
bytes, sets, mappings, and nested sequences in parameters are encoded safely for JSON.
Field meanings:
name: source operation name, such ascx;q0_phys,q1_phys: physical qubit indices involved in the remote operation;qpu0,qpu1: owning QPUs for those physical qubits;params: operation parameters converted through JSON-safe encoding;clbits: classical bit indices associated with the source instruction;index: source instruction index in the physical circuit;qpu0_marker,qpu1_marker: position of the operation’s synchronization barrier among all barriers of each QPU’s program (seesplit_into_qpusabove).
Writers¶
write_remote_ops_json(remote_ops, path) -> None
write_distributed_program(program, path, *, include_empty_circuits=True) -> dict[str, Path]
write_remote_ops_json writes a standards-compliant JSON manifest with
allow_nan=False. write_distributed_program writes qpu_<id>.qasm files and a
remote_ops.json manifest to a directory, validating all artifact inputs before writing.
write_distributed_program returns a mapping of artifact labels to Path objects.
Keys are stable (qpu_<id> and remote_ops) so callers can report or post-process
outputs without re-deriving file names.
Scheduling API¶
estimate_parallel_makespan¶
estimate_parallel_makespan(mapped, arch, model) -> ScheduleSummary
Coarse synchronized QPU timeline estimator. It walks the circuit, accumulates local operation costs per QPU, and synchronizes timelines when remote operations occur. An operation that touches a classical bit also waits for the previous operation on that bit, on whichever QPU it ran.
estimate_parallel_makespan_layered¶
estimate_parallel_makespan_layered(mapped, arch, model) -> ScheduleSummary
DAG-layer estimator with communication-port-limited remote rounds. It approximates parallel local execution within each DAG layer and groups remote operations into rounds according to available QPU communication ports.
estimate_parallel_makespan_topology¶
estimate_parallel_makespan_topology(mapped, arch, model) -> TopologyScheduleSummary
Topology-aware estimator with QPU ports, link capacity, switch pair budgets, reconfiguration delay, asynchronous classical overlap, and unschedulable penalties. Use this estimator for network-resource studies.
estimate_topology_schedule_plan¶
estimate_topology_schedule_plan(mapped, arch, model) -> TopologySchedulePlan
Returns the topology-aware summary plus a detailed trace of layers and remote rounds.
Each layer and each remote round carries absolute start_time and end_time offsets,
so callers can render timelines or feed simulators without recomputing cumulative
durations. This is the most useful API when diagnosing why a makespan increased.
estimate_entanglement_schedule¶
estimate_entanglement_schedule(mapped, arch, model, *, plan=None,
ports_per_qpu=None) -> EntanglementScheduleSummary
Event-driven as-soon-as-possible schedule over aggregated EPR blocks, with one timeline per physical qubit and per classical bit, a pool of comm ports held for a whole block, per-link channels, and hop-scaled probabilistic entanglement distribution. Unlike the layer-based estimators it imposes no global barrier between layers and charges one transaction per block rather than per gate, so its makespan is not comparable with theirs.
plan defaults to aggregate_remote_operations(mapped, arch, ports_per_qpu=...).
A supplied plan has to fit the schedule’s port budget, as one built with that same
budget always does. A plan that needs more ports at once than exist – more live cat
copies than a QPU has, or no port left for an entangler – raises ValueError
rather than silently reporting the work as unschedulable.
See Entanglement model.
audit_topology_schedule_plan¶
audit_topology_schedule_plan(plan, arch, model, mapped=None) -> tuple[str, ...]
Re-derives a TopologySchedulePlan’s numbers from the outside and returns one
description per inconsistency; an empty tuple means every figure was reproduced.
The estimator builds the summary and the trace in one pass, so nothing in it
cross-checks the two or checks either against the budgets the plan claims to
respect. This checks that:
layer and round intervals chain, and each
end_timeisstart_time + duration;a layer lasts
max(local_duration, sum of its round durations);each round’s
qpu_ports_usedandlink_utilizationare exactly what routing itsqpu_pairsconsumes, withincomm_qubits_per_qpuandlink_capacity;each round lasts as long as its slowest placed operation;
the six summary fields agree with the trace they summarise.
Passing mapped adds the check that needs the circuit: that the plan accounts for
exactly the operations spanning more than one QPU, counted as split_into_qpus
counts them. The cost model itself — per-hop EPR time, classical-RTT overlap, the
round-packing policy — is taken as given; those are modelling choices, and the
audit checks the plan is a faithful, feasible account of them.
quport compile-dist runs this before writing schedule_trace.json and refuses to
write a manifest that does not add up.
audit_entanglement_schedule¶
audit_entanglement_schedule(summary, mapped, arch, model, *,
plan=None, ports_per_qpu=None) -> tuple[str, ...]
The counterpart for estimate_entanglement_schedule, which returns aggregates and
no trace — so instead of replaying events, this checks everything the aggregates
are related by theorem:
a QPU with
Pports cannot hold more thanPcat copies at once, nor accrue more thanP * makespanof port-busy time; a link withCchannels likewise;entanglement_timeequals the sum oflink_busy_time, by definition;every gate on a qubit occupies that qubit’s timeline, so the busiest qubit’s own work is a lower bound on the makespan;
remote_gatesis the circuit’s own count of operations spanning more than one QPU, and no more gates can be unschedulable than there are remote ones;with
plan, the summary describes that plan’s blocks and EPR pairs.
ports_per_qpu must be whatever the schedule was produced with. Monotonicity —
that widening a resource never lengthens a schedule — is a property of the
estimator rather than of one result, so it is obtained by scheduling one fixed
plan twice and comparing; tests/test_entanglement_schedule.py does exactly
that for ports, link channels, epr_gen, and epr_success_prob.
quport compile-dist and quport ebits --out both run this before writing
entanglement_plan.json.
Entanglement API¶
diagonal_positions(operation) -> frozenset[int]
build_distributable_packets(qc, *, symmetric_root="greedy") -> PacketDecomposition
ebit_cost(decomposition, part, n_qpus) -> int
ebit_objective(decomposition, part, n_qpus, dist=None) -> tuple[int, float]
ebit_report(decomposition, part, n_qpus) -> EbitReport
ebit_traffic_matrix(decomposition, part, n_qpus) -> list[list[float]]
aggregate_remote_operations(mapped, arch, *, ports_per_qpu=None,
max_block_gates=None) -> AggregationPlan
diagonal_positionsreports which operand positions commute withZ, the condition under which a cat copy of that operand survives an operation.build_distributable_packetsextracts placement-independent packets;ebit_costscores any partition against them with the λ−1 metric, andebit_objectiveadds the hop-weighted variant used by theebitstrategy.ebit_reportreturnsEbitReport(ebits, baseline_ebits, reduction, packets, active_packets, packed_gates, cut_gates, unpackable_ebits, peak_cat_copies, pair_ebits).aggregate_remote_operationsturns a mapped circuit intoRemoteBlockobjects under a real comm-port budget, evicting the least recently used cat copy when a port is needed. With unlimited ports itsepr_pairsequalsebit_costwhenever every cross-QPU gate’s root is forced, as forcx; symmetric gates (cz,cp) leave the root free, and the two models can then choose differently.
tpccap_partition and tpccap_sa_partition accept packets, w_ebit, and
congestion_source. w_ebit=0.0 and congestion_source="gates" (the defaults)
leave their historical objectives unchanged and only fill in the ebits and
weighted_ebit_distance diagnostics. congestion_source="ebits" routes EPR demand
rather than gate demand through the congestion term, and requires packets. With
uniform weights and gates a cat copy can serve, gate demand upper-bounds EPR demand,
because aggregation only ever removes transactions; a teleported gate costs two EPR
pairs, and decayed weights shrink gate demand, so neither bounds the other in
general.
ebit_partition(n, weights, n_qpus, capacity, comm_ports_per_qpu, sp, packets, seed=None)
is the ebit strategy itself: tpccap_sa_partition with w_dist=0, w_ebit=1,
w_port=0, w_cong=anneal_w_cong=0.05, and congestion_source="ebits". Both
map_and_transpile and compile_distributed partition through it, so
strategy="ebit" names one objective in either pipeline.
compile_distributed returns packets, ebits, aggregation, and
entanglement_schedule alongside its existing fields.
Exact partitioning¶
optimal_partition(n, n_qpus, capacity, *, objective="cut", weights=None,
packets=None, max_nodes=DEFAULT_MAX_NODES) -> ExactPartition
partition_gap(part, n_qpus, capacity, *, objective="cut", weights=None,
packets=None, max_nodes=DEFAULT_MAX_NODES) -> PartitionGap
Branch and bound over set partitions of at most n_qpus blocks, for both
objectives QuPort optimises: "cut" (needs weights) and "ebits" (needs
packets). Symmetry is broken by restricted-growth canonical form, which is valid
because both objectives are invariant under relabelling QPUs and the capacity is
uniform.
ExactPartition(part, objective, proved_optimal, nodes).proved_optimalis false whenmax_nodesran out first;objectiveis then an upper bound on the optimum, andpartis still feasible and still the best found.PartitionGap(heuristic, optimal, proved_optimal)withabsoluteandrelativeproperties.relativeis0.0when the heuristic is optimal andmath.infwhen the optimum is zero and the heuristic is not.partition_gapraises ifpartis infeasible, or if it scores below a proved optimum — which would mean one of the two implementations is wrong.
The tree is over set partitions, so this terminates on roughly a dozen qubits. It exists to calibrate the heuristics, not to compile.
Time-varying placement¶
split_windows(decomposition, count) -> tuple[TemporalWindow, ...]
static_temporal_partition(part, windows) -> TemporalPartition
temporal_ebit_cost(decomposition, partition, n_qpus, *,
migration_cost=1) -> TemporalCost
optimize_temporal_partition(decomposition, part, n_qpus, capacity, windows, *,
migration_cost=1, max_passes=8,
seed=None) -> TemporalResult
Prices letting qubits move between QPUs mid-circuit, in the same e-bit model.
TemporalWindow(start, stop)is a half-open instruction range; windows must be contiguous and the first must start at 0.split_windowscuts the stream into windows of similar communication content, returning fewer than asked for when the circuit has too few relevant gates.TemporalPartition(windows, assignments)holds one assignment per window, withmigrations()andto_dict().TemporalCost(packet_ebits, unpackable_ebits, migration_ebits, moves)and itstotal. Cat copies are counted over root epochs, so a copy survives a window boundary when its root does not move.TemporalResult(partition, cost, static_cost, stationary_cost, passes)withsaved/reductionagainst the seed, andmigration_saved/migration_reductionagainst the best placement the same search reaches with migration forbidden.cost.total <= stationary_cost <= static_costholds by construction.
With one window, or the same assignment in every window, temporal_ebit_cost
returns exactly ebit_cost for that assignment.
Reassembly and verification of a distributed program¶
reassemble_distributed_program(mapped, local_routed, remote_ops, arch, *,
restore_layout=True) -> QuantumCircuit
verify_distributed_program(mapped, local_routed, remote_ops, arch, *,
seed=0, atol=1e-9) -> bool
reassemble_distributed_program is the inverse of split_into_qpus: it merges
per-QPU programs and a remote-op manifest back into one circuit and, with
restore_layout=True, undoes each QPU’s routing permutation so the result is
directly comparable with the mapped circuit. Classical bits and registers are
carried across, so measurements and conditioned operations survive the round
trip. verify_distributed_program does that comparison by state-vector
simulation: terminating measurements are dropped, and a circuit with mid-circuit
measurement, reset, or classical control is refused with ValueError.
A distributed program is a partial order. Within a QPU the constraint is per
qubit, so instructions on disjoint qubits may run in either order, and two QPUs
can list the same remote operations in opposite orders. Merging follows qubit
dataflow: an instruction runs once it leads on every qubit it touches, and a
remote operation once its marker leads on both sides. Classical bits are shared
across the programs, and the order of their accesses across QPUs is taken from
mapped: an instruction that touches a classical bit also waits for every
earlier access to that bit, on any QPU. Reading each program strictly linearly
can deadlock; reassemble_distributed_program raises when the programs
genuinely contradict each other.
Pass routed_remote_ops with local_routed, or program.remote_ops with
program.local_circuits.
Protocol emission and verification¶
build_telegate_circuit(mapped, arch, plan=None, *, coherent=True,
ports_per_qpu=None) -> TelegateProgram
verify_telegate_equivalence(mapped, arch, plan=None, *, seed=0, atol=1e-9,
ports_per_qpu=None) -> bool
build_telegate_circuit expands an aggregation plan into the circuit that
performs it. coherent=True (default) emits the deferred-measurement form,
which is unitary and therefore verifiable; coherent=False emits real
mid-circuit measurement with if feedforward and reset, suitable for OpenQASM
3 export. Ancillas are recycled between blocks, so the emitted width follows the
number of concurrently live cat copies.
TelegateProgram(circuit, n_data, ancillas, blocks, epr_pairs, unschedulable_gates, measured) — the first n_data qubits of circuit are the
mapped circuit’s, in order; the rest are protocol ancillas that start and end in
the ground state. n_ancillas is a convenience property.
verify_telegate_equivalence simulates the unitary form on a pseudo-random
product input, traces out the ancillas, and compares the data qubits’ reduced
state with the mapped circuit’s. It raises for plans with unschedulable gates,
and for circuits wider than quport.protocol.MAX_VERIFIABLE_QUBITS (24).
Schedule dataclasses¶
ScheduleSummary(makespan, steps, remote_ops)TopologyScheduleSummary(makespan, layers, remote_ops, remote_rounds, peak_link_util, peak_qpu_ports_used)RemoteRoundTrace(layer_index, round_index, qpu_pairs, duration, qpu_ports_used, link_utilization, unschedulable_ops=0, start_time=0.0, end_time=0.0)LayerScheduleTrace(layer_index, local_duration, remote_ops, remote_rounds, duration, start_time=0.0, end_time=0.0)TopologySchedulePlan(summary, layers)EntanglementScheduleSummary(makespan, blocks, epr_pairs, remote_gates, unschedulable_gates, entanglement_time, peak_ports_in_use, port_busy_time, qpu_busy_time, link_busy_time)
TopologyScheduleSummary, RemoteRoundTrace, LayerScheduleTrace, and
TopologySchedulePlan provide to_dict() methods that return stable JSON-ready
payloads. The conversion normalizes tuple-heavy fields such as QPU pairs and link
utilization into ordinary JSON arrays/objects, so command-line schedule exports and
downstream simulators can consume traces without depending on Python dataclass
serialization details. The serializers also revalidate manifest fields and reject
non-finite timings, negative counts, booleans in integer fields, malformed QPU/link
pairs, and self-loop pairs before emitting payloads.
LayerScheduleTrace.start_time is the absolute offset at which the DAG layer begins,
and LayerScheduleTrace.end_time is start_time + duration. Remote rounds are
serialized from the containing layer’s start_time; each RemoteRoundTrace.start_time
is the previous round’s end_time (or the layer start for the first round), and
RemoteRoundTrace.end_time is start_time + duration. If local work is longer than
the cumulative remote rounds, the layer end can be later than the final remote-round
end because local work occupies the full layer interval.
Interaction and metrics helpers¶
WeightValue¶
WeightValue is a type alias for values accepted by validated interaction-weight
APIs: SupportsFloat | SupportsIndex | str. Runtime validation still rejects
booleans, non-finite values, negative values, invalid edge keys, and out-of-range
logical indices.
degree¶
degree(weights, n) -> list[float]
Computes weighted degree for n logical nodes. Self-loops and zero-weight edges are
ignored after validation.
cut_weight / compute_cut¶
cut_weight(weights, part) -> float
compute_cut(weights, part) -> float
Computes the total weight of interactions crossing partition boundaries. part
must be a list of non-negative integer QPU assignments and must be long enough for
all logical indices referenced by weights.
CircuitMetrics¶
CircuitMetrics(swaps, depth, size, n_1q, n_2q, remote_2q)
Returned by compute_metrics(qc, arch) and embedded in mapping/distributed results.
remote_2q is derived by comparing the QPU ownership of each two-qubit operation’s
physical operands.
swaps counts instructions literally named swap, which makes it basis-dependent.
The default basis_gates of ("rz", "sx", "x", "cx") has no swap, so Qiskit
rewrites routing SWAPs into CX gates and swaps is 0 for every run, with the
routing overhead appearing in n_2q instead. Include "swap" in basis_gates to
keep the instructions and make the metric meaningful.
A swap instruction counts toward both swaps and n_2q, so in estimate_cost
the swap latency is an overhead on top of the two-qubit cost: a surviving SWAP
costs twoq + swap, which is 40 under the default LatencyModel rather than 30.
Lower-level modules worth knowing¶
Although not all lower-level helpers are exported from quport.__all__, advanced
users may import from submodules directly:
quport.pipeline.random_benchmark_circuitfor deterministic random circuits;quport.config.load_configandquport.config.dump_configfor JSON/YAML configs;quport.metrics.compute_metricsandquport.metrics.count_opsfor direct analysis;quport.interaction.extract_twoq_weightsandextract_temporal_twoq_weightsfor partition diagnostics;quport.network.build_qpu_graphfor QPU-level topology inspection;quport.network.prepare_routing_tablesandroute_prepared_link_loadsto route many traffic matrices over one interconnect without re-validating the shortest-path tables each time, andaccumulate_traffic/accumulate_boundary_countsfor the same reason on edge weights. These reproduce their validating counterparts exactly; the caller takes on the input contract;quport.entanglement.acts_diagonallyandbreaks_cat_copyfor custom cat-copy analyses;quport.hypergraph.DistributablePacketfor inspecting individual packets.