Skip to content

Commit ae5d61d

Browse files
committed
stuff
1 parent 09a2860 commit ae5d61d

17 files changed

Lines changed: 96 additions & 94 deletions

.github/workflows/nightly.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,4 @@ jobs:
4343
pip install -r dev_tools/requirements/envs/pytest.env.txt
4444
pip install --no-deps -e .
4545
- run: |
46-
check/pytest
46+
check/pytest --durations=10

qualtran/_infra/composite_bloq.py

Lines changed: 40 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -397,11 +397,12 @@ def flatten_once(
397397
# pylint: disable=protected-access
398398
bb._i = max(binst.i for binst in self.bloq_instances) + 1
399399

400-
soq_map: List[Tuple[SoquetT, SoquetT]] = []
400+
# soq_map: List[Tuple[SoquetT, SoquetT]] = []
401+
flat_soq_map: Dict[Soquet, Soquet] = {}
401402
new_out_soqs: Tuple[SoquetT, ...]
402403
did_work = False
403404
for binst, in_soqs, old_out_soqs in self.iter_bloqsoqs():
404-
in_soqs = _map_soqs(in_soqs, soq_map) # update `in_soqs` from old to new.
405+
in_soqs = _map_flat_soqs(in_soqs, flat_soq_map) # update `in_soqs` from old to new.
405406
if pred(binst):
406407
try:
407408
new_out_soqs = bb.add_from(binst.bloq, **in_soqs)
@@ -416,12 +417,13 @@ def flatten_once(
416417
# pylint: disable=protected-access
417418
new_out_soqs = tuple(soq for _, soq in bb._add_binst(binst, in_soqs=in_soqs))
418419

419-
soq_map.extend(zip(old_out_soqs, new_out_soqs))
420+
_update_flat_soq_map(zip(old_out_soqs, new_out_soqs), flat_soq_map)
421+
# soq_map.extend(zip(old_out_soqs, new_out_soqs))
420422

421423
if not did_work:
422424
raise DidNotFlattenAnythingError()
423425

424-
fsoqs = _map_soqs(self.final_soqs(), soq_map)
426+
fsoqs = _map_flat_soqs(self.final_soqs(), flat_soq_map)
425427
return bb.finalize(**fsoqs)
426428

427429
def flatten(
@@ -865,6 +867,40 @@ def _map_soqs(soqs: SoquetT) -> SoquetT:
865867
return {name: _map_soqs(soqs) for name, soqs in soqs.items()}
866868

867869

870+
def _map_flat_soqs(
871+
soqs: Dict[str, SoquetT], flat_soq_map: Dict[Soquet, Soquet]
872+
) -> Dict[str, SoquetT]:
873+
874+
# use vectorize to use the flat mapping.
875+
def _map_soq(soq: Soquet) -> Soquet:
876+
# Helper function to map an individual soquet.
877+
return flat_soq_map.get(soq, soq)
878+
879+
# Use `vectorize` to call `_map_soq` on each element of the array.
880+
vmap = np.vectorize(_map_soq, otypes=[object])
881+
882+
def _map_soqs(soqs: SoquetT) -> SoquetT:
883+
if isinstance(soqs, Soquet):
884+
return _map_soq(soqs)
885+
return vmap(soqs)
886+
887+
return {name: _map_soqs(soqs) for name, soqs in soqs.items()}
888+
889+
890+
def _update_flat_soq_map(soq_map: Iterable[Tuple[SoquetT, SoquetT]], flat_soq_map):
891+
for old_soqs, new_soqs in soq_map:
892+
if isinstance(old_soqs, Soquet):
893+
assert isinstance(new_soqs, Soquet), new_soqs
894+
flat_soq_map[old_soqs] = new_soqs
895+
continue
896+
897+
assert isinstance(old_soqs, np.ndarray), old_soqs
898+
assert isinstance(new_soqs, np.ndarray), new_soqs
899+
assert old_soqs.shape == new_soqs.shape, (old_soqs.shape, new_soqs.shape)
900+
for o, n in zip(old_soqs.reshape(-1), new_soqs.reshape(-1)):
901+
flat_soq_map[o] = n
902+
903+
868904
class BloqBuilder:
869905
"""A builder class for composing bloqs.
870906

qualtran/_infra/gate_with_registers.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -508,13 +508,6 @@ def controlled(
508508
return controlled_bloq
509509

510510
def _unitary_(self):
511-
if all(reg.side == Side.THRU for reg in self.signature):
512-
try:
513-
tensor = self.tensor_contract()
514-
assert tensor.ndim == 2, "All registers should have been checked to be THRU."
515-
return tensor
516-
except (DecomposeNotImplementedError, DecomposeTypeError, NotImplementedError):
517-
return NotImplemented
518511
return NotImplemented
519512

520513
def my_tensors(

qualtran/_infra/quantum_graph.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,9 @@ def bloq_is(self, t) -> bool:
4343
`Union[BloqInstance, DanglingT]`"""
4444
return isinstance(self.bloq, t)
4545

46+
def __hash__(self):
47+
return hash(self.i)
48+
4649

4750
class DanglingT:
4851
"""The type of the singleton objects `LeftDangle` and `RightDangle`.

qualtran/bloqs/block_encoding/block_encoding_base.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,6 @@ def signal_state(self) -> BlackBoxPrepare:
9595
r"""Returns the signal / ancilla flag state $|G\rangle."""
9696

9797

98-
9998
_BLOCK_ENCODING_DOC = BloqDocSpec(
10099
bloq_cls=BlockEncoding, examples=[] # type: ignore[type-abstract]
101100
)

qualtran/bloqs/chemistry/hubbard_model/qubitization/select_hubbard_test.py

Lines changed: 7 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -73,20 +73,13 @@ def test_hubbard_majoranna_small(bloq_autotester):
7373
bloq_autotester(_hubb_majoranna_small)
7474

7575

76-
def test_hubb_majoranna_bloq_counts():
77-
for n in [2, 3, 10, 11]:
78-
bloq = HubbardMajorannaOperator(x_dim=n, y_dim=n, control_val=None)
79-
qlt_testing.assert_equivalent_bloq_counts(
80-
bloq,
81-
generalizer=[ignore_cliffords, ignore_alloc_free, ignore_split_join, generalize_cvs],
82-
)
83-
84-
for n in [2, 3, 10, 11]:
85-
bloq = HubbardMajorannaOperator(x_dim=n, y_dim=n, control_val=1)
86-
qlt_testing.assert_equivalent_bloq_counts(
87-
bloq,
88-
generalizer=[ignore_cliffords, ignore_alloc_free, ignore_split_join, generalize_cvs],
89-
)
76+
@pytest.mark.parametrize('n', [2, 3, 10, 11])
77+
@pytest.mark.parametrize('cv', [None, 1])
78+
def test_hubb_majoranna_bloq_counts(cv, n):
79+
bloq = HubbardMajorannaOperator(x_dim=n, y_dim=n, control_val=cv)
80+
qlt_testing.assert_equivalent_bloq_counts(
81+
bloq, generalizer=[ignore_cliffords, ignore_alloc_free, ignore_split_join, generalize_cvs]
82+
)
9083

9184

9285
def test_hubbard_spin_up_z_symb(bloq_autotester):

qualtran/bloqs/hamiltonian_simulation/hamiltonian_simulation_by_gqsp_test.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,8 +79,9 @@ def verify_hamiltonian_simulation_by_gqsp(
7979
N = H.shape[0]
8080

8181
W_e_iHt = HamiltonianSimulationByGQSP(W, t=t, precision=precision)
82-
# TODO This cirq.unitary call is 4-5x faster than tensor_contract.
82+
# TODO cirq.unitary was 4-5x faster than tensor_contract.
8383
# https://github.com/quantumlib/Qualtran/issues/1336
84+
# TODO: note performance regression
8485
result_unitary = cirq.unitary(BloqAsCirqGate(W_e_iHt))
8586

8687
expected_top_left = scipy.linalg.expm(-1j * H * t)
@@ -95,6 +96,7 @@ def verify_hamiltonian_simulation_by_gqsp(
9596
def test_hamiltonian_simulation_by_gqsp(
9697
select_bitsize: int, target_bitsize: int, t: float, precision: float
9798
):
99+
# TODO: this is slow again
98100
random_state = np.random.RandomState(42)
99101

100102
for _ in range(5):

qualtran/bloqs/phase_estimation/qubitization_qpe_test.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,8 +72,9 @@ def test_qubitization_qpe_sparse_chem_bloq_autotester(bloq_autotester):
7272
)
7373
@pytest.mark.parametrize('use_resource_state', [True, False])
7474
def test_qubitization_phase_estimation_of_walk(num_terms: int, use_resource_state: bool):
75-
if num_terms >= 2:
76-
return pytest.xfail("Cirq regression") # TODO: Github Issue
75+
# TODO: This is slow.
76+
# if num_terms >= 2:
77+
# return pytest.xfail("Cirq regression") # TODO: Github Issue
7778

7879
precision, eps = 5, 0.05
7980
ham, walk = get_uniform_pauli_qubitized_walk(num_terms)

qualtran/bloqs/phase_estimation/text_book_qpe_test.py

Lines changed: 19 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,7 @@ def test_textbook_phase_estimation_zpow_theta(theta):
5353
)
5454
@pytest.mark.parametrize('use_resource_state', [True, False])
5555
def test_textbook_phase_estimation_qubitized_walk(num_terms: int, use_resource_state: bool):
56+
# TODO: broken
5657
precision, eps = 5, 0.05
5758
ham, walk = get_uniform_pauli_qubitized_walk(num_terms)
5859

@@ -74,27 +75,23 @@ def test_textbook_phase_estimation_qubitized_walk(num_terms: int, use_resource_s
7475
# TODO cirq simulation seems to fail for controlled `QubitizationWalkOperator`.
7576
# the following code decomposes a few levels till it gets only simulable bloqs.
7677
# https://github.com/quantumlib/Qualtran/issues/1495
77-
# def should_decompose(binst):
78-
# from qualtran import Adjoint, Controlled
79-
# from qualtran.bloqs.basic_gates import Power
80-
# from qualtran.bloqs.qubitization import QubitizationWalkOperator
81-
# from qualtran.bloqs.block_encoding import SelectBlockEncoding
82-
#
83-
# bloqs_to_decompose = (TextbookQPE, QubitizationWalkOperator, Power, SelectBlockEncoding)
84-
#
85-
# if binst.bloq_is(bloqs_to_decompose):
86-
# return True
87-
#
88-
# if binst.bloq_is(Controlled) or binst.bloq_is(Adjoint):
89-
# return isinstance(binst.bloq.subbloq, bloqs_to_decompose)
90-
#
91-
# return False
92-
93-
cbloq = qpe_bloq.as_composite_bloq().flatten()
94-
95-
96-
97-
quregs = get_named_qubits(qpe_bloq.signature.lefts())
78+
def should_decompose(binst):
79+
from qualtran import Adjoint, Controlled
80+
from qualtran.bloqs.basic_gates import Power
81+
from qualtran.bloqs.qubitization import QubitizationWalkOperator
82+
83+
bloqs_to_decompose = (TextbookQPE, QubitizationWalkOperator, Power)
84+
85+
if binst.bloq_is(bloqs_to_decompose):
86+
return True
87+
88+
if binst.bloq_is(Controlled) or binst.bloq_is(Adjoint):
89+
return isinstance(binst.bloq.subbloq, bloqs_to_decompose)
90+
91+
return False
92+
93+
cbloq = qpe_bloq.as_composite_bloq().flatten(pred=should_decompose)
94+
quregs = get_named_qubits(cbloq.signature.lefts())
9895
qpe_circuit, quregs = cbloq.to_cirq_circuit_and_quregs(None, **quregs)
9996
for eig_idx, eig_val in enumerate(eigen_values):
10097
# Apply QPE to determine eigenvalue for walk operator W on initial state |L>|k>
@@ -107,7 +104,7 @@ def test_textbook_phase_estimation_qubitized_walk(num_terms: int, use_resource_s
107104

108105
# 3. QPE circuit with state prep
109106
qpe_with_init = prep_L_K + qpe_circuit
110-
# assert len(qpe_with_init.all_qubits()) < 23
107+
assert len(qpe_with_init.all_qubits()) < 23
111108

112109
# 4. Estimate theta
113110
theta = simulate_theta_estimate(qpe_with_init, quregs['qpe_reg'])

qualtran/bloqs/reflections/reflection_using_prepare_test.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -109,12 +109,13 @@ def get_3q_uniform_dirac_notation(signs, global_phase: complex = 1):
109109
ret = ret + f' {c} {term}'
110110
return ret
111111

112+
112113
@pytest.mark.slow
113114
@pytest.mark.parametrize('num_ones', [5])
114115
@pytest.mark.parametrize('eps', [0.05])
115116
@pytest.mark.parametrize('global_phase', [+1, -1j])
116117
def test_reflection_using_prepare(num_ones, eps, global_phase):
117-
return pytest.xfail("Cirq regression") # TODO error message
118+
return pytest.xfail("Cirq regression") # TODO error message
118119

119120
data = [1] * num_ones
120121
prepare_gate = StatePreparationAliasSampling.from_probabilities(data, precision=eps)

0 commit comments

Comments
 (0)