Skip to content

Commit 188b663

Browse files
authored
fix QPE test failure, add non-slow bloq example autotest (#1487)
* fix QPE test failure, add non-slow bloq example autotest * fix bug: `cirq.ControlledGate` fails when it can't detect that bloq is unitary * regen notebook * add comment on controlled unitary failure
1 parent 7497989 commit 188b663

5 files changed

Lines changed: 54 additions & 8 deletions

File tree

qualtran/_infra/controlled.py

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -458,9 +458,19 @@ def _unitary_(self):
458458
# subbloq is a cirq gate, use the cirq-style API to derive a unitary.
459459
import cirq
460460

461-
return cirq.unitary(
462-
cirq.ControlledGate(self.subbloq, control_values=self.ctrl_spec.to_cirq_cv())
463-
)
461+
# TODO It would be ideal to use `tensor_contract` always,
462+
# but at the moment it's about 5-10x slower than `cirq.unitary`.
463+
# So we default to `cirq.unitary`, and only use `tensor_contract` if it fails.
464+
# https://github.com/quantumlib/Qualtran/issues/1336
465+
# TODO `cirq.ControlledGate` fails to correctly verify `subbloq` using
466+
# a compute-uncompute `And` pair is unitary.
467+
# https://github.com/quantumlib/Qualtran/issues/1488
468+
try:
469+
return cirq.unitary(
470+
cirq.ControlledGate(self.subbloq, control_values=self.ctrl_spec.to_cirq_cv())
471+
)
472+
except ValueError:
473+
pass # use the tensor contraction instead
464474
if all(reg.side == Side.THRU for reg in self.subbloq.signature):
465475
# subbloq has only THRU registers, so the tensor contraction corresponds
466476
# to a unitary matrix.

qualtran/bloqs/phase_estimation/qubitization_qpe.ipynb

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,6 @@
6161
"\n",
6262
"#### Parameters\n",
6363
" - `walk`: Bloq representing the Qubitization walk operator to run the phase estimation protocol on.\n",
64-
" - `m_bits`: Bitsize of the phase register to be used during phase estimation.\n",
6564
" - `ctrl_state_prep`: Bloq to prepare the control state on the phase register. Defaults to `OnEach(self.m_bits, Hadamard())`.\n",
6665
" - `qft_inv`: Bloq to apply inverse QFT on the phase register. Defaults to `QFTTextBook(self.m_bits).adjoint()` \n",
6766
"\n",
@@ -193,6 +192,22 @@
193192
")"
194193
]
195194
},
195+
{
196+
"cell_type": "code",
197+
"execution_count": null,
198+
"id": "49743657",
199+
"metadata": {
200+
"cq.autogen": "QubitizationQPE.qubitization_qpe_ising"
201+
},
202+
"outputs": [],
203+
"source": [
204+
"from qualtran.bloqs.chemistry.ising.walk_operator import get_walk_operator_for_1d_ising_model\n",
205+
"from qualtran.bloqs.phase_estimation import RectangularWindowState\n",
206+
"\n",
207+
"walk, _ = get_walk_operator_for_1d_ising_model(4, 0.1)\n",
208+
"qubitization_qpe_ising = QubitizationQPE(walk, RectangularWindowState(4))"
209+
]
210+
},
196211
{
197212
"cell_type": "markdown",
198213
"id": "b19f9365",
@@ -213,8 +228,8 @@
213228
"outputs": [],
214229
"source": [
215230
"from qualtran.drawing import show_bloqs\n",
216-
"show_bloqs([qubitization_qpe_hubbard_model_small, qubitization_qpe_sparse_chem, qubitization_qpe_chem_thc],\n",
217-
" ['`qubitization_qpe_hubbard_model_small`', '`qubitization_qpe_sparse_chem`', '`qubitization_qpe_chem_thc`'])"
231+
"show_bloqs([qubitization_qpe_hubbard_model_small, qubitization_qpe_sparse_chem, qubitization_qpe_chem_thc, qubitization_qpe_ising],\n",
232+
" ['`qubitization_qpe_hubbard_model_small`', '`qubitization_qpe_sparse_chem`', '`qubitization_qpe_chem_thc`', '`qubitization_qpe_ising`'])"
218233
]
219234
},
220235
{

qualtran/bloqs/phase_estimation/qubitization_qpe.py

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,6 @@ class QubitizationQPE(GateWithRegisters):
6464
Args:
6565
walk: Bloq representing the Qubitization walk operator to run the phase estimation protocol
6666
on.
67-
m_bits: Bitsize of the phase register to be used during phase estimation.
6867
ctrl_state_prep: Bloq to prepare the control state on the phase register. Defaults to
6968
`OnEach(self.m_bits, Hadamard())`.
7069
qft_inv: Bloq to apply inverse QFT on the phase register. Defaults to
@@ -119,7 +118,7 @@ def decompose_from_registers(
119118
qpre_reg = quregs['qpe_reg']
120119

121120
yield self.ctrl_state_prep.on(*qpre_reg)
122-
yield walk_controlled.on_registers(**walk_regs, control=qpre_reg[-1])
121+
yield walk_controlled.on_registers(**walk_regs, ctrl=qpre_reg[-1])
123122
walk = self.walk**2
124123
for i in range(self.m_bits - 2, -1, -1):
125124
yield reflect_controlled.on_registers(control=qpre_reg[i], **reflect_regs)
@@ -143,6 +142,16 @@ def __str__(self) -> str:
143142
return f'QubitizationQPE[{self.m_bits}]'
144143

145144

145+
@bloq_example
146+
def _qubitization_qpe_ising() -> QubitizationQPE:
147+
from qualtran.bloqs.chemistry.ising.walk_operator import get_walk_operator_for_1d_ising_model
148+
from qualtran.bloqs.phase_estimation import RectangularWindowState
149+
150+
walk, _ = get_walk_operator_for_1d_ising_model(4, 0.1)
151+
qubitization_qpe_ising = QubitizationQPE(walk, RectangularWindowState(4))
152+
return qubitization_qpe_ising
153+
154+
146155
@bloq_example
147156
def _qubitization_qpe_hubbard_model_small() -> QubitizationQPE:
148157
import numpy as np
@@ -252,5 +261,6 @@ def _qubitization_qpe_sparse_chem() -> QubitizationQPE:
252261
_qubitization_qpe_hubbard_model_small,
253262
_qubitization_qpe_sparse_chem,
254263
_qubitization_qpe_chem_thc,
264+
_qubitization_qpe_ising,
255265
),
256266
)

