Skip to content

Commit fd80e52

Browse files
🚚 Create resource_estimation module (#173)
## Description This PR moves the resource estimation code into a new `resource_estimation` module. ## Checklist: - [x] The pull request only contains commits that are focused and relevant to this change. - [x] I have added appropriate tests that cover the new/changed functionality. - [x] I have updated the documentation to reflect these changes. - [x] The changes follow the project's style guidelines and introduce no new warnings. - [x] The changes are fully tested and pass the CI checks. - [x] I have reviewed my own code changes. --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
1 parent 3c7f217 commit fd80e52

File tree

52 files changed

+1435
-1296
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1435
-1296
lines changed

docs/_static/mqt_dark.png

59.7 KB
Loading

docs/_static/mqt_light.png

55.9 KB
Loading

docs/index.md

Lines changed: 45 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
---
2+
file_format: mystnb
3+
kernelspec:
4+
name: python3
5+
mystnb:
6+
number_source_lines: true
7+
---
8+
19
# MQT ProblemSolver
210

311
MQT ProblemSolver provides a framework to utilize quantum computing as a technology for users with little to no quantum computing knowledge
@@ -26,7 +34,7 @@ In the current implementation, two case studies are conducted:
2634

2735
### A SAT Problem: Constraint Satisfaction Problem
2836

29-
This exemplary implementation can be found in the [`csp_example.ipynb`](https://github.com/cda-tum/mqt-problemsolver/blob/main/notebooks/csp_example.ipynb) Jupyter notebook.
37+
This exemplary implementation can be found in the [`csp_example.ipynb`](https://github.com/munich-quantum-toolkit/problemsolver/blob/main/notebooks/csp_example.ipynb) Jupyter notebook.
3038
Here, the solution to a Kakuro riddle with a 2x2 grid can be solved for arbitrary sums `s0` to `s3`:
3139

3240
<p align="center">
@@ -37,7 +45,7 @@ MQT ProblemSolver will return valid values to `a`, `b`, `c`, and `d` if a soluti
3745

3846
### A Graph-based Optimization Problem: Travelling Salesman Problem
3947

40-
This exemplary implementation can be found in the [`tsp_example.ipynb`](https://github.com/cda-tum/mqt-problemsolver/blob/main/notebooks/tsp_example.ipynb) Jupyter notebook.
48+
This exemplary implementation can be found in the [`tsp_example.ipynb`](https://github.com/munich-quantum-toolkit/problemsolver/blob/main/notebooks/tsp_example.ipynb) Jupyter notebook.
4149
Here, the solution to a Travelling Salesman Problem with 4 cities can be solved for arbitrary distances `dist_1_2` to `dist_3_4`between the cities.
4250

4351
<p align="center">
@@ -84,7 +92,7 @@ For more details, see {cite:p}`quetschlich2023precompilation`.
8492
Resource estimation is a promising alternative to actually execute quantum circuits on real quantum hardware which is currently restricted by the number of qubits and the error rates. By estimating the resources needed for a quantum circuit,
8593
the development of quantum computing applications can be accelerated without the need to wait for the availability of large-enough quantum hardware.
8694

87-
In `resource_estimation/RE_experiments.py`, we evaluate the resources to calculate the ground state energy of a Hamiltonian to chemical accuracy of 1 mHartree using the qubitization quantum simulation algorithm.
95+
In [`experiments.ipynb`](https://github.com/munich-quantum-toolkit/problemsolver/blob/main/notebooks/resource_estimation/experiments.ipynb), we evaluate the resources to calculate the ground state energy of a Hamiltonian to chemical accuracy of 1 mHartree using the qubitization quantum simulation algorithm.
8896
The Hamiltonian describes the 64 electron and 56 orbital active space of one of the stable intermediates in the ruthenium-catalyzed carbon fixation cycle.
8997

9098
In this evaluation, we investigate
@@ -118,14 +126,15 @@ In the `equivalence_checking` module, our approach to this problem by utilizing
118126
- A second one to actually input a miter expression (in form of a string) together with some parameters independent from the miter (shots and delta) and use our approach to find the counter examples (if the circuits are non-equivalent).
119127

120128
These two implementations are provided by the functions `try_parameter_combinations()` and `find_counter_examples()`, respectively.
121-
Examples for their usages are shown in the [`equivalence_checking_example.ipynb`](https://github.com/cda-tum/mqt-problemsolver/blob/main/notebooks/equivalence_checking/equivalence_checking_example.ipynb) Jupyter notebook.
129+
Examples for their usages are shown in the [`equivalence_checking_example.ipynb`](https://github.com/munich-quantum-toolkit/problemsolver/blob/main/notebooks/equivalence_checking/equivalence_checking_example.ipynb) Jupyter notebook.
122130

123131
For more details, see {cite:p}`quetschlich2024equivalence_checking`.
124132

125133
## Improving Hardware Requirements for Fault-Tolerant Quantum Computing by Optimizing Error Budget Distributions
126134

127135
Applying error correction to execute quantum circuits fault-tolerantly induces massive overheads in the required physical resources, often in the orders of magnitude.
128-
This leads to thousands of qubits already for toy-sized quantum applications. Obviously, these need to be reduced, for which the so-called error budget can be a particular lever.
136+
This leads to thousands of qubits already for toy-sized quantum applications.
137+
Obviously, these need to be reduced, for which the so-called error budget can be a particular lever.
129138
Even though error correction is applied, a certain error rate still remains in the execution of the quantum circuit.
130139
Hence, the end user defines a maximum tolerated error rate, the error budget, for the quantum application to be considered by the compiler.
131140
Since an error-corrected quantum circuit consists of different parts, this error budget is distributed among these parts.
@@ -136,18 +145,44 @@ To find an efficient distribution, we use resource estimation to evaluate differ
136145
<img src="_static/error_budget_approach.svg" height=150px>
137146
</p>
138147

139-
The implementation of the approach can be found under `resource_estimation/error_budget_optimization`.
140-
An example usage of the implementation is shown in the [`example_use.ipynb`](https://github.com/cda-tum/mqt-problemsolver/blob/main/resource_estimation/error_budget_optimization/example_use.ipynb) Jupyter notebook.
148+
For an examplary usage of the implementation, see below.
149+
150+
```{code-cell} ipython3
151+
from mqt.problemsolver.resource_estimation.error_budget_optimization import (
152+
evaluate,
153+
generate_data,
154+
plot_results,
155+
train,
156+
)
157+
158+
total_error_budget = 0.1
159+
benchmarks_and_sizes = [("ae", [3, 4, 5, 6, 7, 8, 9, 10])]
160+
data = generate_data(
161+
total_error_budget=total_error_budget,
162+
number_of_randomly_generated_distributions=1000,
163+
benchmarks_and_sizes=benchmarks_and_sizes,
164+
)
165+
model, x_test, y_test = train(data)
166+
y_pred = model.predict(x_test)
167+
product_diffs = evaluate(x_test, y_pred, total_error_budget)
168+
product_diffs_dataset = evaluate(x_test, y_test, total_error_budget)
169+
plot_results(product_diffs, product_diffs_dataset, legend=True, bin_width=4)
170+
```
171+
172+
A more elaborate example of the implementation is shown in the [`example.ipynb`](https://github.com/munich-quantum-toolkit/problemsolver/blob/main/notebooks/resource_estimation/error_budget_optimization/example.ipynb) Jupyter notebook.
141173

142174
For more details, see {cite:p}`forster2025error_budget_optimization`.
143175

144176
## Quantum Circuit Optimization for the Fault-Tolerance Era: Do We Have to Start from Scratch?
145177

146-
Translating quantum circuits into a device's native gate set often increases gate count, amplifying noise in today's error-prone Noisy Intermediate-Scale Quantum (NISQ) devices. Although optimizations exist to reduce gate counts, scaling to larger qubit and circuit sizes will see hardware errors dominate, blocking industrial-scale use. Error correction can enable Fault-Tolerant Quantum Computing (FTQC) but demands massive qubit overheads, often tens of thousands for small problems.
178+
Translating quantum circuits into a device's native gate set often increases gate count, amplifying noise in today's error-prone Noisy Intermediate-Scale Quantum (NISQ) devices.
179+
Although optimizations exist to reduce gate counts, scaling to larger qubit and circuit sizes will see hardware errors dominate, blocking industrial-scale use. Error correction can enable Fault-Tolerant Quantum Computing (FTQC) but demands massive qubit overheads, often tens of thousands for small problems.
147180

148-
This motivates FTQC-oriented optimization techniques and raises the question: can NISQ techniques be adapted, or must new ones be developed? We address this question by evaluating Qiskit and TKET optimization passes on benchmark circuits from MQT Bench. As tools to directly design and evaluate fault-tolerant quantum circuit instances, we use resource estimation to assess FTQC requirements.
181+
This motivates FTQC-oriented optimization techniques and raises the question: can NISQ techniques be adapted, or must new ones be developed?
182+
We address this question by evaluating Qiskit and TKET optimization passes on benchmark circuits from MQT Bench.
183+
As tools to directly design and evaluate fault-tolerant quantum circuit instances, we use resource estimation to assess FTQC requirements.
149184

150-
The implementation of the approach can be found under `resource_estimation/ft_optimization`.
185+
An example usage of the implementation is shown in the [`example.ipynb`](https://github.com/munich-quantum-toolkit/problemsolver/blob/main/notebooks/resource_estimation/fault_tolerant_optimization/example.ipynb) Jupyter notebook.
151186

152187
For more details, see {cite:p}`forster2025ft_circuit_optimization`.
153188

resource_estimation/error_budget_optimization/example_use.ipynb renamed to notebooks/resource_estimation/error_budget_optimization/example.ipynb

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,12 @@
1010
"import csv\n",
1111
"from pathlib import Path\n",
1212
"\n",
13-
"from evaluate import evaluate, plot_results\n",
14-
"from generate_data import generate_data\n",
15-
"from training import train"
13+
"from mqt.problemsolver.resource_estimation.error_budget_optimization import (\n",
14+
" evaluate,\n",
15+
" generate_data,\n",
16+
" plot_results,\n",
17+
" train,\n",
18+
")"
1619
]
1720
},
1821
{
@@ -36,7 +39,7 @@
3639
"use_zip_file_circuits = False\n",
3740
"\n",
3841
"if use_paper_data:\n",
39-
" csv_path = Path(\"paper_data/logical_counts.csv\")\n",
42+
" csv_path = Path(\"logical_counts.csv\")\n",
4043
" with Path.open(csv_path, encoding=\"utf-8\", newline=\"\") as csvfile:\n",
4144
" reader = csv.DictReader(csvfile)\n",
4245
" logical_counts = [{k: int(v) for k, v in row.items()} for row in reader]\n",
@@ -47,9 +50,9 @@
4750
" )\n",
4851
"\n",
4952
"elif use_zip_file_circuits:\n",
50-
" zip_file_path = Path(\"paper_data\") / \"mqtbench.zip\"\n",
53+
" zip_file_path = Path(\"mqt_bench.zip\")\n",
5154
" if not zip_file_path.exists():\n",
52-
" msg = f\"Paper data not found at {zip_file_path}\"\n",
55+
" msg = f\"Data not found at {zip_file_path}\"\n",
5356
" raise FileNotFoundError(msg)\n",
5457
" data = generate_data(\n",
5558
" total_error_budget,\n",
@@ -101,8 +104,8 @@
101104
"metadata": {},
102105
"outputs": [],
103106
"source": [
104-
"Y_pred = model.predict(x_test)\n",
105-
"product_diffs = evaluate(x_test, Y_pred, total_error_budget)\n",
107+
"y_pred = model.predict(x_test)\n",
108+
"product_diffs = evaluate(x_test, y_pred, total_error_budget)\n",
106109
"product_diffs_dataset = evaluate(x_test, y_test, total_error_budget)\n",
107110
"\n",
108111
"plot_results(product_diffs, product_diffs_dataset, legend=True, bin_width=4)"
@@ -111,7 +114,7 @@
111114
],
112115
"metadata": {
113116
"kernelspec": {
114-
"display_name": ".venv",
117+
"display_name": "mqt-problemsolver (3.13.3)",
115118
"language": "python",
116119
"name": "python3"
117120
},

resource_estimation/error_budget_optimization/paper_data/logical_counts.csv renamed to notebooks/resource_estimation/error_budget_optimization/logical_counts.csv

File renamed without changes.

resource_estimation/error_budget_optimization/paper_data/mqtbench.zip renamed to notebooks/resource_estimation/error_budget_optimization/mqt_bench.zip

File renamed without changes.
Lines changed: 210 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,210 @@
1+
{
2+
"cells": [
3+
{
4+
"cell_type": "code",
5+
"execution_count": null,
6+
"id": "a5210510",
7+
"metadata": {},
8+
"outputs": [],
9+
"source": [
10+
"from math import ceil\n",
11+
"\n",
12+
"from qsharp.estimator import EstimatorParams, EstimatorResult, LogicalCounts, QECScheme, QubitParams"
13+
]
14+
},
15+
{
16+
"cell_type": "markdown",
17+
"id": "25ef4938",
18+
"metadata": {},
19+
"source": [
20+
"# Experiments"
21+
]
22+
},
23+
{
24+
"cell_type": "code",
25+
"execution_count": null,
26+
"id": "06e15253",
27+
"metadata": {},
28+
"outputs": [],
29+
"source": [
30+
"# For all experiments, we are using the logical resource counts as a starting\n",
31+
"# point. These have been computed using the qsharp Python package (version\n",
32+
"# 1.8.0) for the https://aka.ms/fcidump/XVIII-cas4-fb-64e-56o Hamiltonian on\n",
33+
"# the sample\n",
34+
"# https://github.com/microsoft/qsharp/tree/main/samples/estimation/df-chemistry:\n",
35+
"#\n",
36+
"# ```\n",
37+
"# $ python chemistry.py -f https://aka.ms/fcidump/XVIII-cas4-fb-64e-56o\n",
38+
"# $ jq '.logicalCounts' < resource_estimate.json\n",
39+
"# ```\n",
40+
"\n",
41+
"logical_counts = LogicalCounts({\n",
42+
" \"numQubits\": 1318,\n",
43+
" \"tCount\": 96,\n",
44+
" \"rotationCount\": 11987084,\n",
45+
" \"rotationDepth\": 11986482,\n",
46+
" \"cczCount\": 67474931068,\n",
47+
" \"measurementCount\": 63472407520,\n",
48+
"})"
49+
]
50+
},
51+
{
52+
"cell_type": "markdown",
53+
"id": "7b396e6b",
54+
"metadata": {},
55+
"source": [
56+
"## Default qubit models"
57+
]
58+
},
59+
{
60+
"cell_type": "code",
61+
"execution_count": null,
62+
"id": "582477ec",
63+
"metadata": {},
64+
"outputs": [],
65+
"source": [
66+
"params = EstimatorParams(6)\n",
67+
"params.error_budget = 0.01\n",
68+
"params.items[0].qubit_params.name = QubitParams.GATE_US_E3\n",
69+
"params.items[1].qubit_params.name = QubitParams.GATE_US_E4\n",
70+
"params.items[2].qubit_params.name = QubitParams.GATE_NS_E3\n",
71+
"params.items[3].qubit_params.name = QubitParams.GATE_NS_E4\n",
72+
"params.items[4].qubit_params.name = QubitParams.MAJ_NS_E4\n",
73+
"params.items[4].qec_scheme.name = QECScheme.FLOQUET_CODE\n",
74+
"params.items[5].qubit_params.name = QubitParams.MAJ_NS_E6\n",
75+
"params.items[5].qec_scheme.name = QECScheme.FLOQUET_CODE\n",
76+
"\n",
77+
"results = logical_counts.estimate(params=params)\n",
78+
"\n",
79+
"print(results.summary_data_frame())"
80+
]
81+
},
82+
{
83+
"cell_type": "markdown",
84+
"id": "a707e2e5",
85+
"metadata": {},
86+
"source": [
87+
"## Evaluating different number of T factories"
88+
]
89+
},
90+
{
91+
"cell_type": "code",
92+
"execution_count": null,
93+
"id": "f16bbe88",
94+
"metadata": {},
95+
"outputs": [],
96+
"source": [
97+
"params = EstimatorParams(num_items=14)\n",
98+
"params.qubit_params.name = QubitParams.MAJ_NS_E6\n",
99+
"params.qec_scheme.name = QECScheme.FLOQUET_CODE\n",
100+
"\n",
101+
"params.error_budget = 0.01\n",
102+
"for i in range(14):\n",
103+
" params.items[i].constraints.max_t_factories = 14 - i\n",
104+
"\n",
105+
"results = logical_counts.estimate(params=params)\n",
106+
"\n",
107+
"print(results.summary_data_frame())"
108+
]
109+
},
110+
{
111+
"cell_type": "markdown",
112+
"id": "d94cb722",
113+
"metadata": {},
114+
"source": [
115+
"## Modifying error rates and operating times"
116+
]
117+
},
118+
{
119+
"cell_type": "code",
120+
"execution_count": null,
121+
"id": "75fe4f65",
122+
"metadata": {},
123+
"outputs": [],
124+
"source": [
125+
"base_time = 50 # ns\n",
126+
"base_error = 1e-3\n",
127+
"\n",
128+
"error_growth = 1e-1\n",
129+
"time_growth = 0.9\n",
130+
"\n",
131+
"params = EstimatorParams(num_items=5)\n",
132+
"params.error_budget = 0.01\n",
133+
"for t in range(5):\n",
134+
" params.items[t].qubit_params.instruction_set = \"gateBased\"\n",
135+
" params.items[t].qubit_params.name = f\"t{t}\"\n",
136+
" params.items[t].qubit_params.one_qubit_measurement_time = f\"{(2 * base_time) * time_growth**t} ns\"\n",
137+
" params.items[t].qubit_params.one_qubit_gate_time = f\"{base_time * time_growth**t} ns\"\n",
138+
" params.items[t].qubit_params.two_qubit_gate_time = f\"{base_time * time_growth**t} ns\"\n",
139+
" params.items[t].qubit_params.t_gate_time = f\"{base_time * time_growth**t} ns\"\n",
140+
" params.items[t].qubit_params.one_qubit_measurement_error_rate = base_error * error_growth**t\n",
141+
" params.items[t].qubit_params.one_qubit_gate_error_rate = base_error * error_growth**t\n",
142+
" params.items[t].qubit_params.two_qubit_gate_error_rate = base_error * error_growth**t\n",
143+
" params.items[t].qubit_params.t_gate_error_rate = base_error * error_growth**t\n",
144+
" params.items[t].qubit_params.idle_error_rate = base_error * error_growth**t\n",
145+
"\n",
146+
"results = logical_counts.estimate(params=params)\n",
147+
"\n",
148+
"print(results.summary_data_frame())"
149+
]
150+
},
151+
{
152+
"cell_type": "markdown",
153+
"id": "a272e940",
154+
"metadata": {},
155+
"source": [
156+
"## Modifying logical counts"
157+
]
158+
},
159+
{
160+
"cell_type": "code",
161+
"execution_count": null,
162+
"id": "43a81d61",
163+
"metadata": {},
164+
"outputs": [],
165+
"source": [
166+
"def modified_logical_counts(space_factor: float, time_factor: float) -> LogicalCounts:\n",
167+
" return LogicalCounts({\n",
168+
" \"numQubits\": ceil(logical_counts[\"numQubits\"] * space_factor),\n",
169+
" \"tCount\": ceil(logical_counts[\"tCount\"] * time_factor),\n",
170+
" \"rotationCount\": ceil(logical_counts[\"rotationCount\"] * time_factor),\n",
171+
" \"rotationDepth\": ceil(logical_counts[\"rotationDepth\"] * time_factor),\n",
172+
" \"cczCount\": ceil(logical_counts[\"cczCount\"] * time_factor),\n",
173+
" \"measurementCount\": ceil(logical_counts[\"measurementCount\"] * time_factor),\n",
174+
" })\n",
175+
"\n",
176+
"\n",
177+
"params = EstimatorParams()\n",
178+
"params.error_budget = 0.01\n",
179+
"params.qubit_params.name = QubitParams.MAJ_NS_E6\n",
180+
"params.qec_scheme.name = QECScheme.FLOQUET_CODE\n",
181+
"estimates = []\n",
182+
"for space_factor, time_factor in [(1.0, 1.0), (0.5, 2.0), (2.0, 0.5), (0.75, 0.75)]:\n",
183+
" counts = modified_logical_counts(space_factor, time_factor)\n",
184+
" estimates.append(counts.estimate(params=params))\n",
185+
"\n",
186+
"print(EstimatorResult(estimates).summary_data_frame())"
187+
]
188+
}
189+
],
190+
"metadata": {
191+
"kernelspec": {
192+
"display_name": "mqt-problemsolver (3.13.3)",
193+
"language": "python",
194+
"name": "python3"
195+
},
196+
"language_info": {
197+
"codemirror_mode": {
198+
"name": "ipython",
199+
"version": 3
200+
},
201+
"file_extension": ".py",
202+
"mimetype": "text/x-python",
203+
"name": "python",
204+
"nbconvert_exporter": "python",
205+
"pygments_lexer": "ipython3"
206+
}
207+
},
208+
"nbformat": 4,
209+
"nbformat_minor": 5
210+
}

0 commit comments

Comments
 (0)