uniqc.compile.decompose module

IR-level decomposition of OriginIR-native gates to QASM 2.0 stdlib gates.

Some OriginIR opcodes (RPhi, RPhi90, RPhi180, PHASE2Q, UU15) have no corresponding name in the OpenQASM 2.0 standard library (qelib1.inc). Circuit.qasm works around this by inlining gate ... { ... } definitions from uniqc.circuit_builder.translate_qasm2_oir.QASM2_CUSTOM_GATE_DEFS, but the cloud parsers used by Quafu / QuarkStudio / IBM frequently reject QASM source that depends on such custom gate blocks.

This module rewrites those opcodes into mathematically-equivalent sequences of gates that are in qelib1.inc:

OriginIR gate

Replacement (OriginIR opcode names, equivalent up to global phase)

RPhi

RZ(-phi); RX(theta); RZ(phi)

RPhi90

RZ(-phi); RX(pi/2); RZ(phi)

RPhi180

RZ(-phi); RX(pi); RZ(phi)

PHASE2Q

U1(t1) q1; U1(t2) q2; CU1(tzz) (q1->q2) (CU1 is emitted as U1 with control_qubits=[q1])

UU15

U3 a; U3 b; XX; YY; ZZ; U3 a; U3 b (KAK form)

This is a lightweight, qiskit-free pre-processing pass. It runs before uniqc.compile.compile_for_backend() so that subsequent basis-gate and topology compilation can take over.

The decomposition preserves the dagger flag by reversing the replacement sequence and negating angle parameters where appropriate. Gate instances wrapped with control_qubits are not currently decomposed; doing so requires lifting each replacement gate to its controlled form, which is out of scope for this pass — call compile() explicitly first if you need that.

uniqc.compile.decompose.decompose_for_qasm2(circuit)[source]

Return a new Circuit with QASM2-unrepresentable gates rewritten.

The original circuit is not mutated. When the input contains no gate in QASM2_UNREPRESENTABLE_GATES, this returns a shallow copy.

Examples

>>> from uniqc.circuit_builder import Circuit
>>> c = Circuit(2)
>>> c.rphi(0, 0.4, 0.7)
>>> c.add_gate("PHASE2Q", [0, 1], params=[0.1, 0.2, 0.3])
>>> c2 = decompose_for_qasm2(c)
>>> {op[0] for op in c2.opcode_list}.isdisjoint({"RPhi", "PHASE2Q"})
True
Parameters:

circuit (Circuit)

Return type:

Circuit

uniqc.compile.decompose.decompose_opcode_for_qasm2(op)[source]

Return replacement opcodes for op if it is QASM2-unrepresentable.

Returns [op] unchanged when op is already a QASM2-friendly opcode. Raises NotImplementedError when the gate is in QASM2_UNREPRESENTABLE_GATES but is wrapped with control_qubits (controlled-RPhi / controlled-UU15 etc. require a more general lift that this lightweight pass does not provide).

Parameters:

op (tuple[str, int | list[int], int | list[int] | None, float | list[float] | tuple[float, ...] | None, bool, int | list[int]])

Return type:

list[tuple[str, int | list[int], int | list[int] | None, float | list[float] | tuple[float, …] | None, bool, int | list[int]]]