Skip to content

Commit

Permalink
Update THC Prepare to use QROAMClean (#1378)
Browse files Browse the repository at this point in the history
  • Loading branch information
fdmalone authored Oct 5, 2024
1 parent 14e6fe7 commit 705149c
Show file tree
Hide file tree
Showing 6 changed files with 1,716 additions and 227 deletions.
3 changes: 2 additions & 1 deletion qualtran/bloqs/block_encoding/lcu_block_encoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
BloqDocSpec,
CtrlSpec,
Register,
Side,
Signature,
SoquetT,
)
Expand Down Expand Up @@ -250,7 +251,7 @@ def selection_registers(self) -> Tuple[Register, ...]:

@cached_property
def junk_registers(self) -> Tuple[Register, ...]:
return self.prepare.junk_registers
return tuple(reg for reg in self.prepare.junk_registers if reg.side == Side.THRU)

@cached_property
def target_registers(self) -> Tuple[Register, ...]:
Expand Down
100 changes: 26 additions & 74 deletions qualtran/bloqs/chemistry/resource_estimation.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 1,
"id": "2fb17f7f",
"metadata": {},
"outputs": [],
Expand Down Expand Up @@ -113,42 +113,24 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 2,
"id": "b9991178",
"metadata": {},
"outputs": [],
"source": [
"from qualtran.bloqs.block_encoding import LCUBlockEncoding\n",
"from qualtran.bloqs.multiplexers.black_box_select import BlackBoxSelect\n",
"from qualtran.bloqs.state_preparation.black_box_prepare import BlackBoxPrepare\n",
"\n",
"epsilon = 1e-4 # choosing this arbitrarily at this point. See: https://github.com/quantumlib/Qualtran/issues/985\n",
"block_encoding_bloq = LCUBlockEncoding(\n",
" select=BlackBoxSelect(sel_thc), prepare=BlackBoxPrepare(prep_thc)\n",
" select=sel_thc, prepare=prep_thc\n",
")"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "55ce02c5",
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"from qualtran.drawing.musical_score import get_musical_score_data, draw_musical_score\n",
"msd = get_musical_score_data(block_encoding_bloq.decompose_bloq())\n",
"fig, ax = draw_musical_score(msd)\n",
"plt.tick_params(left=False, right=False, labelleft=False, labelbottom=False, bottom=False)\n",
"fig.set_size_inches(8, 4)"
]
},
{
"cell_type": "markdown",
"id": "deb5c0fa",
"metadata": {},
"source": [
"This looks like our math expression above. Now given our block encoding block we can determine the resources required as follows"
"Now given our block encoding block we can determine the resources required as follows"
]
},
{
Expand All @@ -158,35 +140,22 @@
"metadata": {},
"outputs": [],
"source": [
"from qualtran import Bloq\n",
"from qualtran.symbolics import SymbolicInt\n",
"from qualtran.bloqs import block_encoding\n",
"from qualtran.resource_counting import get_bloq_call_graph\n",
"import attrs\n",
"from qualtran.bloqs.bookkeeping import Partition, Split, Join, Allocate, Free\n",
"from qualtran.bloqs.basic_gates import CSwap, TGate\n",
"from qualtran.drawing import show_call_graph\n",
"from qualtran.resource_counting import QECGatesCost, get_cost_value\n",
"from qualtran.resource_counting.generalizers import generalize_cswap_approx\n",
"\n",
"def keeper(bloq):\n",
" # intercept CSwaps which are lumped in with Toffolis in the reference papers\n",
" if isinstance(bloq, CSwap):\n",
" return True\n",
" return False\n",
"\n",
"def generalizer(bloq):\n",
" if isinstance(bloq, (Partition, Split, Join, Allocate, Free)):\n",
" return None\n",
" return bloq\n",
"\n",
"\n",
"def get_toffoli_counts(bloq):\n",
" _, sigma = get_bloq_call_graph(bloq, generalizer=generalizer, keep=keeper)\n",
" toffolis = 0\n",
" for k, v in sigma.items():\n",
" if isinstance(k, CSwap):\n",
" toffolis += v * k.bitsize\n",
" elif isinstance(k, TGate):\n",
" toffolis += v // 4\n",
" return toffolis\n",
"def get_toffoli_counts(bloq: Bloq) -> SymbolicInt:\n",
" return get_cost_value(bloq, QECGatesCost(), generalizer=generalize_cswap_approx).total_t_and_ccz_count(ts_per_rotation=0)['n_ccz']\n",
"\n",
"num_toff = get_toffoli_counts(block_encoding_bloq)\n",
"print(num_toff)\n",
"# note the cost here is from openfermion, the reference number excludes the reflection\n",
"print(f'qualtran = {num_toff} vs. ref = 10880, delta = {num_toff - 10880}')"
]
Expand Down Expand Up @@ -219,6 +188,7 @@
"metadata": {},
"outputs": [],
"source": [
"import matplotlib.pyplot as plt\n",
"plt.pie(toffoli_counts, labels=['SELECT', 'PREPARE', r'PREPARE$^{\\dagger}$'], autopct='%1.1f%%')"
]
},
Expand All @@ -227,34 +197,12 @@
"id": "94fe7d78",
"metadata": {},
"source": [
"We see SELECT is the dominant cost and the inverse state preparation is significantly more expensive than its inverse. Let's have a look at the circuits to see where the costs are coming from."
"We see SELECT is the dominant cost and that state preparation is significantly more expensive than its inverse. Let's look at a breakdown of the costs"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "f671f121",
"metadata": {},
"outputs": [],
"source": [
"msd = get_musical_score_data(prep_thc.decompose_bloq())\n",
"fig, ax = draw_musical_score(msd)\n",
"fig.set_size_inches(12, 8)\n",
"ax.set_title('Prepare')\n",
"plt.tick_params(left=False, right=False, labelleft=False, labelbottom=False, bottom=False)"
]
},
{
"cell_type": "markdown",
"id": "cec920ff",
"metadata": {},
"source": [
"This figure should resemble Fig. 4 in the [THC paper](https://arxiv.org/abs/2011.03494). This circuit takes a familiar form, uniform state preparation followed by coherent alias sampling (QROM + swaps). Let's see a breakdown of these costs."
]
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 6,
"id": "5efd66ae",
"metadata": {},
"outputs": [],
Expand Down Expand Up @@ -306,6 +254,7 @@
"metadata": {},
"outputs": [],
"source": [
"from qualtran.drawing import get_musical_score_data, draw_musical_score\n",
"msd = get_musical_score_data(sel_thc.decompose_bloq())\n",
"fig, ax = draw_musical_score(msd)\n",
"fig.set_size_inches(12, 8)\n",
Expand Down Expand Up @@ -356,7 +305,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 10,
"id": "614bfb21",
"metadata": {},
"outputs": [],
Expand Down Expand Up @@ -414,7 +363,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 13,
"id": "349b70ab",
"metadata": {},
"outputs": [],
Expand All @@ -435,7 +384,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 14,
"id": "2ef506ab",
"metadata": {},
"outputs": [],
Expand All @@ -462,7 +411,7 @@
},
{
"cell_type": "code",
"execution_count": null,
"execution_count": 15,
"id": "e34dcb1c",
"metadata": {},
"outputs": [],
Expand All @@ -471,6 +420,8 @@
" SelectFirstQuantization,\n",
" PrepareFirstQuantization,\n",
")\n",
"from qualtran.bloqs.state_preparation.black_box_prepare import BlackBoxPrepare\n",
"from qualtran.bloqs.multiplexers.black_box_select import BlackBoxSelect\n",
"\n",
"# keep the electron count small to make the diagrams nicer\n",
"rs = 3.0\n",
Expand Down Expand Up @@ -547,15 +498,16 @@
"metadata": {},
"outputs": [],
"source": [
"from qualtran.resource_counting.generalizers import ignore_split_join, ignore_alloc_free\n",
"# let's just get the names of the relevant bloqs in select first\n",
"fig, ax = plt.subplots(nrows=1, ncols=5)\n",
"eta_vals = [10, 20, 40, 60, 80]\n",
"for ieta, eta in enumerate(eta_vals):\n",
" sel_fq = SelectFirstQuantization(num_bits_p, eta, eta, eta)\n",
" bloq_counts = sel_fq.bloq_counts(generalizer=generalizer)\n",
" bloq_counts = sel_fq.bloq_counts(generalizer=[ignore_split_join, ignore_alloc_free])\n",
" # dictionary returned does not preserve any order so sort by the pretty names of the bloqs\n",
" sorted_bloqs = sorted(\n",
" [bloq for bloq in sel_fq.bloq_counts(generalizer=generalizer).keys()],\n",
" [bloq for bloq in sel_fq.bloq_counts(generalizer=[ignore_split_join, ignore_alloc_free]).keys()],\n",
" key=lambda x: str(x),\n",
" )\n",
" keys = [str(b) for b in sorted_bloqs]\n",
Expand All @@ -582,7 +534,7 @@
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"display_name": "qualtran",
"language": "python",
"name": "python3"
},
Expand Down
Loading

0 comments on commit 705149c

Please sign in to comment.