-
Notifications
You must be signed in to change notification settings - Fork 103
Moving FLASQ into Qualtran #1842
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
wjhuggins
wants to merge
65
commits into
quantumlib:main
Choose a base branch
from
wjhuggins:qualtran-pr
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from 64 commits
Commits
Show all changes
65 commits
Select commit
Hold shift + click to select a range
b5af1ab
phase7: copy FLASQ source and test files (raw, unmodified)
wjhuggins 4ed31ff
phase7: add frozendict, pandas, and seaborn dependencies for FLASQ
wjhuggins e0b0adc
phase7: rewrite all imports and fix adder_example path
wjhuggins a11767c
phase7: rename test classes to *TestSuite
wjhuggins 4dc927b
phase7: convert notebooks to .ipynb and add notebooks_test.py
wjhuggins df911e1
license: add Apache 2.0 headers to flasq files
wjhuggins b97421b
tests: mark slow and xfail tests in flasq
wjhuggins 0cba1a5
phase7: final cleanup and add .gitignore
wjhuggins 97096c6
phase7: add joblib to dependencies
wjhuggins df79b55
tests: run notebooks in temp dir to avoid polluting CWD
wjhuggins 9e92415
Add script to reproduce cultivation spacetime volume heatmap (paper F…
wjhuggins bbb571d
refactor: avoid private API _extract_bloq_from_op in cirq_interop.py
wjhuggins afb0c1d
fix: import CirqGateAsBloq from public path in volume_counting.py
wjhuggins bb601f0
chore: ignore PDF files in Qualtran
wjhuggins b77f85f
fix: import CirqQuregT under TYPE_CHECKING in cirq_interop and adder_…
wjhuggins 6c42eab
chore: add tqdm to pyproject.toml dependencies
wjhuggins d7819e8
dead-code: remove commented-out code in cirq_interop and adder_example
wjhuggins 36d162a
docs: remove meta-comment TODO in gf2_multiplier_test.py
wjhuggins 5cc2f94
chore: enable parallel test execution by default in pyproject.toml
wjhuggins 5318b4e
chore: revert parallel test execution due to missing pytest-xdist
wjhuggins 58a0c9e
chore: enable parallel test execution by default in pyproject.toml
wjhuggins 39eed78
chore: revert parallel test execution in pyproject.toml
wjhuggins 4a6935c
fix: add missing return types to __all__ in flasq/__init__.py
wjhuggins 7a9d36e
fix: use autouse fixture for env vars in notebooks_test.py
wjhuggins 8dca0d2
docs: add slow markers to flasq_model_test and nan_guard_test
wjhuggins 461aa26
dead-code: remove print statements from test files
wjhuggins 899a0df
docs: add slow marker to test_ising_volume_limited_depth_comparison_5…
wjhuggins effd1fa
fix: resolve T_REACT in hwp_test.py to fix volume-limited check
wjhuggins a843b44
dead-code: remove remaining TODO in hwp_test.py
wjhuggins d9500e7
dead-code: remove TODOs in flasq_model_test.py
wjhuggins a65c164
fix: export bloq_is_t_like from resource_counting to avoid type ignor…
wjhuggins e274330
fix: remove xfail markers from passing tests in misc_bug_test.py
wjhuggins 98ad76f
refactor: extract convert_sympy_exprs_in_df to utils.py and use in po…
wjhuggins ae72ef9
refactor: remove redundant static cost check in TotalSpanCost.compute
wjhuggins 163b8d6
refactor: use converter in MeasurementDepth and remove __attrs_post_i…
wjhuggins fa57231
cleanup: fix stale comment in MeasurementDepth and rename TestHashabl…
wjhuggins 57faeaf
style: run isort on flasq/ to fix import ordering
wjhuggins d54a935
style: run black on flasq/ to fix code formatting
wjhuggins 05f55b6
style: resolve isort/black conflict in flasq_model_test.py by consoli…
wjhuggins ca75ebf
fix: resolve upstream API breakage and analysis variable bugs
wjhuggins 0a90650
fix: resolve systemic frozendict typing issues via _to_frozendict wra…
wjhuggins b45945d
fix: resolve mypy union narrowing, collection variance, and assertion…
wjhuggins bb4e2db
fix: resolve remaining type narrowing, import, and test collection er…
wjhuggins 5deb8d9
style: reformat after mypy fixes
wjhuggins 770ae58
fix: resolve mypy errors in utils.py by converting frozendict to list…
wjhuggins e402c5c
fix: resolve mypy errors in plotting.py by adding assert guards for m…
wjhuggins d51f305
fix: resolve mypy errors in volume_counting.py by fixing isinstance a…
wjhuggins 423b7b9
fix: resolve mypy error in volume_counting_test.py by adding type ign…
wjhuggins 576fb14
fix: resolve mypy errors related to span counting by widening calcula…
wjhuggins c08d443
fix: resolve mypy errors in flasq_model.py by adding type ignore for …
wjhuggins 3e51685
chore: remove unused imports across FLASQ modules (pylint W0611)
wjhuggins 8dd1729
chore: add missing copyright headers to flasq tests and data scripts …
wjhuggins 94f4059
fix: use raw string for regex in naive_grid_qubit_manager_test.py (py…
wjhuggins ef47ded
fix: remove f prefix from strings without interpolation in adder_exam…
wjhuggins 0ed9d95
fix: assign floating expressions to discard variable in tests (pylint…
wjhuggins d9eaa25
fix: use lazy f-string interpolation in measurement_depth.py logging …
wjhuggins 4dfe0d2
fix: replace broad exception catching with specific exception classes…
wjhuggins 8972873
fix: resolve syntax error and logging f-string in measurement_depth.py
wjhuggins 1105296
fix: resolve f-string without interpolation in adder_example.py
wjhuggins aba6777
fix: resolve pylint warning by changing lru_cache maxsize in flasq_mo…
wjhuggins 89bc37c
fix: disable false positive pylint warnings in test files
wjhuggins 5d73974
style: reformat after pylint fixes
wjhuggins a42c4b7
fix: resolve final pylint warnings for clean run
wjhuggins d74f277
ci: enable FLASQ_FAST_MODE_OVERRIDE in notebooks CI job
wjhuggins e4bfabf
fix: guard symbolic comparison in apply_flasq_cost_model
wjhuggins File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -142,3 +142,6 @@ jupyter_kernel.lock | |
|
|
||
| # Mac OS | ||
| .DS_Store | ||
|
|
||
| # FLASQ generated PDFs | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -34,5 +34,6 @@ | |
| from ._success_prob import SuccessProb | ||
| from ._qubit_counts import QubitCount | ||
| from ._bloq_counts import BloqCount, QECGatesCost, GateCounts | ||
| from .classify_bloqs import bloq_is_t_like | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We can't have just this one function re-exported. Can you please update usage of this function to just use its full, alread-public import |
||
|
|
||
| from . import generalizers | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| # Copyright 2024 Google LLC | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # https://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| """qualtran.surface_code.flasq: FLASQ cost model for fault-tolerant quantum resource estimation.""" | ||
|
|
||
| from qualtran.surface_code.flasq import cultivation_analysis # noqa: F401 — imported as module | ||
| from qualtran.surface_code.flasq.cirq_interop import convert_circuit_for_flasq_analysis | ||
| from qualtran.surface_code.flasq.error_mitigation import ( | ||
| calculate_error_mitigation_metrics, | ||
| calculate_failure_probabilities, | ||
| ) | ||
| from qualtran.surface_code.flasq.flasq_model import ( | ||
| apply_flasq_cost_model, | ||
| conservative_FLASQ_costs, | ||
| FLASQCostModel, | ||
| FLASQSummary, | ||
| get_rotation_depth, | ||
| optimistic_FLASQ_costs, | ||
| ) | ||
| from qualtran.surface_code.flasq.measurement_depth import MeasurementDepth, TotalMeasurementDepth | ||
| from qualtran.surface_code.flasq.naive_grid_qubit_manager import NaiveGridQubitManager | ||
| from qualtran.surface_code.flasq.optimization import ( | ||
| ErrorBudget, | ||
| generate_circuit_specific_configs, | ||
| generate_configs_for_constrained_qec, | ||
| generate_configs_from_cultivation_data, | ||
| post_process_for_failure_budget, | ||
| post_process_for_logical_depth, | ||
| post_process_for_pec_runtime, | ||
| run_sweep, | ||
| ) | ||
| from qualtran.surface_code.flasq.span_counting import BloqWithSpanInfo, GateSpan, TotalSpanCost | ||
| from qualtran.surface_code.flasq.symbols import ( | ||
| MIXED_FALLBACK_T_COUNT, | ||
| ROTATION_ERROR, | ||
| T_REACT, | ||
| V_CULT_FACTOR, | ||
| ) | ||
| from qualtran.surface_code.flasq.utils import substitute_until_fixed_point | ||
| from qualtran.surface_code.flasq.volume_counting import FLASQGateCounts, FLASQGateTotals | ||
|
|
||
| __all__ = [ | ||
| "FLASQCostModel", | ||
| "FLASQSummary", | ||
| "apply_flasq_cost_model", | ||
| "conservative_FLASQ_costs", | ||
| "optimistic_FLASQ_costs", | ||
| "get_rotation_depth", | ||
| "FLASQGateTotals", | ||
| "TotalSpanCost", | ||
| "TotalMeasurementDepth", | ||
| "convert_circuit_for_flasq_analysis", | ||
| "NaiveGridQubitManager", | ||
| "ErrorBudget", | ||
| "run_sweep", | ||
| "generate_configs_for_constrained_qec", | ||
| "generate_configs_from_cultivation_data", | ||
| "generate_circuit_specific_configs", | ||
| "post_process_for_failure_budget", | ||
| "post_process_for_pec_runtime", | ||
| "post_process_for_logical_depth", | ||
| "calculate_error_mitigation_metrics", | ||
| "calculate_failure_probabilities", | ||
| "MIXED_FALLBACK_T_COUNT", | ||
| "ROTATION_ERROR", | ||
| "V_CULT_FACTOR", | ||
| "T_REACT", | ||
| "substitute_until_fixed_point", | ||
| "cultivation_analysis", | ||
| "FLASQGateCounts", | ||
| "GateSpan", | ||
| "MeasurementDepth", | ||
| "BloqWithSpanInfo", | ||
| ] |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,112 @@ | ||
| # Copyright 2024 Google LLC | ||
| # | ||
| # Licensed under the Apache License, Version 2.0 (the "License"); | ||
| # you may not use this file except in compliance with the License. | ||
| # You may obtain a copy of the License at | ||
| # | ||
| # https://www.apache.org/licenses/LICENSE-2.0 | ||
| # | ||
| # Unless required by applicable law or agreed to in writing, software | ||
| # distributed under the License is distributed on an "AS IS" BASIS, | ||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
| # See the License for the specific language governing permissions and | ||
| # limitations under the License. | ||
|
|
||
| # test_adder_example.py | ||
| import cirq | ||
|
|
||
| from qualtran.resource_counting import get_cost_value | ||
| from qualtran.surface_code.flasq.cirq_interop import convert_circuit_for_flasq_analysis | ||
|
|
||
| # Import functions/classes to be tested or used in tests | ||
| from qualtran.surface_code.flasq.examples.adder_example import ( | ||
| analyze_adder_costs, | ||
| create_adder_circuit_and_decorations, | ||
| ) | ||
| from qualtran.surface_code.flasq.span_counting import GateSpan, TotalSpanCost | ||
| from qualtran.surface_code.flasq.volume_counting import FLASQGateCounts, FLASQGateTotals | ||
|
|
||
| TEST_BITSIZE = 4 | ||
|
|
||
|
|
||
| def test_analyze_adder_costs_runs(): | ||
| """Tests that analyze_adder_costs executes without exceptions.""" | ||
| analyze_adder_costs(TEST_BITSIZE) | ||
|
|
||
|
|
||
| def test_create_adder_circuit_runs_and_returns_circuit(): | ||
| """Tests create_adder_circuit runs and returns a Cirq circuit.""" | ||
| circuit, _, _, _ = create_adder_circuit_and_decorations(TEST_BITSIZE) | ||
| assert isinstance(circuit, cirq.Circuit) | ||
| assert len(list(circuit.all_operations())) > 0 | ||
|
|
||
|
|
||
| def test_decomposed_adder_flasq_and_span_costs(): | ||
| """ | ||
| Tests applying FLASQ and Span costing to the decomposed adder circuit. | ||
| Verifies that costs are calculated and no unknown/uncounted bloqs remain. | ||
| """ | ||
| original_circuit, signature, in_quregs, out_quregs = create_adder_circuit_and_decorations( | ||
| TEST_BITSIZE | ||
| ) | ||
| cbloq, decomposed_circuit = convert_circuit_for_flasq_analysis( | ||
| original_circuit, signature=signature, in_quregs=in_quregs, out_quregs=out_quregs | ||
| ) | ||
| assert cbloq is not None # Ensure conversion succeeded | ||
| assert decomposed_circuit is not None # Ensure decomposed circuit is returned | ||
|
|
||
| flasq_costs = get_cost_value(cbloq, FLASQGateTotals()) | ||
| assert isinstance(flasq_costs, FLASQGateCounts) | ||
| assert not flasq_costs.bloqs_with_unknown_cost | ||
| # Check that some expected gates were counted (Add decomposes to Toffoli/CNOT) | ||
| assert flasq_costs.toffoli > 0 or flasq_costs.cnot > 0 | ||
| # 4. Calculate Span costs | ||
| span_info = get_cost_value(cbloq, TotalSpanCost()) | ||
| assert isinstance(span_info, GateSpan) | ||
| assert not span_info.uncounted_bloqs | ||
| # Check that some span was counted (multi-qubit gates exist) | ||
| # Resolve symbols in span_info before making boolean checks | ||
| assert span_info.connect_span > 0 | ||
| # Check the decomposed circuit from the conversion | ||
| assert len(list(decomposed_circuit.all_operations())) > 0 | ||
|
|
||
|
|
||
| import cirq | ||
| import numpy as np | ||
|
|
||
| from qualtran import QUInt | ||
| from qualtran.bloqs.arithmetic import Add | ||
| from qualtran.bloqs.mcmt import And | ||
| from qualtran.cirq_interop import cirq_optree_to_cbloq | ||
|
|
||
|
|
||
| def test_self_contained_adder_issue(): | ||
| adder_bloq = Add(a_dtype=QUInt(4), b_dtype=QUInt(4)) | ||
|
|
||
| a_qubits = np.asarray([cirq.LineQubit(i * 3 + 0) for i in range(4)]) | ||
| b_qubits = np.asarray([cirq.LineQubit(i * 3 + 1) for i in range(4)]) | ||
|
|
||
| adder_op, _ = adder_bloq.as_cirq_op( | ||
| qubit_manager=cirq.SimpleQubitManager(), a=b_qubits, b=a_qubits | ||
| ) | ||
| assert adder_op is not None | ||
| circuit = cirq.Circuit(adder_op) | ||
|
|
||
| def is_and_or_short(op): | ||
|
|
||
| if len(op.qubits) <= 2: | ||
| return True | ||
|
|
||
| if isinstance(op.gate, And): | ||
| return True | ||
|
|
||
| return False | ||
|
|
||
| circuit = cirq.Circuit(cirq.decompose(circuit, keep=is_and_or_short)) | ||
|
|
||
| cbloq = cirq_optree_to_cbloq( | ||
| circuit.all_operations(), | ||
| signature=adder_bloq.signature, | ||
| in_quregs={"a": a_qubits, "b": b_qubits}, | ||
| out_quregs={"a": a_qubits, "b": b_qubits}, | ||
| ) |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we document this .. somewhere? How slow are the notebooks in non-fast mode? When we build the docs do we need the full notebook versions? Is there any merit to making the fast mode the default and explaining in the notebooks what to set to get the full version?