uniqc.circuit_builder.qcircuit module¶
Quantum circuit builder with OriginIR and OpenQASM 2.0 output.
This module provides a Circuit class for building quantum circuits programmatically. It supports various quantum gates, controlled operations, dagger (adjoint) blocks, and measurement operations. The circuit can be exported to OriginIR or OpenQASM format.
- Key exports:
Circuit: Main quantum circuit builder class. OpcodeType: Type alias for opcode tuples.
- class uniqc.circuit_builder.qcircuit.Circuit(qregs=None, param_dict=None)[source]¶
Bases:
objectQuantum circuit builder that generates OriginIR and OpenQASM output.
- Variables:
used_qubit_list (list[int]) – Qubits referenced in the circuit.
circuit_str (str) – Raw string builder used by context managers.
max_qubit (int) – Highest qubit index used.
qubit_num (int) – Total number of qubits.
cbit_num (int) – Total number of classical bits.
measure_list (list[int]) – Qubits scheduled for measurement.
opcode_list (list[OpCode]) – Internal list of gate opcodes.
_qregs (dict[str, QReg]) – Named quantum registers (if created with qregs parameter).
AnyQuantumCircuit — the universal input type
Most public APIs (
compile(),Simulator,submit_task()) acceptAnyQuantumCircuit, which is a union of:Circuit— this classstr— OriginIR or OpenQASM 2.0 (auto-detected from content)qiskit.QuantumCircuit— converted via QASM round-trippyqpanda3.QProg— converted via OriginIR round-trip
Use
to_qiskit_circuit()orto_pyqpanda3_circuit()to convert back to external formats.- add_gate(operation, qubits, cbits=None, params=None, dagger=False, control_qubits=None, has_param=False, trainable=True, init_params=None)[source]¶
Add a gate to the circuit.
- Parameters:
operation – Gate name (e.g., “H”, “CNOT”, “RX”)
qubits – Target qubit(s) - can be int, Qubit, QRegSlice, or list
cbits – Classical bit(s) for measurement
params – Gate parameters
dagger – Whether to apply dagger (adjoint)
control_qubits – Control qubit(s)
has_param – If True, automatically create an
nn.Parameterfor this gate’s rotation angle(s). The created parameter is stored in_auto_paramsand registered inparam_map. Requires PyTorch.trainable – Whether the auto-created parameter is trainable (
requires_grad). Only used when has_param=True.init_params – Custom initial value(s) for the auto-created parameter. A scalar or list/tuple matching the gate’s num_params. Defaults to
Uniform(-π, π)(TorchQuantum convention). Only used when has_param=True.
- assign_parameters(values, *, inplace=False)[source]¶
Bind numeric values to symbolic parameters.
- Parameters:
values – Either a
dictmapping parameter -> value, or a boundParametersobject. Dict keys may be name strings ("theta","alpha_2"),Parameterobjects, sympySymbolobjects, or aParametersarray (paired with a sequence of values).inplace – If
Truemutate this circuit and return it; otherwise (default) return a new bound circuit, leaving self unchanged.
Partial binding is allowed — parameters absent from values remain symbolic. Fully-substituted parameters collapse to plain floats, so a fully-bound circuit can be simulated or submitted like any concrete circuit.
- Returns:
The bound circuit (new instance unless inplace).
- barrier(*qubits)[source]¶
Insert a barrier across the specified qubits.
- Parameters:
*qubits – Qubits to include in the barrier.
- bind_parameters(values, *, inplace=False)¶
Alias matching common quantum-SDK naming.
- cbit_num¶
- check_dynamic_program_closed()[source]¶
Raise if any
QIF/QWHILEblock is still open (missing a matchingendqif()/endqwhile()).Serializing or executing a circuit with unclosed blocks would only reflect however much of the branch/loop body has been built so far, silently hiding the incomplete construction — so both
_make_originir_circuit()and dynamic-program execution call this first.- Raises:
ValueError – If
self._dynamic_block_stackis non-empty.
- property circuit¶
Generate the circuit in OriginIR format.
- circuit_str¶
- cnot(controller, target)[source]¶
Apply CNOT (controlled-X) gate.
- Parameters:
controller – Control qubit - can be int, Qubit, or QRegSlice
target – Target qubit - can be int, Qubit, or QRegSlice
- control(*args)[source]¶
Return a context manager that wraps gates in a CONTROL block.
All gates added inside the
withblock will be executed only when all specified control qubits are in state|1>.- Parameters:
*args – One or more control qubits - can be int, Qubit, or QRegSlice
- Returns:
A
CircuitControlContextcontext manager.- Raises:
ValueError – No control qubits were supplied.
- copy()[source]¶
Return a deep copy of this circuit.
QRAM declarations, classical memory, and any structured dynamic program (mid-circuit MEASURE/RESET/QIF/QWHILE) are preserved. The dynamic program body is recursively cloned so mutating either circuit’s control-flow blocks after copying cannot affect the other.
- cp(control, target, lam)[source]¶
Apply controlled-phase gate (equivalent to CU1).
- Parameters:
control – Control qubit.
target – Target qubit.
lam – Phase angle in radians.
- creg(size)[source]¶
Declare the classical-register (CREG) size for this circuit.
CREG bits
c[0..size-1]are single bits written byMEASURE/ classical instructions and read byQIF/QWHILEconditions. Sets a floor on the CREG size; it also auto-grows to fit the largest classical bit referenced bymeasure_to()/ classical instructions.- Parameters:
size – Number of classical bits (must be non-negative).
- crx(control, target, theta)[source]¶
Apply controlled-RX gate.
- Parameters:
control – Control qubit.
target – Target qubit.
theta – Rotation angle in radians.
- cry(control, target, theta)[source]¶
Apply controlled-RY gate.
- Parameters:
control – Control qubit.
target – Target qubit.
theta – Rotation angle in radians.
- crz(control, target, theta)[source]¶
Apply controlled-RZ gate.
- Parameters:
control – Control qubit.
target – Target qubit.
theta – Rotation angle in radians.
- cswap(q1, q2, q3)[source]¶
Apply CSWAP (Fredkin) gate to three qubits.
- Parameters:
q1 – Control qubit - can be int, Qubit, or QRegSlice
q2 – First target qubit
q3 – Second target qubit
- cu(control, target, theta, phi, lam)[source]¶
Apply controlled-U3 gate.
- Parameters:
control – Control qubit.
target – Target qubit.
theta – Rotation angle in radians.
phi – Phi angle in radians.
lam – Lambda angle in radians.
- cx(controller, target)[source]¶
Apply CX gate (alias for CNOT).
- Parameters:
controller – Control qubit - can be int, Qubit, or QRegSlice
target – Target qubit - can be int, Qubit, or QRegSlice
- cz(q1, q2)[source]¶
Apply controlled-Z gate to two qubits.
- Parameters:
q1 – First qubit - can be int, Qubit, or QRegSlice
q2 – Second qubit - can be int, Qubit, or QRegSlice
- dagger()[source]¶
Return a context manager that wraps gates in a DAGGER block.
All gates added inside the
withblock will be conjugate-transposed (adjoint).- Returns:
A
CircuitDagContextcontext manager.
- property depth¶
Calculate the depth of the quantum circuit.
- endqif()[source]¶
Close the innermost open
QIFblock.- Raises:
ValueError – If there is no open
QIFblock.
- endqwhile()[source]¶
Close the innermost open
QWHILEblock.- Raises:
ValueError – If there is no open
QWHILEblock.
- property free_parameters¶
Sorted names of the unbound symbolic parameters in this circuit.
- classmethod from_originir(originir_str)[source]¶
Create a Circuit from an OriginIR(-ext) string.
Text using the classical / control-flow extension (mid-circuit
MEASURE/RESET,AND/OR/XOR/MOV/NOTinstructions, orQIF/QWHILEblocks) is parsed via the structured program parser; ordinary flat circuits (including QRAM/CONTROL/DAGGER) go through the original flat parser unchanged.- Parameters:
originir_str – OriginIR formatted circuit string.
- Returns:
A new Circuit instance.
- classmethod from_originir_ext(originir_ext_str)[source]¶
Create a Circuit from an OriginIR-ext string.
Equivalent to
from_originir()— both parse the same superset syntax. This alias makes the intent explicit when working with OriginIR-ext source.
- classmethod from_qasm(qasm_str)[source]¶
Create a Circuit from an OpenQASM 2.0 string.
- Parameters:
qasm_str – OpenQASM 2.0 formatted circuit string.
- Returns:
A new Circuit instance.
- get_matrix()[source]¶
Return the full unitary matrix of this circuit as
np.ndarray.Qubit 0 is treated as the least-significant bit of the statevector index. The returned matrix uses the convention
state_out = U @ state_inand gates are applied in the same order asopcode_list.- Raises:
NotMatrixableError – If the circuit contains MEASURE / CONTROL / DAGGER scope opcodes that have no unitary representation.
- get_param(opcode_idx)[source]¶
Get the tensor parameter registered for opcode_idx.
- Raises:
KeyError – If no tensor is registered for this opcode.
- get_params_by_gate(gate_name)[source]¶
Return auto-created parameters for gates named gate_name.
Example:
>>> c = Circuit(2) >>> c.ry(0, has_param=True) >>> c.ry(1, has_param=True) >>> c.rz(0, has_param=True) >>> len(c.get_params_by_gate("RY")) 2
- get_qreg(name)[source]¶
Get a named quantum register by name.
- Parameters:
name – Register name
- Returns:
QReg object
- Raises:
KeyError – If register name not found
- h(qn)[source]¶
Apply single-qubit Hadamard gate to qubit.
- Parameters:
qn – Target qubit - can be int, Qubit, or QRegSlice
- property has_param¶
TorchQuantum-aligned alias for
has_tensor_params().Returns
Trueonly when at least one parameter is a tensor (i.e., actually trainable). Pure Python-float parameters returnFalse.This is a no-argument property, distinct from the
has_paramkeyword argument onadd_gate()/ convenience gate methods (which opts-in to auto-creating annn.Parameterfor that gate).
- identity(qn)[source]¶
Apply the identity (no-op) gate to qubit.
- Parameters:
qn – Target qubit - can be int, Qubit, or QRegSlice
- property is_parametric¶
Trueif the circuit still contains unbound symbolic parameters.Such circuits serialize to OriginIR-ext (with a
PARAMheader) but cannot be simulated, exported to QASM/official OriginIR, or submitted to cloud backends until bound viaassign_parameters().
- iswap(q1, q2)[source]¶
Apply iSWAP gate to two qubits.
- Parameters:
q1 – First qubit - can be int, Qubit, or QRegSlice
q2 – Second qubit - can be int, Qubit, or QRegSlice
- max_qubit¶
- measure(*qubits)[source]¶
Schedule qubits for measurement.
Each qubit may be measured at most once per circuit. Calling
measure(0)and thenmeasure(0)again — or passing the same qubit twice in a single call (measure(0, 0)) — raisesValueError. This guards against the common mistake of usingmeasure(0, 1)to measure two qubits whencbitis meant to be implicit; use onemeasure(q)call per qubit instead, or pass distinct qubit indices.- Parameters:
*qubits – One or more qubits to measure — can be int, Qubit, or QRegSlice.
- Raises:
ValueError – Called inside an active CONTROL or DAGGER context block, or any qubit would be measured more than once.
- measure_list¶
- measure_to(qubit, cbit)[source]¶
Mid-circuit measurement of qubit into CREG bit cbit.
The qubit’s outcome is written to
c[cbit]for use in laterQIF/QWHILEconditions or classical instructions. Unlike the terminalmeasure(), the qubit stays live for further gates and this may be called insideQIF/QWHILEblocks.- Parameters:
qubit – The qubit to measure — int, Qubit, or QRegSlice (one qubit).
cbit – Destination CREG bit index.
- Raises:
ValueError – If qubit resolves to more than one qubit.
- opcode_list¶
- property originir¶
Generate the circuit in OriginIR format.
- property originir_official¶
Generate the circuit in strict official OriginIR format.
- p(qn, lam)[source]¶
Apply phase gate P(λ), equivalent to U1.
- Parameters:
qn – Target qubit - can be int, Qubit, or QRegSlice
lam – Phase angle in radians.
- property param_dict¶
The named parameter dictionary, if provided at construction.
- property params¶
All auto-created
nn.Parametertensors (flat list for optimizers).
- phase2q(q1, q2, theta1, theta2, thetazz)[source]¶
Apply two-qubit phase gate with local and ZZ terms.
- Parameters:
q1 – First qubit - can be int, Qubit, or QRegSlice
q2 – Second qubit - can be int, Qubit, or QRegSlice
theta1 – Local phase angle for q1 in radians.
theta2 – Local phase angle for q2 in radians.
thetazz – ZZ interaction angle in radians.
- property qasm¶
Generate the circuit in OpenQASM format.
- qelse()[source]¶
Open the
QELSEbranch of the innermost openQIFblock.- Raises:
ValueError – If there is no open
QIFblock awaitingQELSE.
- qif(cond)[source]¶
Open a
QIF <cond> ... [QELSE ...] ENDQIFblock.- Parameters:
cond – A condition string (see
uniqc.circuit_builder.classical_program.parse_cond()) or aCondinstance. Nonzero evaluates as true.
- qram_call(name, *qubits, control_qubits=None)[source]¶
Add a QRAM call to the circuit.
QRAM XOR-loads are self-inverse; when control_qubits is given, the load is applied only when every control qubit is
|1>(identity otherwise). Control qubits must be disjoint from the QRAM’s own address/data qubits.- Parameters:
name – Name of a previously declared QRAM.
*qubits – Qubit list (addr bits followed by data bits).
control_qubits – Optional control qubit(s) — can be int, Qubit, QRegSlice, or a list thereof. Merged with any enclosing
control()context block, same as ordinary gates.
- qram_declare(name, addr_size, data_size)[source]¶
Declare a QRAM with the given address and data sizes.
- Parameters:
name – Unique name for this QRAM.
addr_size – Number of address qubits.
data_size – Number of data qubits.
- property qregs¶
Return the named quantum registers.
- qubit_num¶
- qwhile(cond, max_iterations=None)[source]¶
Open a
QWHILE <cond> ... ENDQWHILEblock.- Parameters:
cond – A condition string or
Condinstance. Nonzero evaluates as true; re-evaluated before every iteration.max_iterations – Optional override of the internal iteration watchdog (defaults to
uniqc.circuit_builder.classical_program.DEFAULT_MAX_WHILE_ITERATIONS). This is a simulator safety cap, not part of the OriginIR-ext surface syntax.
- Raises:
ValueError – If max_iterations is not a positive integer.
- reset(qubit)[source]¶
Mid-circuit reset of qubit to
|0>.- Parameters:
qubit – The qubit to reset — int, Qubit, or QRegSlice (one qubit).
- Raises:
ValueError – If qubit resolves to more than one qubit.
- rphi(qn, theta=None, phi=None, *, has_param=False, trainable=True, init_params=None)[source]¶
Apply RPhi rotation gate.
- rx(qn, theta=None, *, has_param=False, trainable=True, init_params=None)[source]¶
Apply RX rotation gate.
- Parameters:
qn – Target qubit - can be int, Qubit, or QRegSlice
theta – Rotation angle in radians. Omit when has_param=True.
has_param – Auto-create an
nn.Parameterfor this gate.trainable – Whether the parameter is trainable (only with has_param).
init_params – Custom initial value. Default:
Uniform(-π, π).
- ry(qn, theta=None, *, has_param=False, trainable=True, init_params=None)[source]¶
Apply RY rotation gate.
- rz(qn, theta=None, *, has_param=False, trainable=True, init_params=None)[source]¶
Apply RZ rotation gate.
- s(qn)[source]¶
Apply S (phase) gate to qubit.
- Parameters:
qn – Target qubit - can be int, Qubit, or QRegSlice
- sdg(qn)[source]¶
Apply S-dagger (inverse phase) gate to qubit.
- Parameters:
qn – Target qubit - can be int, Qubit, or QRegSlice
- set_control(*args)[source]¶
Manually open a CONTROL block (low-level API; prefer
control()).- Parameters:
*args – Control qubits - can be int, Qubit, or QRegSlice
- set_param(opcode_idx, tensor)[source]¶
Register a differentiable tensor for the parametric gate at opcode_idx.
- Parameters:
opcode_idx – Index into
opcode_list.tensor – A
torch.Tensor(typically withrequires_grad=True).
- Raises:
IndexError – If opcode_idx is out of range.
- set_param_last(tensor)[source]¶
Register a tensor for the most recently added gate.
Convenience wrapper around
set_param()for the common pattern of registering a parameter immediately after adding a gate.- Returns:
The opcode index that was registered.
- Raises:
IndexError – If the circuit has no gates.
- swap(q1, q2)[source]¶
Apply SWAP gate to two qubits.
- Parameters:
q1 – First qubit - can be int, Qubit, or QRegSlice
q2 – Second qubit - can be int, Qubit, or QRegSlice
- sx(qn)[source]¶
Apply square-root-of-X (SX) gate to qubit.
- Parameters:
qn – Target qubit - can be int, Qubit, or QRegSlice
- sxdg(qn)[source]¶
Apply conjugate-transpose of SX gate to qubit.
- Parameters:
qn – Target qubit - can be int, Qubit, or QRegSlice
- t(qn)[source]¶
Apply T gate to qubit.
- Parameters:
qn – Target qubit - can be int, Qubit, or QRegSlice
- tdg(qn)[source]¶
Apply T-dagger (inverse T) gate to qubit.
- Parameters:
qn – Target qubit - can be int, Qubit, or QRegSlice
- property tensor_params¶
Return all registered tensor parameters (for passing to an optimizer).
- to_extended_originir()[source]¶
Export the circuit in extended OriginIR format (full form with QINIT/CREG/MEASURE).
- to_originir_official()[source]¶
Export the circuit as strict official OriginIR.
Extended gates are decomposed to the official gate set, and inline
dagger/controlled_bysyntax is replaced with block-levelDAGGER/CONTROLdelimiters. The output is suitable for submission to OriginQ cloud.
- to_pyqpanda3_circuit()[source]¶
Convert to a pyqpanda3
QProg.- Returns:
pyqpanda3 QProg equivalent of this circuit.
- Raises:
ImportError – If pyqpanda3 is not installed.
- to_qiskit_circuit()[source]¶
Convert to a
qiskit.QuantumCircuit.- Returns:
qiskit.QuantumCircuit equivalent of this circuit.
- Raises:
ImportError – If qiskit is not installed.
- toffoli(q1, q2, q3)[source]¶
Apply Toffoli (CCNOT) gate to three qubits.
- Parameters:
q1 – First control qubit
q2 – Second control qubit
q3 – Target qubit
- u1(qn, lam=None, *, has_param=False, trainable=True, init_params=None)[source]¶
Apply U1 single-parameter unitary gate.
- u2(qn, phi=None, lam=None, *, has_param=False, trainable=True, init_params=None)[source]¶
Apply U2 two-parameter unitary gate.
- u3(qn, theta=None, phi=None, lam=None, *, has_param=False, trainable=True, init_params=None)[source]¶
Apply U3 three-parameter unitary gate.
- used_qubit_list¶
- uu15(q1, q2, params)[source]¶
Apply general two-qubit UU15 gate with 15 parameters.
- Parameters:
q1 – First qubit - can be int, Qubit, or QRegSlice
q2 – Second qubit - can be int, Qubit, or QRegSlice
params – List of 15 rotation parameters in radians.
- x(qn)[source]¶
Apply Pauli-X (NOT) gate to qubit.
- Parameters:
qn – Target qubit - can be int, Qubit, or QRegSlice
- xx(q1, q2, theta=None, *, has_param=False, trainable=True, init_params=None)[source]¶
Apply XX Ising interaction gate.
- xy(q1, q2, theta)[source]¶
Apply XY Ising interaction gate.
- Parameters:
q1 – First qubit - can be int, Qubit, or QRegSlice
q2 – Second qubit - can be int, Qubit, or QRegSlice
theta – Interaction angle in radians.
- y(qn)[source]¶
Apply Pauli-Y gate to qubit.
- Parameters:
qn – Target qubit - can be int, Qubit, or QRegSlice
- yy(q1, q2, theta=None, *, has_param=False, trainable=True, init_params=None)[source]¶
Apply YY Ising interaction gate.