Skip to content

Commit 47a36c8

Browse files
authored
First pass at fixing chemistry costs to use QECGatesCost (#1505)
1 parent 859d9e8 commit 47a36c8

17 files changed

+236
-140
lines changed

dev_tools/qualtran_dev_tools/notebook_specs.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,7 @@
6666
import qualtran.bloqs.chemistry.hubbard_model.qubitization
6767
import qualtran.bloqs.chemistry.pbc.first_quantization.prepare_t
6868
import qualtran.bloqs.chemistry.pbc.first_quantization.prepare_uv
69+
import qualtran.bloqs.chemistry.pbc.first_quantization.prepare_zeta
6970
import qualtran.bloqs.chemistry.pbc.first_quantization.projectile.select_and_prepare
7071
import qualtran.bloqs.chemistry.pbc.first_quantization.select_t
7172
import qualtran.bloqs.chemistry.pbc.first_quantization.select_uv
@@ -311,6 +312,7 @@
311312
qualtran.bloqs.chemistry.pbc.first_quantization.prepare_uv._PREPARE_UV,
312313
qualtran.bloqs.chemistry.pbc.first_quantization.select_t._SELECT_T,
313314
qualtran.bloqs.chemistry.pbc.first_quantization.select_uv._SELECT_UV,
315+
qualtran.bloqs.chemistry.pbc.first_quantization.prepare_zeta._PREPARE_ZETA,
314316
],
315317
directory=f'{SOURCE_DIR}/bloqs/chemistry/pbc/first_quantization',
316318
),

