Skip to content

Commit 433a288

Browse files
Simplify cbloq.to_cirq_circuit() with sensible defaults and add cbloq.to_cirq_circuit_and_quregs() (#927)
* Simplify cbloq.to_cirq_circuit() with sensible defaults and add cbloq.to_cirq_circuit_and_quregs * Update call sites to use to_cirq_circuit * Fix tests and mypy * Fix another typo --------- Co-authored-by: Matthew Harrigan <mpharrigan@google.com>
1 parent 1b8b449 commit 433a288

18 files changed

Lines changed: 92 additions & 60 deletions

qualtran/_infra/composite_bloq.py

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,6 @@
4949
import cirq
5050

5151
from qualtran.cirq_interop._cirq_to_bloq import CirqQuregInT, CirqQuregT
52-
from qualtran.cirq_interop.t_complexity_protocol import TComplexity
5352
from qualtran.resource_counting import BloqCountT, SympySymbolAllocator
5453
from qualtran.simulation.classical_sim import ClassicalValT
5554

@@ -139,16 +138,19 @@ def as_cirq_op(
139138
"""Return a cirq.CircuitOperation containing a cirq-exported version of this cbloq."""
140139
import cirq
141140

142-
circuit, out_quregs = self.to_cirq_circuit(qubit_manager=qubit_manager, **cirq_quregs)
141+
circuit, out_quregs = self.to_cirq_circuit_and_quregs(
142+
qubit_manager=qubit_manager, cirq_quregs=cirq_quregs
143+
)
143144
return cirq.CircuitOperation(circuit), out_quregs
144145

145-
def to_cirq_circuit(
146-
self, qubit_manager: Optional['cirq.QubitManager'] = None, **cirq_quregs: 'CirqQuregInT'
146+
def to_cirq_circuit_and_quregs(
147+
self, qubit_manager: Optional['cirq.QubitManager'] = None, **cirq_quregs
147148
) -> Tuple['cirq.FrozenCircuit', Dict[str, 'CirqQuregT']]:
148-
"""Convert this CompositeBloq to a `cirq.Circuit`.
149+
"""Convert this CompositeBloq to a `cirq.Circuit` and output qubit registers.
149150
150151
Args:
151-
qubit_manager: A `cirq.QubitManager` to allocate new qubits.
152+
qubit_manager: A `cirq.QubitManager` to allocate new qubits. If not provided,
153+
uses `cirq.SimpleQubitManager()` by default.
152154
**cirq_quregs: Mapping from left register names to Cirq qubit arrays.
153155
154156
Returns:
@@ -166,6 +168,30 @@ def to_cirq_circuit(
166168
self.signature, cirq_quregs, self._binst_graph, qubit_manager=qubit_manager
167169
)
168170

171+
def to_cirq_circuit(
172+
self,
173+
*,
174+
qubit_manager: Optional['cirq.QubitManager'] = None,
175+
cirq_quregs: Optional[Mapping[str, 'CirqQuregInT']] = None,
176+
) -> 'cirq.FrozenCircuit':
177+
"""Convert this CompositeBloq to a `cirq.Circuit`.
178+
179+
Args:
180+
qubit_manager: A `cirq.QubitManager` to allocate new qubits. If not provided,
181+
uses `cirq.SimpleQubitManager()` by default.
182+
cirq_quregs: Mapping from left register names to Cirq qubit arrays. If not provided,
183+
uses `get_named_qubits(self.signature.lefts())` by default.
184+
185+
Returns:
186+
circuit: The cirq.FrozenCircuit version of this composite bloq.
187+
"""
188+
from qualtran._infra.gate_with_registers import get_named_qubits
189+
190+
if cirq_quregs is None:
191+
cirq_quregs = get_named_qubits(self.signature.lefts())
192+
193+
return self.to_cirq_circuit_and_quregs(qubit_manager=qubit_manager, **cirq_quregs)[0]
194+
169195
@classmethod
170196
def from_cirq_circuit(cls, circuit: 'cirq.Circuit') -> 'CompositeBloq':
171197
"""Construct a composite bloq from a Cirq circuit.

qualtran/_infra/composite_bloq_test.py

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,6 @@
4040
)
4141
from qualtran._infra.composite_bloq import _create_binst_graph, _get_dangling_soquets
4242
from qualtran._infra.data_types import BoundedQUInt, QAny, QBit, QFxp, QUInt
43-
from qualtran._infra.gate_with_registers import get_named_qubits
4443
from qualtran.bloqs.basic_gates import CNOT, IntEffect, ZeroEffect
4544
from qualtran.bloqs.for_testing.atom import TestAtom, TestTwoBitOp
4645
from qualtran.bloqs.for_testing.many_registers import TestMultiTypedRegister, TestQFxp
@@ -164,7 +163,9 @@ def test_map_soqs():
164163

165164
def test_bb_composite_bloq():
166165
cbloq_auto = TestTwoCNOT().decompose_bloq()
167-
circuit, _ = cbloq_auto.to_cirq_circuit(q1=[cirq.LineQubit(1)], q2=[cirq.LineQubit(2)])
166+
circuit, _ = cbloq_auto.to_cirq_circuit_and_quregs(
167+
q1=[cirq.LineQubit(1)], q2=[cirq.LineQubit(2)]
168+
)
168169
cirq.testing.assert_has_diagram(
169170
circuit,
170171
desired="""\
@@ -174,6 +175,16 @@ def test_bb_composite_bloq():
174175
""",
175176
)
176177

178+
circuit = cbloq_auto.to_cirq_circuit()
179+
cirq.testing.assert_has_diagram(
180+
circuit,
181+
desired="""\
182+
q1: ───@───X───
183+
│ │
184+
q2: ───X───@───
185+
""",
186+
)
187+
177188

178189
def test_bloq_builder():
179190
signature = Signature.build(x=1, y=1)
@@ -344,7 +355,7 @@ def test_complicated_target_register():
344355
# note: this includes the two `Dangling` generations.
345356
assert len(list(nx.topological_generations(binst_graph))) == 2 * 3 + 2
346357

347-
circuit, _ = cbloq.to_cirq_circuit(None, **get_named_qubits(bloq.signature.lefts()))
358+
circuit = cbloq.to_cirq_circuit()
348359
cirq.testing.assert_has_diagram(
349360
circuit,
350361
"""\

qualtran/_infra/controlled_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ def test_ctrl_bloq_as_cirq_op():
100100

101101
def _test_cirq_equivalence(bloq: Bloq, gate: cirq.Gate):
102102
left_quregs = get_named_qubits(bloq.signature.lefts())
103-
circuit1, right_quregs = bloq.as_composite_bloq().to_cirq_circuit(None, **left_quregs)
103+
circuit1 = bloq.as_composite_bloq().to_cirq_circuit(cirq_quregs=left_quregs)
104104
circuit2 = cirq.Circuit(
105105
gate.on(*merge_qubits(bloq.signature, **get_named_qubits(bloq.signature)))
106106
)
@@ -124,7 +124,7 @@ def _test_cirq_equivalence(bloq: Bloq, gate: cirq.Gate):
124124
bloq = Controlled(Swap(5), CtrlSpec(qdtypes=QUInt(4), cvs=0b0101))
125125
quregs = get_named_qubits(bloq.signature)
126126
ctrl, x, y = quregs['ctrl'], quregs['x'], quregs['y']
127-
circuit1, _ = bloq.decompose_bloq().to_cirq_circuit(None, **quregs)
127+
circuit1 = bloq.decompose_bloq().to_cirq_circuit(cirq_quregs=quregs)
128128
circuit2 = cirq.Circuit(
129129
cirq.SWAP(x[i], y[i]).controlled_by(*ctrl, control_values=[0, 1, 0, 1]) for i in range(5)
130130
)

qualtran/bloqs/basic_gates/hadamard_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ def test_to_cirq():
2525
q = bb.add(OneState())
2626
q = bb.add(Hadamard(), q=q)
2727
cbloq = bb.finalize(q=q)
28-
circuit, _ = cbloq.to_cirq_circuit()
28+
circuit = cbloq.to_cirq_circuit()
2929
cirq.testing.assert_has_diagram(circuit, "_c(0): ───X───H───")
3030
vec1 = cbloq.tensor_contract()
3131
vec2 = cirq.final_state_vector(circuit)

qualtran/bloqs/basic_gates/s_gate_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ def test_to_cirq():
3333
q = bb.add(PlusState())
3434
q = bb.add(SGate(), q=q)
3535
cbloq = bb.finalize(q=q)
36-
circuit, _ = cbloq.to_cirq_circuit()
36+
circuit = cbloq.to_cirq_circuit()
3737
cirq.testing.assert_has_diagram(circuit, "_c(0): ───H───S───")
3838

3939

qualtran/bloqs/basic_gates/states_and_effects.ipynb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,7 @@
10371037
"outputs": [],
10381038
"source": [
10391039
"from cirq.contrib.svg import SVGCircuit\n",
1040-
"circuit, qubits = cbloq.to_cirq_circuit()\n",
1040+
"circuit = cbloq.to_cirq_circuit()\n",
10411041
"SVGCircuit(circuit)"
10421042
]
10431043
}

qualtran/bloqs/basic_gates/swap_test.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,9 @@ def test_two_bit_swap_unitary_vs_cirq():
6565
def test_two_bit_swap_as_cirq_op():
6666
q = cirq.LineQubit.range(2)
6767
expected_circuit = cirq.Circuit(cirq.SWAP(*q))
68-
cbloq_to_circuit, quregs = TwoBitSwap().as_composite_bloq().to_cirq_circuit(x=[q[0]], y=[q[1]])
68+
cbloq_to_circuit = (
69+
TwoBitSwap().as_composite_bloq().to_cirq_circuit(cirq_quregs={'x': [q[0]], 'y': [q[1]]})
70+
)
6971
cirq.testing.assert_same_circuits(expected_circuit, cbloq_to_circuit)
7072

7173

qualtran/bloqs/basic_gates/t_gate_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def test_to_cirq():
3939
q = bb.add(TGate(), q=q)
4040
q = bb.add(TGate(is_adjoint=True), q=q)
4141
cbloq = bb.finalize(q=q)
42-
circuit, _ = cbloq.to_cirq_circuit()
42+
circuit = cbloq.to_cirq_circuit()
4343
cirq.testing.assert_has_diagram(circuit, "_c(0): ───H───T───T^-1───")
4444

4545

qualtran/bloqs/basic_gates/toffoli_test.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ def test_toffoli_cirq():
4242
ctrl, target = bb.add(Toffoli(), ctrl=ctrl, target=target)
4343
cbloq = bb.finalize(q0=ctrl[0], q1=ctrl[1], q2=target)
4444

45-
circuit, qubits = cbloq.to_cirq_circuit()
45+
circuit, qubits = cbloq.to_cirq_circuit_and_quregs()
4646
cirq.testing.assert_has_diagram(
4747
circuit,
4848
"""\

qualtran/bloqs/basic_gates/x_basis_test.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ def test_to_cirq():
6262
q = bb.add(PlusState())
6363
q = bb.add(XGate(), q=q)
6464
cbloq = bb.finalize(q=q)
65-
circuit, _ = cbloq.to_cirq_circuit()
65+
circuit = cbloq.to_cirq_circuit()
6666
cirq.testing.assert_has_diagram(circuit, "_c(0): ───H───X───")
6767
vec1 = cbloq.tensor_contract()
6868
vec2 = cirq.final_state_vector(circuit)
@@ -72,7 +72,7 @@ def test_to_cirq():
7272
q = bb.add(MinusState())
7373
q = bb.add(XGate(), q=q)
7474
cbloq = bb.finalize(q=q)
75-
circuit, _ = cbloq.to_cirq_circuit()
75+
circuit = cbloq.to_cirq_circuit()
7676
cirq.testing.assert_has_diagram(circuit, "_c(0): ───[ _c(0): ───X───H─── ]───X───")
7777
vec1 = cbloq.tensor_contract()
7878
vec2 = cirq.final_state_vector(circuit)

0 commit comments

Comments
 (0)