qualtran/bloqs/phase_estimation/qubitization_qpe_test.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
from qualtran.bloqs.phase_estimation.qubitization_qpe import (
2222
_qubitization_qpe_chem_thc,
2323
_qubitization_qpe_hubbard_model_small,
24+
_qubitization_qpe_ising,
2425
_qubitization_qpe_sparse_chem,
2526
QubitizationQPE,
2627
)
@@ -29,6 +30,10 @@
2930
from qualtran.testing import execute_notebook
3031

3132

33+
def test_ising_example(bloq_autotester):
34+
bloq_autotester(_qubitization_qpe_ising)
35+
36+
3237
@pytest.mark.slow
3338
def test_qubitization_qpe_bloq_autotester(bloq_autotester):
3439
bloq_autotester(_qubitization_qpe_hubbard_model_small)
@@ -103,3 +108,8 @@ def test_qubitization_phase_estimation_of_walk(num_terms: int, use_resource_stat
103108
@pytest.mark.notebook
104109
def test_phase_estimation_of_qubitized_hubbard_model():
105110
execute_notebook('phase_estimation_of_quantum_walk')
111+
112+
113+
@pytest.mark.notebook
114+
def test_notebook():
115+
execute_notebook('qubitization_qpe')

qualtran/conftest.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ def assert_bloq_example_serializes_for_pytest(bloq_ex: BloqExample):
8888
'qubitization_qpe_chem_thc', # too slow
8989
'walk_op_chem_sparse',
9090
'qubitization_qpe_sparse_chem', # too slow
91+
'qubitization_qpe_ising',
9192
'trott_unitary',
9293
'symbolic_hamsim_by_gqsp',
9394
'gf16_addition', # cannot serialize QGF

0 commit comments

Comments
 (0)