Options#

See Options for what each option does.

class QCut.CutOptions(consolidate: Literal['auto', 'always', 'never'] | bool = 'auto', joint_rotation_cuts: bool = True, wire_cut_communication: Literal['auto', 'always', 'never'] | bool = 'auto', expansion: Literal['auto', 'exact', 'sample'] = 'auto', max_exact_groups: int = 1000, num_samples: int | None = None, seed: int | None = None, deduplicate: bool = True, finder_candidates: int = 5, finder_cut_mode: Literal['both', 'wire', 'gate'] = 'both', finder_max_qubits: int | list[int] | None = None, finder_num_partitions: int | None = None)[source]#

Bases: object

Configuration for a cutting run.

consolidate merges runs of gates acting on the same qubit pair into one gate before cutting, so the pair costs one cut instead of several. See ConsolidateStrategy. Merging can cost more than it saves once joint cutting is in play, because a merged run of gates about different axes is no longer a single-axis rotation and cannot be bundled, so "auto" compares the two plans outright rather than guessing.

joint_rotation_cuts cuts parallel two-qubit rotation gates with one joint decomposition instead of one each, which costs strictly less in both sampling overhead and circuit count.

wire_cut_communication lets the two sides of a wire cut exchange the measured outcome, which lowers the overhead of a block of n parallel wires from 4**n to 2**(n+1) - 1. It makes those experiments run in two phases, since the state one side prepares depends on what the other measured. See CommunicationStrategy.

expansion decides how the decomposition becomes experiment circuits, see ExpansionStrategy. Under "auto", max_exact_groups is the largest exact group count still enumerated rather than sampled. When sampling, num_samples draws are taken, defaulting to max_exact_groups, and seed fixes the sampler for a reproducible experiment set. Without one, a seed is drawn and kept as CutExperiment.seed.

deduplicate submits each distinct experiment circuit once and shares its result between every slot it fills, rather than running the same circuit once per group. The slot count grows exponentially in the number of pieces while the distinct count grows linearly, so this is most of the cost of a run. shots still means shots per circuit, so the total spent drops by the same factor; what it bought before was re-measuring circuits already measured. Turn it off to submit one circuit per slot.

finder_candidates is how many candidate partitions the cut finder generates and costs before keeping the cheapest. METIS returns only the partitioning that minimises its own objective, the weighted edge cut, which stops being the true cost once cuts share a decomposition, so several are generated and compared on what they actually cost. Under a qubit budget they vary by how much imbalance METIS is allowed before they vary by seed, since that changes the partition more. Both are fixed, which makes the finder reproducible; seed shifts the seeds as a set.

finder_cut_mode limits the finder to wire cuts, to gate cuts, or lets it use both. finder_num_partitions asks for a number of pieces and finder_max_qubits for a size limit per piece, either one number for all of them or a list with one entry per partition. With neither given the finder splits in two.

consolidate: Literal['auto', 'always', 'never'] | bool = 'auto'#
joint_rotation_cuts: bool = True#
wire_cut_communication: Literal['auto', 'always', 'never'] | bool = 'auto'#
expansion: Literal['auto', 'exact', 'sample'] = 'auto'#
max_exact_groups: int = 1000#
num_samples: int | None = None#
seed: int | None = None#
deduplicate: bool = True#
finder_candidates: int = 5#
finder_cut_mode: Literal['both', 'wire', 'gate'] = 'both'#
finder_max_qubits: int | list[int] | None = None#
finder_num_partitions: int | None = None#
property consolidate_mode: str#

The consolidation strategy, with True and False normalised.

property min_communicating_block: int#

Smallest wire cut block that will use classical communication.

property sample_count: int#

Number of draws to use when sampling.

property num_partitions: int#

Number of partitions to cut the circuit into.

property max_qubits: list[int] | None#
should_sample(exact_groups: int) → bool[source]#

Whether an experiment of exact_groups combinations should be sampled.

replace(**changes) → CutOptions[source]#

Return a copy with changes applied.

__init__(consolidate: Literal['auto', 'always', 'never'] | bool = 'auto', joint_rotation_cuts: bool = True, wire_cut_communication: Literal['auto', 'always', 'never'] | bool = 'auto', expansion: Literal['auto', 'exact', 'sample'] = 'auto', max_exact_groups: int = 1000, num_samples: int | None = None, seed: int | None = None, deduplicate: bool = True, finder_candidates: int = 5, finder_cut_mode: Literal['both', 'wire', 'gate'] = 'both', finder_max_qubits: int | list[int] | None = None, finder_num_partitions: int | None = None) → None#
QCut.DEFAULT_OPTIONS#

The CutOptions used when none are passed. Reassign it to change the defaults process-wide.