qualtran/bloqs/chemistry/pbc/first_quantization/first_quantization.ipynb

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -822,6 +822,119 @@
822822
"show_call_graph(select_uv_g)\n",
823823
"show_counts_sigma(select_uv_sigma)"
824824
]
825+
},
826+
{
827+
"cell_type": "markdown",
828+
"id": "69c98b9f",
829+
"metadata": {
830+
"cq.autogen": "PrepareZetaState.bloq_doc.md"
831+
},
832+
"source": [
833+
"## `PrepareZetaState`\n",
834+
"PREPARE the superpostion over $l$ weighted by $\\zeta_l$.\n",
835+
"\n",
836+
"See https://github.com/quantumlib/Qualtran/issues/473.\n",
837+
"#### Parameters\n",
838+
" - `num_bits_p`: The number of bits to represent each dimension of the momentum register.\n",
839+
" - `eta`: The number of electrons.\n",
840+
" - `m_param`: $\\mathcal{M}$ in the reference.\n",
841+
" - `lambda_zeta`: sum of nuclear charges. \n",
842+
"\n",
843+
"#### Registers\n",
844+
" - `l`: the register indexing the atomic number. \n",
845+
"\n",
846+
"#### References\n",
847+
" - [Fault-Tolerant Quantum Simulations of Chemistry in First Quantization](https://arxiv.org/abs/2105.12767). page 23-24, last 3 paragraphs.\n"
848+
]
849+
},
850+
{
851+
"cell_type": "code",
852+
"execution_count": null,
853+
"id": "074bc1b8",
854+
"metadata": {
855+
"cq.autogen": "PrepareZetaState.bloq_doc.py"
856+
},
857+
"outputs": [],
858+
"source": [
859+
"from qualtran.bloqs.chemistry.pbc.first_quantization.prepare_zeta import PrepareZetaState"
860+
]
861+
},
862+
{
863+
"cell_type": "markdown",
864+
"id": "fd3071f7",
865+
"metadata": {
866+
"cq.autogen": "PrepareZetaState.example_instances.md"
867+
},
868+
"source": [
869+
"### Example Instances"
870+
]
871+
},
872+
{
873+
"cell_type": "code",
874+
"execution_count": null,
875+
"id": "31ee49a4",
876+
"metadata": {
877+
"cq.autogen": "PrepareZetaState.prepare_zeta"
878+
},
879+
"outputs": [],
880+
"source": [
881+
"num_atoms = 10\n",
882+
"lambda_zeta = 10\n",
883+
"num_bits_nuc_pos = 8\n",
884+
"\n",
885+
"prepare_zeta = PrepareZetaState(\n",
886+
" num_atoms=num_atoms, lambda_zeta=lambda_zeta, num_bits_nuc_pos=num_bits_nuc_pos\n",
887+
")"
888+
]
889+
},
890+
{
891+
"cell_type": "markdown",
892+
"id": "4fb19c71",
893+
"metadata": {
894+
"cq.autogen": "PrepareZetaState.graphical_signature.md"
895+
},
896+
"source": [
897+
"#### Graphical Signature"
898+
]
899+
},
900+
{
901+
"cell_type": "code",
902+
"execution_count": null,
903+
"id": "6498eee0",
904+
"metadata": {
905+
"cq.autogen": "PrepareZetaState.graphical_signature.py"
906+
},
907+
"outputs": [],
908+
"source": [
909+
"from qualtran.drawing import show_bloqs\n",
910+
"show_bloqs([prepare_zeta],\n",
911+
" ['`prepare_zeta`'])"
912+
]
913+
},
914+
{
915+
"cell_type": "markdown",
916+
"id": "1e644753",
917+
"metadata": {
918+
"cq.autogen": "PrepareZetaState.call_graph.md"
919+
},
920+
"source": [
921+
"### Call Graph"
922+
]
923+
},
924+
{
925+
"cell_type": "code",
926+
"execution_count": null,
927+
"id": "fbef8e6e",
928+
"metadata": {
929+
"cq.autogen": "PrepareZetaState.call_graph.py"
930+
},
931+
"outputs": [],
932+
"source": [
933+
"from qualtran.resource_counting.generalizers import ignore_split_join\n",
934+
"prepare_zeta_g, prepare_zeta_sigma = prepare_zeta.call_graph(max_depth=1, generalizer=ignore_split_join)\n",
935+
"show_call_graph(prepare_zeta_g)\n",
936+
"show_counts_sigma(prepare_zeta_sigma)"
937+
]
825938
}
826939
],
827940
"metadata": {

qualtran/bloqs/chemistry/pbc/first_quantization/prepare_t_test.py

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,14 @@
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
1414

15-
from qualtran.bloqs.basic_gates import Toffoli
1615
from qualtran.bloqs.chemistry.pbc.first_quantization.prepare import (
1716
UniformSuperpostionIJFirstQuantization,
1817
)
1918
from qualtran.bloqs.chemistry.pbc.first_quantization.prepare_t import (
2019
_prepare_t,
2120
PrepareTFirstQuantization,
2221
)
22+
from qualtran.resource_counting import get_cost_value, QECGatesCost
2323

2424

2525
def test_prepare_t(bloq_autotester):
@@ -33,15 +33,12 @@ def test_prepare_kinetic_t_counts():
3333
n_eta = (eta - 1).bit_length()
3434
expected_cost = (14 * n_eta + 8 * b_r - 36) + 2 * (2 * num_bits_p + 9)
3535
uni = UniformSuperpostionIJFirstQuantization(eta, num_bits_rot_aa=b_r)
36-
_, counts = uni.call_graph()
37-
qual_cost = counts[Toffoli()]
36+
37+
qual_cost = get_cost_value(uni, QECGatesCost()).total_toffoli_only()
3838
uni = UniformSuperpostionIJFirstQuantization(eta, num_bits_rot_aa=b_r).adjoint()
39-
_, counts = uni.call_graph()
40-
qual_cost += counts[Toffoli()]
39+
qual_cost += get_cost_value(uni, QECGatesCost()).total_toffoli_only()
4140
prep = PrepareTFirstQuantization(num_bits_p, eta, num_bits_rot_aa=b_r)
42-
_, counts = prep.call_graph()
43-
qual_cost += counts[Toffoli()]
41+
qual_cost += get_cost_value(prep, QECGatesCost()).total_toffoli_only()
4442
prep = PrepareTFirstQuantization(num_bits_p, eta, num_bits_rot_aa=b_r).adjoint()
45-
_, counts = prep.call_graph()
46-
qual_cost += counts[Toffoli()]
43+
qual_cost += get_cost_value(prep, QECGatesCost()).total_toffoli_only()
4744
assert qual_cost == expected_cost

qualtran/bloqs/chemistry/pbc/first_quantization/prepare_zeta.py

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@
1919
import numpy as np
2020
from attrs import evolve, frozen
2121

22-
from qualtran import Bloq, QAny, Register, Signature
22+
from qualtran import Bloq, bloq_example, BloqDocSpec, QAny, Register, Signature
2323
from qualtran.bloqs.basic_gates import Toffoli
2424

2525
if TYPE_CHECKING:
@@ -65,3 +65,22 @@ def build_call_graph(self, ssa: 'SympySymbolAllocator') -> 'BloqCountDictT':
6565
else:
6666

6767
return {Toffoli(): self.lambda_zeta}
68+
69+
70+
@bloq_example
71+
def _prepare_zeta() -> PrepareZetaState:
72+
num_atoms = 10
73+
lambda_zeta = 10
74+
num_bits_nuc_pos = 8
75+
76+
prepare_zeta = PrepareZetaState(
77+
num_atoms=num_atoms, lambda_zeta=lambda_zeta, num_bits_nuc_pos=num_bits_nuc_pos
78+
)
79+
return prepare_zeta
80+
81+
82+
_PREPARE_ZETA = BloqDocSpec(
83+
bloq_cls=PrepareZetaState,
84+
import_line='from qualtran.bloqs.chemistry.pbc.first_quantization.prepare_zeta import PrepareZetaState',
85+
examples=(_prepare_zeta,),
86+
)

qualtran/bloqs/chemistry/pbc/first_quantization/prepare_zeta_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14-
from qualtran.bloqs.chemistry.pbc.first_quantization.prepare_zeta import PrepareZetaState
14+
from qualtran.bloqs.chemistry.pbc.first_quantization.prepare_zeta import _prepare_zeta
1515

1616

17-
def test_uniform_superposition_ij():
18-
prep = PrepareZetaState(num_atoms=10, lambda_zeta=20, num_bits_nuc_pos=8)
17+
def test_prepare_zeta(bloq_autotester):
18+
bloq_autotester(_prepare_zeta)

qualtran/bloqs/chemistry/pbc/first_quantization/projectile/prepare_t_test.py

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,13 @@
1414

1515
import pytest
1616

17-
from qualtran.bloqs.basic_gates import Toffoli
1817
from qualtran.bloqs.chemistry.pbc.first_quantization.projectile.prepare_t import (
1918
_prep_power_two_proj,
2019
_prep_t_proj,
2120
PreparePowerTwoStateWithProj,
2221
PrepareTFirstQuantizationWithProj,
2322
)
23+
from qualtran.resource_counting import get_cost_value, QECGatesCost
2424

2525

2626
def test_prep_t_proj(bloq_autotester):
@@ -39,13 +39,11 @@ def test_prepare_kinetic_t_proj_counts():
3939
expected_cost = 2 * (2 * num_bits_n + 9) + 2 * (num_bits_n - num_bits_p) + 20
4040
qual_cost = 0
4141
prep = PrepareTFirstQuantizationWithProj(num_bits_p, num_bits_n, eta, num_bits_rot_aa=b_r)
42-
_, counts = prep.call_graph()
43-
qual_cost += counts[Toffoli()]
42+
qual_cost += get_cost_value(prep, QECGatesCost()).total_toffoli_only()
4443
prep = PrepareTFirstQuantizationWithProj(
4544
num_bits_p, num_bits_n, eta, num_bits_rot_aa=b_r
4645
).adjoint()
47-
_, counts = prep.call_graph()
48-
qual_cost += counts[Toffoli()]
46+
qual_cost += get_cost_value(prep, QECGatesCost()).total_toffoli_only()
4947
assert qual_cost == expected_cost
5048

5149

qualtran/bloqs/chemistry/pbc/first_quantization/projectile/select_t_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14-
from qualtran.bloqs.basic_gates import Toffoli
1514
from qualtran.bloqs.chemistry.pbc.first_quantization.projectile.select_t import (
1615
_sel_t_proj,
1716
SelectTFirstQuantizationWithProj,
1817
)
18+
from qualtran.resource_counting import get_cost_value, QECGatesCost
1919

2020

2121
def test_sel_t_proj(bloq_autotester):
@@ -25,5 +25,5 @@ def test_sel_t_proj(bloq_autotester):
2525
def test_select_kinetic_t_counts():
2626
num_bits_n = 6
2727
sel = SelectTFirstQuantizationWithProj(num_bits_n, 10)
28-
_, counts = sel.call_graph()
29-
assert counts[Toffoli()] == 5 * (num_bits_n - 1) + 2 + 1
28+
toffolis = get_cost_value(sel, QECGatesCost()).total_toffoli_only()
29+
assert toffolis == 5 * (num_bits_n - 1) + 2 + 1

qualtran/bloqs/chemistry/pbc/first_quantization/select_t_test.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,11 @@
1111
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1212
# See the License for the specific language governing permissions and
1313
# limitations under the License.
14-
from qualtran.bloqs.basic_gates import Toffoli
1514
from qualtran.bloqs.chemistry.pbc.first_quantization.select_t import (
1615
_select_t,
1716
SelectTFirstQuantization,
1817
)
18+
from qualtran.resource_counting import get_cost_value, QECGatesCost
1919

2020

2121
def test_select_t(bloq_autotester):
@@ -25,5 +25,5 @@ def test_select_t(bloq_autotester):
2525
def test_select_kinetic_t_counts():
2626
num_bits_p = 6
2727
sel = SelectTFirstQuantization(num_bits_p, 10)
28-
_, counts = sel.call_graph()
29-
assert counts[Toffoli()] == 5 * (num_bits_p - 1) + 2
28+
toffolis = get_cost_value(sel, QECGatesCost()).total_toffoli_only()
29+
assert toffolis == 5 * (num_bits_p - 1) + 2

qualtran/bloqs/chemistry/resource_estimation.ipynb

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@
8484
},
8585
{
8686
"cell_type": "code",
87-
"execution_count": 1,
87+
"execution_count": null,
8888
"id": "2fb17f7f",
8989
"metadata": {},
9090
"outputs": [],
@@ -113,7 +113,7 @@
113113
},
114114
{
115115
"cell_type": "code",
116-
"execution_count": 2,
116+
"execution_count": null,
117117
"id": "b9991178",
118118
"metadata": {},
119119
"outputs": [],
@@ -202,7 +202,7 @@
202202
},
203203
{
204204
"cell_type": "code",
205-
"execution_count": 6,
205+
"execution_count": null,
206206
"id": "5efd66ae",
207207
"metadata": {},
208208
"outputs": [],
@@ -305,7 +305,7 @@
305305
},
306306
{
307307
"cell_type": "code",
308-
"execution_count": 10,
308+
"execution_count": null,
309309
"id": "614bfb21",
310310
"metadata": {},
311311
"outputs": [],
@@ -346,9 +346,8 @@
346346
"metadata": {},
347347
"outputs": [],
348348
"source": [
349-
"_, sigma = df_bloq.call_graph()\n",
350349
"refl_cost_and_qpe = (df_bloq.num_aux -1).bit_length() + (num_spin_orb // 2 - 1).bit_length() + num_bits_state_prep + 1 + 2\n",
351-
"print(f'qualtran cost = {sigma[TGate()] // 4} vs paper = {21753 - refl_cost_and_qpe}')"
350+
"print(f'qualtran cost = {get_toffoli_counts(df_bloq)} vs paper = {21753 - refl_cost_and_qpe}')"
352351
]
353352
},
354353
{
@@ -363,7 +362,7 @@
363362
},
364363
{
365364
"cell_type": "code",
366-
"execution_count": 13,
365+
"execution_count": null,
367366
"id": "349b70ab",
368367
"metadata": {},
369368
"outputs": [],
@@ -384,7 +383,7 @@
384383
},
385384
{
386385
"cell_type": "code",
387-
"execution_count": 14,
386+
"execution_count": null,
388387
"id": "2ef506ab",
389388
"metadata": {},
390389
"outputs": [],
@@ -411,7 +410,7 @@
411410
},
412411
{
413412
"cell_type": "code",
414-
"execution_count": 15,
413+
"execution_count": null,
415414
"id": "e34dcb1c",
416415
"metadata": {},
417416
"outputs": [],

qualtran/bloqs/chemistry/trotter/grid_ham/inverse_sqrt_test.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,6 @@ def test_newton_raphson_inverse_sqrt_bloq_counts():
4141
poly_bitsize = 15
4242
target_bitsize = 22
4343
bloq = NewtonRaphsonApproxInverseSquareRoot(int_bitsize, poly_bitsize, target_bitsize)
44-
_, counts = bloq.call_graph()
4544
cost_square = poly_bitsize**2 // 2 - 4
4645
cost_scale = poly_bitsize * (2 * int_bitsize - 1) - int_bitsize**2
4746
cost_mult = 2 * (target_bitsize**2 - target_bitsize - 1)

0 commit comments

Comments
 (0)